The new features of vue3 are different from those of vue2

Posted by coldfused on Mon, 07 Feb 2022 04:49:28 +0100

preface:

It has been a long time since the official version of the test version of vue3 was released. Let's summarize vue3 0 compared with our vue2 new and changed content.

vue official entrance

1, Life cycle: (more relevant: entrance)

1,Removed vue2.0 Medium beforeCreate and created Two phases, the same new one setup

2,beforeMount Before mounting    Rename  onBeforeMount

3,mounted After mounting    Rename  onMounted

4,beforeUpdate Before data update    Rename  onBeforeUpdate

5,updated After data update    Rename  onUpdated

6,beforeDestroy Before destruction    Rename  onBeforeUnmount

7,destoryed After destruction    Rename  onUnmounted

8,errorCaptured report errors    Rename  onErrorCaptured
Vue2.xVue3.x
beforeCreatesetup
createdsetup
beforeMountonBeforeMount
mountedonMounted
beforeUpdateonBeforeUpdate
updatedonUpdated
beforeDestroyonBeforeUnmount
destroyedonUnmounted
activatedonActivated
deactivatedonDeactivated
errorCapturedonErrorCaptured
- -onRenderTracked
- -onRenderTriggered

Initialization loading sequence:

setup => beforeCreate => created => onBeforeMount => onMounted

2, New function: setup

setup The function will be in beforeCreate Before calling, because the component is data and methods Not initialized yet,
therefore stay setup Cannot be used in this of

therefore Vue In order to avoid our wrong use, it will directly setup In function this Changed to undefined. 
setup Functions can only be synchronous, not asynchronous

The setup function is a new life cycle function added in Vue3. It is the entry of the # Composition API # when writing components. The setup function receives two parameters # props and # context,

The syntax is:

setup(props,context){}

props

Props # contains all the data passed from the parent component to the child component. Receive using # props # in sub components.

Props , is responsive. When a new , props , is passed in, it will be updated in time.
Because it is responsive, ES6 deconstruction cannot be used. Deconstruction will eliminate its responsiveness.

Parent component:

<template>
	<!-- The parent component passes data to the child component -->
	<Sub :name="name" :age="age" />
</template>

<script>
import { ref } from 'vue'
import Sub from './Sub.vue'
export default {
	setup () {
		const name = ref('Zhang San');
		const age = ref(20)

		return { name, age }
	},
	components: { Sub },
}
</script>

Subcomponent (Sub.vue):

<template>
	<div>{{name}}{{age}}</div>
</template>

<script>
export default {
	props: {
		name: String,
		age: Number
	},
	mounted () {
        // vue2. How to write x
		console.log(this.name); // Zhang San
		console.log(this.age); // 20
	},
	setup (props) {
        // vue3. How to write x
		console.log(props.name); // Zhang San
		console.log(props.age); // 20
		
		// let { name ,age } = props;  //  It cannot be deconstructed directly
		let { name, age } = toRefs(props);
		console.log(name.value, age.value); // Zhang San 20
	}
}
</script>

context

context , contains , attrs, slots, emit , and other data methods:

  • attrs: get attributes on components
  • slots: get the node of the slot
  • Emit: emit method (child component passes data to parent component)

Parent component:

<template>
	<Sub subData="some other data" @subClick='subClick'>parent</Sub>
</template>

<script>
import Sub from './Sub.vue'
export default {
	setup () {

		function subClick (e) {
			console.log(e); // Receive data from sub components
		}

		return { subClick }
	},
	components: { Sub },
}
</script>

Subcomponent (Sub.vue):

<template>
	<!-- The parent component passes data to the child component -->
	<div @click="handleClick">Child</div>
</template>

<script>
export default {
	mounted () {
        // vue2.x get properties on components
        console.log(this.$attrs.subData);  // 'some other data'
        
		// vue2.x get the node of slot
		console.log(this.$slots);

	},
	methods: {
		// vue2.x emit method (child component passes data to parent component)
		handleClick () {
			this.$emit('subClick', 'vue2.x - this is subData')
		},
	},
	setup (props, context) {
		let { attrs, slots, emit } = context;

		// vue3.x get properties on components
		console.log(attrs.subData);  // 'some other data'

		// vue3.x get the node of slot
		console.log(slots.default());

		// vue3.x emit method (child component passes data to parent component)
		function handleClick () {
			emit('subClick', 'vue3.x - this is subData');
		}

		return { handleClick }
	}
}
</script>

3, Ref get dom elements, ref and reactive

Create a responsive data

  • ref: the responsive reference of any type (recommended basic type) data (you need to add. value when setting and obtaining values).
    The essence of ref is copying, and modifying data will not affect the original data.
  • reactive: can only be a responsive reference to complex type data

vue2. In 0:

1. Defined on the page:

<div ref='abc'><div>

2. Take dom:

this.$refs.abc

vue3. In 0:


1. Usage scenario - obtain dom with ref in the charts of echarts

<div ref='echart'><div>

import { onMounted,toRefs, ref,reactive } from 'vue';
 
 setup(){
    //1. Definition
    let state = reactive({
      echart: ref(),
    })
     const echartInit = () =>{
        //2. Use in method
      var myChart = echarts.init(state.echart);
        ...
    }
    return {
        //3. Send out
      ...toRefs(state),
    };
 
}

2. Usage scenario - initialize elements that get ref directly

<div ref="box">
   I am div
</div>
import { onMounted, ref} from 'vue';
setup(){
    let box = ref(null)
    //mount 
    onMounted(()=>{
      console.log('box.value', box.value)
    })
 
    return {
      box
    }
}

