The difference between Vue3. X and Vue2

1.OptionsApi and CompositionApi differences

Note: you can still use vue2’s optional Api writing in Vue3. X, but I would prefer to use the latest component Api writing

Optionsapi-vue2. X – Optional Api

1. Limit the freedom, must be in accordance with the relevant provisions to writing code, such as props, the methods, data, computed, watch, according to prohibit crossing the line 2. Context must use this. 3. The lifecycle contains beforeCreated() and Created().

CompositionApi – Vue3. X – Constituent Api

1. Break up the code and allow free writing in the setup() function to further reduce the fragmentation of the code by 2. GetData => context.getData 3 instead of this, use the context parameter in setup(). The life cycle is replaced by the setup() entry for the purpose of 4. Tree-shaking, importing what is used and packaging only the apis used

Example: Content context

2. Life cycle changes

Setup is used instead of beforeCreate and created. Other lifecycle names are changed and functions remain the same

3. The template template supports multiple root labels

  • Adjust from the original single root tag to support multiple root tags, reduce useless code, increase code freedom!
  • Multiple root tags are supported because the bottom layer is wrapped as a Fragment component
/ / Vue2. X
<template>
	<div class="name">
		<p></p>
		<p></p>
	</div>
</template>
Copy the code
//Vue3.x
<template>
	<div class="name"></div>
	<div class="name2"></div>
	<div class="name3"></div>
</template>
Copy the code

4.Route Obtains the page instance and Route information

Vue2.x

  • Get the Router instance through this
export default{
  mounted() {
    this.getRouter();
  },
  methods: {
    getRouter() {
      console.log(this.$route);
      console.log(this.$router); }},}Copy the code

Vue3.x

  • The first is to get the current component instance using the getCurrentInstance method

import { getCurrentInstance } from "vue";
export default {
  setup(props, context) {
    const { ctx } = getCurrentInstance();
    console.log(ctx.$router.currentRoute.value); }};Copy the code
  • The second is through userRoute and userRouter
import { useRoute, useRouter } from "vue-router";
export default {
  setup(props, context) {
    const currRoute = useRoute();
    const currRouter = useRouter();

    console.log(currRoute);
    console.log(currRouter); }};Copy the code

5.Vuex status management

  • The API hasn’t changed significantly,
  • X is new Store and Vue3. X is createStore
// Create store instance in vue2. x
export default new Vuex.Store({
   // ... 
})

Copy the code
//Vue3.x
import Vuex from 'vuex'

export default Vuex.createStore({
  state: {
    count: 0
  },
  mutations: {
    ADD (state) {
      state.count++
    }
  },
  actions: {
    add ({ commit }) {
      commit('ADD')}},modules: {}})Copy the code

Used in Vue3. X components – two ways

  • The first way
<template>
  <div class="home">
    <p>{{count}}</p>
    <button @click="add">increase</button>
  </div>
</template>

<script>
import { computed } from 'vue'
import { useStore } from 'vuex'
export default {
  setup () {
    const store = useStore()
    const count = computed(() = > store.state.count)

    const add = () = > {
      store.dispatch('add')}return {
      count,
      add
    }
  }
}
</script>
Copy the code
  • Second way: Get the store in the context of the current component
import {getCurrentInstance} from 'vue'
// ...
const store = getCurrentInstance().ctx.$store
Copy the code

Reactive object functions ref and Reactive

export default{
	setup(){
		const count=ref(0);
		const state=reactive({
			count:0}}})Copy the code

ref

  • Ref is more focused on defining individual variables, while Reactive is more focused on defining objects.
  • Value = XXX and reactive only needs state.count= XXX
  • Ref encapsulates reactive internally
  • Ref is a simple bidirectional binding variable and toRef converts non-responsive objects into responsive ones
  • {{count}} can be used directly in templates

reactive

  • Reactive can use all sorts of methods like calculating properties inside of it, it just binds data in both directions
  • Reactive return data should be converted using toRefs
  • When mixed with ref, isRef can be used to determine the type

7. Listen for the difference between watch and watchEffect

  • Watch needs to specify the listening attribute (parameter). The new watchEffect in vue3. X does not need to specify the listening attribute (parameter) and automatically collects responsive attributes
  • Watch can get new and old values (pre-update values), but watchEffect can’t
  • Watch specifies dependencies from the beginning, and they are not executed when initialized, but only when the dependency changes

WatchEffect is executed once upon initialization to collect dependencies, and again when the dependencies change

  • Neither Watch nor watchEffect can listen for properties that are not bidirectionally bound
  • Watch can directly listen to objects bound to REF and Reactive, but watchEffect cannot. The value of ref must be. Value, and the value of Reactive must be specific to internal properties

Conclusion: By comparing the differences between the two properties, use watchEffect 2 if you need to execute them during component initialization. If you need to get new and old values, use Watch

8. Compute attributes computed

  • The first type does not allow the value to be modified, prompting a warning: the calculated property is not allowed to change
  • The second allows you to modify the value

9. Changes in the use of Props

  • Vue2. X
exprot default {
    props: {
        title: String
    },
    mounted() {
        console.log(this.title); }}Copy the code
  • Vue3. X
// Call through the built-in arguments in setup instead of this
exprot default {
    props: {
        title: String
    },
    // Properties passed to the props component
    setup(props,context) {
        console.log(props.title) / / response type}}Copy the code

10. Mixin changes to Mixins

  • The mixin pattern in ve2. X looks superficially safe. However, it has become an anti-pattern because it shares code by merging objects, which increases the vulnerability of code implicitly. The source of code is unclear, the conflict of method attributes, and the ability of reasoning function is concealed.
