Summary of new features of vue3.0

Vue 3.0 It was finally released on September 18, 2020 and has been used Typescript A large-scale reconstruction has been carried out, which has brought Composition API RFC Version, similar React Hook Write Vue in the same way. You can customize your own hook to make users more flexible.

Some new features of vue 3.0.

  1. setup()
  2. ref()
  3. reactive()
  4. isRef()
  5. toRefs()
  6. computed()
  7. watch()
  8. Lifecycle hooks
  9. Template refs
  10. globalProperties
  11. Suspense

Comparison of Vue2 and Vue3

  • Unfriendly to TypeScript support (all attributes are placed on this object, which is difficult to push down the data type of the component)

  • A large number of API s are mounted on the prototype of Vue objects, which is difficult to implement TreeShaking.

  • The architecture layer is not friendly to cross platform dom rendering development support

  • Composition API . Inspired by ReactHook

  • More convenient support jsx

  • Vue 3's Template supports multiple root tags, but Vue 2 does not

  • Rewrite the virtual DOM and optimize the compilation of the template


I setup function

The setup() function is a new attribute provided specifically for components in vue3. It provides a unified entry for us to use the new features of vue3's Composition API. The setup function will be executed before beforeCreate and created. Vue3 also cancels these two hooks and replaces them with setup. This function is equivalent to a life cycle function. All the past data, methods and watch in Vue are written in the setup() function with the corresponding new api

setup(props, context) {
    context.attrs
    context.slots
    context.emit
    
    return {
        
    }
}
  • Props: used to receive props data
  • Context is used to define the context. The context object contains some useful attributes. These attributes can only be accessed through this in vue 2.x. This cannot be accessed in the setup() function. It is undefined
  • Return value: return {}, which returns responsive data and functions to be used in the template

II reactive function

The reactive() function receives a common object, return s a response data object, and wants to use the created response data. It is also very simple. After it is created, it goes out in setup, and it can be called directly in template.

<template>
    {{name}} // test
<template>

<script lang="ts">
import { defineComponent, reactive, ref, toRefs } from 'vue';

export default defineComponent({
    setup(props, context) {
    
    let state = reactive({
        name: 'test'
    });
    
    return state
    }
});
</script>

III ref function

The ref() function is used to create a responsive data object according to the given value. The return value of the ref() function call is an object. This object only contains a value attribute. If you access the ref function inside the setup function, you need to add. Value

<template>
    <div class="mine">
        {{count}} // 10
    </div>
</template>

<script lang="ts">
import { defineComponent, ref } from 'vue';

export default defineComponent({
    setup() {
    	const count = ref<number>(10)
    	// To get the value defined in ref in js, you need to use the value attribute
    	console.log(count.value);
    	return {
        	count
    	}
    }
});
</script>

Access the responsive data created by ref in the reactive object

<template>
    <div class="mine">
        {{count}} -{{t}} // 10 -100
    </div>
</template>

<script lang="ts">
import { defineComponent, reactive, ref, toRefs } from 'vue';

export default defineComponent({
    setup() {
    	const count = ref<number>(10)
    	const obj = reactive({
        	t: 100,
        	count
    	})
    	// The. Value attribute is not required to obtain the value of ref through reactive
    	console.log(obj.count);
    	return {
        	...toRefs(obj)
    	}
    }
});
</script>

IV isRef function

isRef() is used to determine whether a value is an object created by ref()

<script lang="ts">
import { defineComponent, isRef, ref } from 'vue';

export default defineComponent({
    setup(props, context) {
    	const name: string = 'vue'
    	const age = ref<number>(18)
    	console.log(isRef(age)); // true
    	console.log(isRef(name)); // false

    	return {
        	age,
        	name
    	}
    }
});
</script>

V toRefs function

The toRefs() function can convert the responsive object created by reactive() into an ordinary object. However, each attribute node on this object is responsive data of ref() type

<template>
    <div class="mine">
    {{name}} // test
    {{age}} // 18
    </div>
</template>