4, toRef and toRefs

You can also create a responsive data

  • toRef: used to extract a property from a responsive object and wrap the property into a ref object to link it with the original object.
    The essence of toRef is reference. Modifying responsive data will affect the original data.
  • toRefs: used to convert a responsive object into an ordinary object and wrap every attribute in the object into a ref object.
    toRefs is an upgraded version of toRef, but toRefs converts responsive objects. Other features are the same as toRef
<template>
	<ul>
		<li>{{name1}}</li>
		<li>{{name2.name.value}}</li>
		<li>{{name}}</li>
	</ul>
</template>

<script>
import { toRef, toRefs, reactive } from 'vue'
export default {
	setup () {
		let nameObj1 = reactive({ name: 'Zhang San' });
		let name1 = toRef(nameObj1, 'name');
		let age1 = toRef(nameObj1, 'age '); // age does not exist
		setTimeout(() => {
			name1.value = 'zhangsan';
			age1.value = 20; // Normal responsive assignment even if age does not exist
		}, 1000)


		let nameObj2 = reactive({ name: 'Zhang San' });
		let age2 = toRef(nameObj3, 'age '); // age does not exist
		let name2 = toRefs(nameObj2);
		setTimeout(() => {
			name2.name.value = 'zhangsan';
			age2.value = 20; // age assignment does not exist, no response
		}, 2000)


		let nameObj3 = reactive({ name: 'Zhang San' });
		setTimeout(() => {
			nameObj3.name = 'zhangsan';
		}, 3000)
		let { name } = toRefs(nameObj3); // After deconstruction, we still need to maintain the response

		return { name1, name2, name }
	}
}
</script>

5, watch and watchEffect listening properties

  • watch} function:
    Used to listen to specific data sources and perform side effects in callback functions.
    The default is lazy, which means that callbacks are executed only when the listening source data changes.
  • watchEffect} function:
    1. Execute and listen immediate ly
    2. Automatically sense code dependencies (automatically collect dependencies), and there is no need to pass the monitored content (there is no need to manually pass in dependencies like "watch")
    3. The value before the change cannot be obtained (oldVal)

6, readonly read only property

Indicates that the responsive object cannot be modified

<template>
	<ul>
		<li>{{nameObj.name}}</li>
	</ul>
</template>

<script>
import { reactive, readonly } from 'vue'
export default {
	setup () {
		let nameObj = reactive({ name: 'Zhang San' });
		let readonlyObj = readonly(nameObj); // Set the nameObj responsive object as read-only and cannot be modified

		setTimeout(() => {
			readonlyObj.name = 'zhangsan'; // Cannot set attribute = > set operation on key "name" failed: target is readonly Proxy {Name: "Zhang San"}
		}, 1000)

		return { nameObj }
	}
}
</script>

7, computed calculated attribute

<template>
	<div>
		<button @click="add">+</button>
		<p>{{addCount}}</p>
	</div>
</template>

<script>
import { ref, computed } from 'vue'
export default {
	setup () {
		const num = ref(0);
		const add = () => {
			num.value++
		}
		// Calculation properties
		const addCount = computed(() => {
			return num.value * 2;
		})
		return { add, addCount }
	}
}
</script>

8, provide and inject

Transfer data and methods from parent component to child component

Parent component:

<template>
	<Sub />
</template>

<script>
import { ref, provide } from 'vue'
import Sub from './Sub.vue'
export default {
	setup () {
		const name = ref('Zhang San');

		// Provide (alias, data and method to be passed)
		provide('myName', name)
		provide('handleClick', () => {
			name.value = 'zhangsan';
		})

	},
	components: { Sub },
}
</script>

Subcomponent (Sub.vue):

<template>
	<div @click="handleClick">{{name}}</div>
</template>

<script>
import { inject } from 'vue'
export default {
	setup () {
		//Call the inject method to receive the data and methods shared by the parent through the specified alias
		const name = inject('myName');
		const handleClick = inject('handleClick');

		return { name, handleClick }
	}
}
</script>

9, Teleport portal

Personal understanding: like the global slot, it is a unified element, which modifies the content of the specific page,

Teleport translates to transmission, which is like the "arbitrary door" in Doraemon. The function of any door is to instantly transmit people to another place.

give an example:
We hope that the dom and top-level components rendered by "Dialog" are sibling nodes, which can be found in "app An element for mounting is defined in the Vue file:

<template>
	<router-view />
	<div id="model"></div> <!-- Mount point -->
</template>

Define a Dialog component Dialog Vue, pay attention to the # to # attribute, which is consistent with the # id selector above:

<template>
	<teleport to="#model"> 
		<!-- Mount content -->
		<div>title</div>
        <div>I'am a Dialog.</div>
	</teleport>
</template>

The DOM rendering effect is as follows:

We use the # report component to specify the location of the component rendering in # app through the # to attribute Vue , but Dialog is completely composed of , Dialog Vue# component control.

10, Suspend

The suspend component is used to display backup content while waiting for an asynchronous component to resolve.

In vue2 This scenario is often encountered in X:

<template>
<div>
    <div v-if="!loading">
    	<!-- Asynchronous rendering -->
        ...  
    </div>
    <div v-if="loading">
        Loading...
    </div>
</div>
</template>

. . .

11, Root element

Only one root element is allowed in vue2

Multiple root elements are allowed in vue3

12, pinia

It can be regarded as a lightweight vuex

Topics: Vue Vue.js