// in the vUE page, this method will introduce all the methods and properties in the Mixins
import mixin from 'mixin.js'
export default{
	data(){},
	mixins: [mixin]
}
Copy the code
  • The smartest part of the Composition API in Vue3.x is that it allows Vue to share code relying on safeguards built into native JavaScript, such as passing variables to functions and module systems, using only the parts that need to be called!
// in the vue page
import mixin from 'mixin.js'
// The first way - use the ES6 deconstruction method, quoting only what is needed
export default{
	setup(){
		const { count, plusOne, hello } = mixin()
		hello()
		console.log(count.value, plusOne.value)
	}
}

// The second way is to call a local variable in a component
export default {
  setup () {
    // a local value synthesis function is needed
    const myLocalVal = ref(0);
    // It must be passed explicitly as an argument
    const{... } = mixin(myLocalVal); }}Copy the code

11. Custom Diretctives

  • Custom instructions extracted from official documentation
  • As the name implies, custom instructions are self-created, such as V-HTML, V-bind, V-ON and other instructions are easy to call

12. Teleport

  • Official documentation explains Teleport
  • Move DOM elements within the template to other locations outside of the original DOM structure, completely controlled by the internal Vue component
  • Resolve the CSS hierarchy between components without dealing with z-index issues
  • Solve the positioning problem of Modal, not affected by the parent element
  • Usage scenarios: Feedback, notice, Toast,Modal

Vue3 Teleport introduction, please have a look, this is really good

13. Value transfer between parent and child components

  • When sending data back to the parent component, a custom name, such as backData, needs to be defined in emits; otherwise, emits Option is warned in the console
<template></template>
export default{
	emits: ['backData'].setup(props,{emit}){
		function back(){
			emit('backData'); }}}Copy the code

Two. Small knowledge

1. Does Vue3 based coding all use TypeScript coding?

1. TypeScript is not appropriate for business projects where the business is constantly changing, because speed is Paramount.

2. TypeScript is best for utility/infrastructure projects.

2. When defineComponent is used

Depending on the language in which the code is written, choose the appropriate module

  1. If you use TypeScript, you must use defineComponent when exporting. The two are paired to validate the type, as shown in Figure 1
  2. If you code in JavaScript, you don’t need this function, as shown in Figure 2

3. The difference between script and script setup

  • After adding the setup script, export the property or method
<template>
  <button @click="inc">{{ count }}</button>
</template>

<script setup>
  import { ref } from 'vue'

  const count = ref(0)
  const inc = () = > count.value++
</script>
Copy the code
  • Without setup, you need to return the property or method, similar to the return in data() in vue2.x
import { ref } from 'vue'

export default {
  setup() {
    const count = ref(0)
    const inc = () = > count.value++

    return {
      count,
      inc,
    }
  },
}
Copy the code

4. Responsiveness difference between Object.defineProperty(Vue2) and Proxy(Vue3)

Vue2.x Object.defineProperty

  • Only getter and setter operations of object properties can be hijacked. When data changes, all properties of the object, such as data and props, need to be traversed, which consumes a lot of energy
  • The Set/Map, class, and array types are not supported
  • Unable to detect new attributes added or deleted, not responsive, need to manually call this.$set to update
  • Object.defineproperty cannot monitor array subscripts, resulting in arrays being set directly by array subscripts, unable to respond in real time, and unable to listen for methods such as push, which were overwritten in VUE to add setters
const data= {
    name: 'xiaoming'.sex: 'male'
}
// Walk through the object and hijack its attribute values
Object.keys(data).forEach(key= > {
  let val = data[key]
  Object.defineProperty(data, key, {
    enumerable: true.// This property can be enumerated
    configurable: true.// The attribute can be deleted and the attribute descriptor can be changed
    get () {
      console.log(` attribute values${data}The current value of${val}`)
      return val
    },
    set (newValue) {
      console.log('Listens for the property value${data}by${val}into${newValue}`)
      val = newValue
    }
  })
});
 
data.name // Attribute value name The current value is zhangsan
data.name = 'lisi' // The value of name changed from zhangsan to lisi
data.age // Attribute value age The current value is 18
data.age = 25 // The age of the property is changed from 18 to 25
Copy the code

Vue3.x Proxy(ES6)

  • You can hijack an entire object
  • Object new properties can be responsive in real time, can detect array subscript changes
  • Because Proxy is a new attribute in ES6, some browsers do not support it and can only be compatible with IE11
let obj = {
  a: 1.b: 2,}const p = new Proxy(obj, {
  get(target, key, value) {
    if (key === 'c') {
      return 'I am a result of customization';
    } else {
      returntarget[key]; }},set(target, key, value) {
    if (value === 4) {
      target[key] = 'I am a result of customization';
    } else{ target[key] = value; }}})console.log(obj.a) / / 1
console.log(obj.c) // undefined
console.log(p.a) / / 1
console.log(p.c) // I am a result of customization
 
obj.name = '李白';
console.log(obj.name); / / li bai
obj.age = 4;
console.log(obj.age); / / 4
 
p.name = '李白';
console.log(p.name); / / li bai
p.age = 4;
console.log(p.age); // I am a result of customization
Copy the code

5. Configure the env environment variable

  • The project root directories create.end.development and.end. Production
  • Custom environment variables must start with VITE_APP
  • Add the suffix to package.json
  • Import. Meta. Env. VITE_APP_BASE_API;

console.log(import.meta.env);
Copy the code

Further reading

  • Vue3 official document
  • The difference between Vue3 and Vue2

If you are already familiar with the new features of Vue3. X, it is recommended that you read the following articles to get a quick start on the Vue3 project

  • Vue3 series (1) initialization project and Vite 2.0 configuration
  • Vue3 series (2) installation dependency and initial experience of UI framework