<script lang="ts">
import { defineComponent, reactive, ref, toRefs } from 'vue';

export default defineComponent({
    setup(props, context) {
    	let state = reactive({
        	name: 'test'
    	});

    	const age = ref(18)
    
    	return {
        	...toRefs(state),
        	age
    	}
    }
});
</script>

Vi computed Create calculated properties

The computed function is used to create calculated attributes. As in the past, the value it returns is a ref object. You can pass a method or an object, which contains set() and get() methods

6.1 create read-only calculated attributes

import { computed, defineComponent, ref } from 'vue';

export default defineComponent({
    setup(props, context) {
    	const age = ref(18)

    	// Create a responsive calculation attribute readOnlyAge according to the value of age,
    	// It automatically calculates and returns a new ref based on the dependent Ref
    	const readOnlyAge = computed(() => age.value++) // 19

    	return {
        	age,
        	readOnlyAge
    	}
    }
});
</script>

6.2 create a readable and writable calculation attribute through set() and get() methods

<script lang="ts">
import { computed, defineComponent, ref } from 'vue';

export default defineComponent({
    setup(props, context) {
    	const age = ref<number>(18)

    	const computedAge = computed({
        	get: () => age.value + 1,
        	set: value => age.value + value
    	})
    	// The operation of assigning value to the calculated attribute will trigger the set function, 
    	// After triggering the set function, the value of age will be updated
    	age.value = 100
    	
    	return {
        	age,
        	computedAge
    	}
    }
});
</script>

VII watch Monitor data

The watch function is used to listen to a specific data source and perform side effects in the callback function. The default is lazy execution, that is, the callback is executed only when the listening source data changes.

7.1 listening to data sources declared with reactive

<script lang="ts">
import { 
	computed, defineComponent, reactive, toRefs, watch 
} from 'vue';

interface Person {
    name: string,
    age: number
}

export default defineComponent({
    setup(props, context) {
    	const state = reactive<Person>({ name: 'vue', age: 10 })

    	watch(
        	() => state.age,
        	(age, preAge) => {
        		console.log(age); // 100
        		console.log(preAge); // 10
        	}
    	)
    	// When modifying the age, the callback of watch will be triggered to print the values before and after the change
    	state.age = 100
    	
    	return {
        	...toRefs(state)
    	}
    }
});
</script>

7.2 listening to data sources declared with ref

<script lang="ts">
import { defineComponent, ref, watch } from 'vue';

interface Person {
    name: string,
    age: number
}

export default defineComponent({
    setup(props, context) {
    const age = ref<number>(10);

    	watch(age, () => console.log(age.value)); // 100
    
    	// When modifying the age, the callback of watch will be triggered to print the changed value
    	age.value = 100
    	return {
        	age
    	}
    }
});
</script>

7.3 simultaneous monitoring of multiple values

<script lang="ts">
import { 
	computed, defineComponent, reactive, toRefs, watch 
} from 'vue';

interface Person {
    name: string,
    age: number
}

export default defineComponent({
    setup(props, context) {
    	const state = reactive<Person>({ name: 'vue', age: 10 })

    	watch(
        	[() => state.age, () => state.name],
        	([newName, newAge], [oldName, oldAge]) => {
        		console.log(newName);
        		console.log(newAge);

        		console.log(oldName);
        		console.log(oldAge);
        	}
    	)
    	// When modifying the age, the callback of watch will be triggered to print the values before and after the change, 
    	// At this time, it should be noted that changing one of the values will execute the callback of watch
    	state.age = 100
    	state.name = 'vue3'
    	
    	return {
        	...toRefs(state)
    	}
    }
});
</script>

7.4 execute the return method to stop listening

The watch monitoring created in the setup() function will automatically stop when the current component is destroyed. If you want to explicitly stop a monitoring, you can call the return value of the watch() function. The syntax is as follows:

<script lang="ts">
import { set } from 'lodash';
import { 
	computed, defineComponent, reactive, toRefs, watch 
} from 'vue';

interface Person {
    name: string,
    age: number
}

export default defineComponent({
    setup(props, context) {
    	const state = reactive<Person>({ name: 'vue', age: 10 })

    	const stop =  watch(
        	[() => state.age, () => state.name],
        	([newName, newAge], [oldName, oldAge]) => {
        		console.log(newName);
        		console.log(newAge);

        		console.log(oldName);
        		console.log(oldAge);
        	}
    	)
    	// When modifying the age, the callback of watch will be triggered to print the values before and after the change, 
    	// At this time, it should be noted that changing one of the values will execute the callback of watch
    	state.age = 100
    	state.name = 'vue3'

    	setTimeout(()=> { 
        	stop()
        	// At this time, the watch callback will not be triggered during modification
        	state.age = 1000
        	state.name = 'vue3-'
    	}, 1000) // Cancel the monitoring of watch in 1 second
    
    	return {
        	...toRefs(state)
    	}
    }
});
</script>

VIII LifeCycle Hooks (New lifecycle function)

The new version of life cycle functions can be imported into components on demand and can only be used in the setup() function, but they can also be defined outside setup and used in setup

<script lang="ts">
import { set } from 'lodash';
import { 
	defineComponent, onBeforeMount, onBeforeUnmount, onBeforeUpdate,
	onErrorCaptured, onMounted, onUnmounted, onUpdated 
} from 'vue';

export default defineComponent({
    setup(props, context) {
    	onBeforeMount(()=> {
        	console.log('beformounted!')
    	})
    	onMounted(() => {
        	console.log('mounted!')
    	})

    	onBeforeUpdate(()=> {
        	console.log('beforupdated!')
    	})
    	onUpdated(() => {
        	console.log('updated!')
    	})

    	onBeforeUnmount(()=> {
        	console.log('beforunmounted!')
    	})
    	onUnmounted(() => {
        	console.log('unmounted!')
    	})

    	onErrorCaptured(()=> {
        	console.log('errorCaptured!')
    	})

    	return {}
    }
});
</script>

IX Template refs

Get the real dom elements through refs. This is the same as the use of react. In order to obtain references to elements or component instances in the template, we can declare a ref in setup() and return it as usual

  1. As usual, write the name of ref in html
  2. Define a ref in setup
  3. Instance of ref returned in setup
  4. The RefImpl object of ref can be obtained in onMounted, and the real dom can be obtained through. value
<template>
    <!--Step 1: as usual, in html Write in ref Name of-->
    <div class="mine" ref="elmRefs">
    	<span>span</span>
    </div>
</template>

<script lang="ts">
import { set } from 'lodash';
import { defineComponent, onMounted, ref } from 'vue';

export default defineComponent({
    setup(props, context) {
    	// Get real dom
    	const elmRefs = ref<null | HTMLElement>(null);
    	onMounted (() => {
        	console.log(elmRefs.value); 
        	// Get a RefImpl object and access the data through. value
    	})

    	return {
        	elmRefs
    	}
    }
});
</script>

X Global configuration of vue

It is configured through config on Vue instance, including the objects of Vue application global configuration. You can modify the properties listed below before mounting the application:

const app = Vue.createApp({})
    
app.config = {...}

Assign handlers for uncapped errors during component rendering and watchers. Errors and application instances call handlers

app.config.errorHandler = (err, vm, info) => {}

Global properties that can be accessed in any component instance within the application, and the properties of the component will have priority. This can replace the Vue 2.x Vue.prototype extension:

const app = Vue.createApp({})

app.config.globalProperties.$http = 'xxxxxxxxs'

You can use getCurrentInstance() to obtain the information configured in global properties in the component. getCurrentInstance method obtains the instance of the current component, and then obtains the current context through ctx property. In this way, we can use router and vuex in setup. Through this property, we can operate variables, global properties, component properties, etc

setup( ) {
    const { ctx } = getCurrentInstance();
    ctx.$http   
}

Xi Suspend component

Before introducing Vue's suspend component, it is necessary to understand the suspend component of React because their functions are similar.

React.lazy accepts a function that needs to dynamically call import(). It must return a Promise that needs to resolve a react component of default export.

import React, { Suspense } from 'react';
    
    
const myComponent = React.lazy(() => import('./Component'));
    
    
function MyComponent() {
    return (
    <div>
        <Suspense fallback={<div>Loading...</div>}>
        <myComponent />
        </Suspense>
    </div>
    );
}

Vue3 also adds the defineAsyncComponent function with similar function of React.lazy to handle dynamic introduction. defineAsyncComponent can accept factory functions that return commitments. When you retrieve the component definition from the server, you should call Promise's parsing callback. You can also call reject(reason) to indicate that the load has failed

import { defineAsyncComponent } from 'vue'

const AsyncComp = defineAsyncComponent(() =>
    import('./components/AsyncComponent.vue')
)

app.component('async-component', AsyncComp)

Vue3 also added the suspend component:

<template>
    <Suspense>
    	<template #default>
        	<my-component />
    	</template>
    	<template #fallback>
        	Loading ...
    	</template>
    </Suspense>
</template>

<script lang='ts'>
import { defineComponent, defineAsyncComponent } from "vue";
const MyComponent = defineAsyncComponent(
	() => import('./Component')
);

export default defineComponent({
    components: {
        MyComponent
    },
    setup() {
        return {}
    }
})    
</script>

12, vue 3.x complete component template structure

A completed vue 3.x complete component template structure includes: component name, props, components, setup (hooks, computed, watch, methods, etc.)

<template>
    <div class="mine" ref="elmRefs">
    	<span>{{name}}</span>
    	<br>
    	<span>{{count}}</span>
    	<div>
        	<button @click="handleClick">Test button</button>
    	</div>

    	<ul>
        	<li 
        		v-for="item in list" 
        		:key="item.id"
        		>{{item.name}}</li>
    	</ul>
    </div>
</template>

<script lang="ts">
import { 
	computed, defineComponent, getCurrentInstance, onMounted, 
	PropType, reactive, ref, toRefs 
} from 'vue';

interface IState {
    count: 0,
    name: string,
    list: Array<object>
}

export default defineComponent({
    name: 'demo',
    
    // Parent component to child component parameters
    props: {
    	name: {
        	type: String as PropType<null | ''>,
        	default: 'vue3.x'
    	},
    	list: {
        	type: Array as PropType<object[]>,
        	default: () => []
    	}
    },
    
    components: {
    	///TODO component registration
    },
    
    emits: ["emits-name"], // For cue
    
    setup (props, context) {
    	console.log(props.name)
    	console.log(props.list)
    
    	const state = reactive<IState>({
        	name: 'vue 3.0 assembly',
        	count: 0,
        	list: [
        		{
            		name: 'vue',
            		id: 1
        		},
        		{
            		name: 'vuex',
            		id: 2
        		}
        	]
    	})

    	const a = computed(() => state.name)

    	onMounted(() => {

    	})

    	function handleClick () {
        	state.count ++
        	// Call the method of the parent component
        	context.emit('emits-name', state.count)
    	}
    
    	return {
        	...toRefs(state),
        	handleClick
    	}
    }
});
</script>

Ecology of vue 3

Official website [1]
Source code [2]
vite builder [3]
Scaffold: [4]https://cli.vuejs.org/
vue-router-next[5]
vuex4.0[6]
UI component library

vant2.x[7]

Ant Design of Vue 2.x[8]

element-plus[9]


From [original address]( https://mp.weixin.qq.com/s?__biz=MzAxODE4MTEzMA==&mid=2650081599&idx=1&sn=d28ae78f205640f7f812318b8b5ccc71&chksm=83db945ab4ac1d4c627a6c44c4d2af3112280de79ae22ecbfe583784b7a73f9a9af220acede4&mpshare=1&scene=23&srcid=1028IwSO0yCUEmj06ewGjQWb&sharer_sharetim )

Keywords: Javascript Vue

Added by messels on Fri, 17 Sep 2021 22:23:33 +0300