The difference between vue3 and vue2 (you don't know the details are all here)

Posted by duhhh33 on Mon, 21 Feb 2022 12:49:20 +0100

Let's talk about the current market development and use. At present, there are still few enterprises using vue3 in 2021, and they are basically developed in the form of vue2. The development mode of vue3 is very similar to react. At this time, someone will think whether it is useful for me to learn vue3. Gan, he mews. Don't get excited and listen to me calmly, Vue3 is slowly upgrading some vue2 things for enterprises now. This is very key, because vue3 can be used in vue2, but vue3 can't use vue2. You haven't even done vue2, and you still use a hammer to do vue3. Let's take a look at some differences between vue3 and vue2

1.webpack and vite

① vue2 uses the form of webpack to build the project
webpack starts with the entry file, then analyzes the route, then the module, finally packs it, and then tells you that the server is ready to start
② vue3 building projects with vite
First tell you that the server is ready, and then wait for you to send an HTTP request, and then the entry file, Dynamic import code split point

The biggest advantage and difference is to make some code files in the project more available, so that the actual effect can be seen faster when saving updated data in the future, that is, the so-called (hot update)

2.main.js file

In vue2, we can use the form of pototype (prototype) to operate, and the constructor is introduced
vue3 needs to operate in the form of structure, and the factory function is introduced
There can be no root tag in the app component in vue3

3.setup function

The setup function must return

<script>
 export default {
  name: 'appName',
  setup(){
  //variable
   let name = 'Wage earners'
   let age = 18
   //method
   function say(){
    console.log(`I'm just a ${name},this year ${age}year`)
   }
   //Returns an object
   return {
    name,
    age,
    say
   }
  }
 }
</script>

You will find that the name in the current ${name} does not need to use this to operate. The function of this is just to get the variable in a scope, and the setup function provides that it is currently only in this scope

At this time, it's very uncomfortable. Isn't it necessary to return every time I define variables and methods? Vue3 provides it for us
Add setup on the script tag, such as < script setup > < / script >, which is equivalent to putting it into the setup during compilation and running
Note: the life cycle of setup is earlier than that of beforeCreate and created. That is to say, currently, the data in data is directly obtained with this, and it is still undefined
In setup syntax, the class receives two parameters: setup(props,context)
We all know this in vue2$ attrs,this.$ slots,this.$ Emit is equivalent to attrs, slots and emit in context
Note: when we only accept one parameter, the page will prompt a warning, but it will not affect the use

4. Command and slot

  • Using slot in vue2 can directly use slot, while vue3 must use the form of v-slot
  • v-for and v-if have the highest priority in vue2, and they are not recommended to be used together
  • v-for and v-if in vue3 will only treat the current v-if as a judgment statement in v-for and will not conflict with each other
  • Remove keyCode as the modifier of v-on in vue3. Of course, config. Is not supported keyCodes
  • Remove v-on from vue3 Native modifier
  • Remove filter from vue3

5.ref and reactive

ref
Turn the data into responsive data and ref turns them into objects. If we directly operate the code, we can't modify it. You will find that the current name and age still modify the page through get and set. You need to use it at this time value, and ref is Refimpl

<template>
  <div class="home">
    <h1>full name:{{name}}</h1>
    <h1>Age:{{age}}</h1>
    <button @click="say">modify</button>
  </div>
</template>

<script>
import {ref} from 'vue'
export default {
  name: 'Home',
  setup(){
    let name = ref('intermediary')
    let age = ref(18)
    console.log(name)
    console.log(age)
    //method
    function say(){
      name='Ponyo '
      age=18
    }
    return {
      name,
      age,
      say
    }
  }
}
</script>

In this case, we don't have to display {name.value}} on the page. In fact, we don't need this. We vue3 will detect that your ref is an object and automatically add it to you Value. If we define our own ref object, the instance will become refimpl. XX is used at this time value. XX to modify

<template>
  <div class="home">
    <h1>full name:{{name}}</h1>
    <h1>Age:{{age}}</h1>
    <h2>occupation:{{job.occupation}}</h2>
    <h2>Salary:{{job.salary}}</h2>
    <button @click="say">modify</button>
  </div>
</template>

<script>
import {ref} from 'vue'
export default {
  name: 'Home',
  setup(){
    let name = ref('intermediary')
    let age = ref(18)
    let job=ref({
      occupation:'programmer',
      salary:'10k'
    })
    console.log(name)
    console.log(age)
    //method
    function say(){
      job.value.salary='12k'
    }
    return {
      name,
      age,
      job,
      say
    }
  }
}
</script>

Then we print obj Value, which is no longer a refimpl object but a proxy object, because vue3 the underlying layer is a proxy object, and the basic data types are based on object get and set in defineproperty are used for data hijacking. Vue3 has encapsulated reactive, which is equivalent to that when we call ref, we will automatically call reactive

reactive
Above, we said that the Object in ref will call reactive and convert the Object into Proxy. Now we directly change it into Proxy through reactive, which makes a deep-seated response

<template>
  <div class="home">
    <h1>full name:{{name}}</h1>
    <h1>Age:{{age}}</h1>
    <h2>occupation:{{job.occupation}}<br>Salary:{{job.salary}}</h2>
    <h3>Hobbies:{{hobby[0]}},{{hobby[1]}},{{ hobby[2] }}</h3>
    <button @click="say">modify</button>
  </div>
</template>

<script>
import {ref,reactive} from 'vue'
export default {
  name: 'Home',
  setup(){
    let name = ref('Ponyo ')
    let age = ref(18)
    let job=reactive({
      occupation:'programmer',
      salary:'10k'
    })
    let hobby=reactive(['having dinner','sleep','Beat beans'])
    console.log(name)
    console.log(age)
    //method
    function say(){
      job.salary='12k'
      hobby[0]='study'
    }
    return {
      name,
      age,
      job,
      say,
      hobby
    }
  }
}
</script>

At this time, you will feel that there are too many methods. You might as well use the methods provided by ref value, does it feel refreshing, but there is a problem. If there is a pile of data, it doesn't have to go all the time value, when the point is smoking, you can use the form of data in simulated vue2, and it will feel more fragrant

<template>
  <div class="home">
    <h1>full name:{{data.name}}</h1>
    <h1>Age:{{data.age}}</h1>
    <h2>occupation:{{data.job.occupation}}<br>Salary:{{data.job.salary}}</h2>
    <h3>Hobbies:{{data.hobby[0]}},{{data.hobby[1]}},{{ data.hobby[2] }}</h3>
    <button @click="say">modify</button>
  </div>
</template>

<script>
import {reactive} from 'vue'
export default {
  name: 'Home',
  setup(){
    let data=reactive({
      name:'Ponyo ',
      age:18,
      job:{
        occupation:'programmer',
        salary:'10k'
      },
      hobby:['having dinner','sleep','Beat beans']
    })
    //method
    function say(){
      data.job.salary='12k'
      data.hobby[0]='study'
    }
    return {
      data,
      say,
    }
  }
}
</script>

Difference between ref and reactive

  1. ref defines the basic data type
  2. ref through object get and set of defineproperty() implement data hijacking
  3. ref operation data Value, not required for reading. value
  4. reactive defines the object or array data type
  5. reactive realizes data hijacking through Proxy
  6. reactive operation and reading data are not required value

6. Responsive principle of vue3

The response principle of vue2 uses object get and set of defineproperty hijack data to realize responsive

  • In vue2, only get and set methods are used to read and modify properties. When we add or delete, the page will not be updated in real time
  • If you change the array directly through subscript, the page will not be updated in real time

According to the responsive principle in vue3, Proxy is used for Proxy and the built-in object reflection in window is used. After learning the syntax of Es6, we know that we are using Proxy for Proxy. For example, Party A's company gives the front-end siege lion of what technology is needed and asks Party B to do recruitment, interview and other links

  • Proxy can intercept any attribute changes in the object, including reading, writing, adding, deleting and so on

  • Reflect operates on source object properties

    const p=new Proxy(data, {
    //Called when a property is read
    get (target, propName) {
    return Reflect.get(target, propName)
    },
    //Called when a property is modified or added
    set (target, propName, value) {
    return Reflect.set(target, propName, value)
    },
    //Called when a property is deleted
    deleteProperty (target, propName) {
    return Reflect.deleteProperty(target, propName)
    }
    })

7. Differences between computed and watch and watcheffect

computed
In vue2, the computed method directly writes the current method to make the call

computed:{  //Calculation properties
            _suming(){
                return parseInt(this.one)+parseInt(this.two)
            },
            dataTimeing(){
                console.log("Calculation attribute method");
                // return "attribute calculation method" + new Date()
                return "Common method"+this.time
            }
        },

If calculated in vue3 is changed to composite Api, it means that it needs to be introduced. If it needs to be modified, it needs to be terminated

<template>
  <div class="home">
    Last name:<input type="text" v-model="names.familyName"><br>
    Name:<input type="text" v-model="names.lastName"><br>
    full name:{{fullName}}<br>
  </div>
</template>

<script>
import {reactive,computed} from 'vue'
export default {
  name: 'Home',
  setup(){
    let names=reactive({
      familyName:'wave',
      lastName:'Girl'
    })
    fullName=computed(()=>{
      return names.familyName+'.'+names.lastName
    })
    //Modify the writing method
    names.fullName=computed({
      get(){
        return	names.familyName+'.'+names.lastName
      },
      set(value){
        let  nameList=value.split('.')
        names.familyName=nameList[0]
        names.lastName=nameList[1]
      }
    })
    return {
      names,
      fullName
    }
  }
}
</script>

watch
In vue2, the watch monitors directly through the form of object

watch: {
            userName: {
                handler(val,res){
                    console.log(val);
                    console.log(res);
                },
                immediate:true,
                deep:true
            },
            
        }

Are watch and computed in vue3 combined APIs? It is

<template>
  <div class="home">
    <h1>Current number is:{{num}}</h1>
    <button @click="num++">Click the number plus one</button>
  </div>
</template>

<script>
import {ref,watch} from 'vue'
export default {
  name: 'Home',
  setup(){
    let num=ref('0')
    //Monitor single
    watch(num,(newValue,oldValue)=>{
      console.log(`The current number has increased,${newValue},${oldValue}`)
    })
    //Listen for multiple response data
     //watch([num,msg],(newValue,oldValue)=>{
     // console.log('current changed ', newValue,oldValue)
    //})

    return {
      num
    }
  }
}
</script>

Why is newValue the same as oldValue? It's embarrassing. It's all new data. Even if you use ref to define it, you still can't listen to oldValue (he mews and tells you that the object defined by ref will automatically call reactive). Therefore, when monitoring the response data defined by reactive, oldValue can't get it correctly, and you will find that, It is forced to turn on deep monitoring (deep:true) and cannot be turned off.

Reactive monitors responsive data, but only one of them. We all know that vue3 will monitor reactive or ref definitions and cannot monitor. What should we do if we need to monitor multiple attributes? It can only be written as follows

watch([()=>names.age,()=>names.familyName],(newValue,oldValue)=>{
  console.log('names Changed',newValue,oldValue)
})

What if we need to listen to the depth attribute? We all know that reactive is a responsive data attribute. If this attribute is an object, we can turn on depth listening

//First kind
watch(()=> names.job.salary,(newValue,oldValue)=>{
  console.log('names Changed',newValue,oldValue)
})
//Second
watch(()=> names.job,(newValue,oldValue)=>{
  console.log('names Changed',newValue,oldValue)
},{deep:true})

watchEffect
watchEffect is a new function in vue3. It can be seen from the literal meaning that it also has watch. In fact, it has the same function as watch

advantage

  • Enable immediate by default: true

  • Monitor whatever you need

  • It is called once when the value changes, and there is no need to return a value

    watchEffect(()=>{
    const one = num.value
    const tow = person.age
    console.log('watchEffect executed ')
    })

8. Life cycle

In vue2, we use new Vue() to execute beforeCreate and created, and then ask if you have VM$ mount(el)

In vue3, all are prepared before execution

Difference: beforeCreate and created have no composite API, and setup is equivalent to these two lifecycle functions

In setup

  • beforeCreate===>Not needed*
  • created=======>Not needed*
  • beforeMount ===>onBeforeMount
  • mounted=======>onMounted
  • beforeUpdate===>onBeforeUpdate
  • updated =======>onUpdatedupdated
  • beforeUnmount ==>onBeforeUnmount
  • unmounted =====>onUnmounted

9.hooks function

//Generally, a hooks folder is built and written in it
import {reactive,onMounted,onBeforeUnmount} from 'vue'
export default function (){
   //Mouse click coordinates
   let point = reactive({
      x:0,
      y:0
   })

   //Method for obtaining coordinates by mouse click
   function savePoint(event){
      point.x = event.pageX
      point.y = event.pageY
      console.log(event.pageX,event.pageY)
   }

   //Life cycle hook for realizing the method of mouse click to obtain coordinates
   onMounted(()=>{
      window.addEventListener('click',savePoint)
   })

   onBeforeUnmount(()=>{
      window.removeEventListener('click',savePoint)
   })

   return point
}
//Call elsewhere
import useMousePosition from './hooks/useMousePosition'
let point = useMousePosition()

10.toRef and toRefs

toRef is equivalent to ref type data

<template>
  <div class="home">
    <h1>Current name:{{names.name}}</h1>
    <h1>Current age:{{names.age}}</h1>
    <h1>Current salary:{{names.job.salary}}K</h1>
    <button @click="names.name+='!'">Click Add!</button>
    <button @click="names.age++">Click plus one</button>
    <button @click="names.job.salary++">Click salary plus one</button>
  </div>
</template>

<script>
import {reactive} from 'vue'
export default {
  name: 'Home',
  setup(){
    let names=reactive({
      name:'Lao Tan',
      age:23,
      job:{
        salary:10
      }
    })
    return {
      names
    }
  }
}
</script>

At this time, we just operate variables. If we need to operate the page string, can we achieve responsiveness? At this time, we need to put name XX becomes toRef to operate the data in name,
At this time, you will definitely want to say that mom sells the batch. Why don't I use ref to change it? Ref can also achieve the effect of responsive data. The data in the current names is not the source data, but the newly defined data, and the names of the source data are not modified by natural operation

return {
  name:names.name,
  age:names.age,
  salary:names.job.salary
}

return {
  name:toRef(names,'name'),
  age:toRef(names,'age'),
  salary:toRef(names.job,'salary')
}

return {
  name:ref(names.name),
  age:ref(names.age),
  salary:ref(names.job.salary),
}

toRefs
What's the difference between toRefs and toRef? You can see the literal meaning. S must mean more. (at this time, you're guessing, it's like this.) be confident, meow, at present It's the structure once. If you don't understand it, you can go to see Es6. That's just a lot to talk about

 <h1>Current name:{{name}}</h1>
 <h1>Current salary:{{job.salary}}K</h1>
return {
    ...toRefs(names)
}

11.router

This is still used in vue2 r o u t e r . P u s h for routing jump. There are no these in v u e 3, but a v u e r o u t e r is defined, which directly introduces u s e r o u t e, u s e r o u t e r, which is equivalent to the't h i s provided in v u e 2 router. Push is used for route jump. There are no these in vue3, but a Vue router is defined, which directly introduces useroute and userouter, which is equivalent to 'this' provided in vue2 router. Push is used for route jump. There are no these in vue3, but a vuerouter is defined, which directly introduces useroute and userouter, which is equivalent to 'this' provided in vue2 route,this. r o u t e r, don't ask this't h i s Router, don't ask this 'router', don't ask 'this route,this.$ What's the difference between router? I haven't seen it. I suggest you go and have a look vue2

import {useRouter,useRoute} from "vue-router";
setup(){
  const router= useRouter()
  const route= useRoute()
  function fn(){
    this.$route.push('/about')
  }
  onMounted(()=>{
    console.log(route.query.code)
  })
  return{
    fn
  }
}

12. Transfer of global Api (very important)

2.x global API (Vue)

3.x instance API(app)

Vue.config.xxxx

app.config.xxxx

Vue.config.productionTip

remove

Vue.component

app.component

Vue.directive

app.directive

Vue.mixin

app.mixin

Vue.use

app.use

Vue.prototype

app.config.globalProperties

vue2 can be accessed via Vue Prototype can only be operated through app. In vue3 config. Global properties, I thought I had made a mistake when I was playing. You will find that there are a lot of things that have been changed

Other APIs (understand)

13.shallowReactive and shallowRef

shallowReactive is a shallow level response. It only changes the data of the first level into a response, and the deep data will not become a response. If shallowRef defines basic type data, it is the same as ref and will not change. However, if it defines object type data, it will not respond, As we said before, if ref defines an object, it will automatically call reactive to become a Proxy, but if shallowRef is used, it will not call reactive to respond.

  • shallowReactive: deals only with the response of the outermost attribute of the object (shallow response).

  • shallowRef: only the response type of basic data is processed, and the response type of object is not processed

    let person = shallowReactive({
    name: 'Duan family in Dali',
    age:10,
    job:{
    salary:20
    }
    })
    let x = shallowRef({
    y:0
    })

14.readonly and shallowReadonly

  • readonly is to receive a responsive data and re assign the value. The returned data cannot be modified (deep read-only)

  • shallowReadonly is only shallow read-only (the first layer is read-only, and the rest can be modified)

    names=readonly(names)
    names=shallowReadonly(names)

15.toRaw and markRaw

toRaw actually turns a reactive object into a normal object. If it is defined by ref, it has no effect (including the objects defined by ref). If the data is added in subsequent operations, the added data is responsive data. Of course, if the data is markRaw, it will not become responsive. You may say, isn't it the same as readonly? That must be different. Readonly can't be changed at all, but markRaw doesn't convert to responsive, but the data will change

<template>
  <div class="home">
    <h1>Current name:{{names.name}}</h1>
    <h1>Current age:{{names.age}}</h1>
    <h1>Current salary:{{names.job.salary}}K</h1>
    <h1 v-if="names.girlFriend">girl friend:{{names.girlFriend}}</h1>
    <button @click="names.name+='!'">Click Add!</button>
    <button @click="addAges">Click plus one</button>
    <button @click="addSalary">Click salary plus one</button>
    <button @click="add">Add girlfriend</button>
    <button @click="addAge">Add girlfriend age</button>
  </div>
</template>

<script>
import {reactive,toRaw,markRaw} from 'vue'
export default {
  name: 'Home',
  setup(){
    let names=reactive({
      name:'Lao Wu',
      age:23,
      job:{
        salary:10
      }
    })
    function addAges(){
      names.age++
      console.log(names)
    }
    function addSalary(){
      let fullName=toRaw(names)
      fullName.job.salary++
      console.log(fullName)
    }
    function add(){
      let girlFriend={sex:'female',age:40}
      names.girlFriend=markRaw(girlFriend)
    }
    function addAge(){
      names.girlFriend.age++
      console.log(names.girlFriend.age)
    }
    return {
      names,
      add,
      addAge,
      addAges,
      addSalary
    }
  }
}
</script>

16.customRef

customRef creates a custom ref and explicitly controls its dependency tracking and update triggers
You can use its features for anti shake and throttling. The original method is not written in detail. Let's talk about the concept, and then come up with a throttling, anti shake, recursion, deep and shallow copy, etc

  • Anti shake: trigger the same time within the specified time and execute it only once (this time can be at the beginning or at the end)

  • Throttling: the same event is triggered within a specified interval. It is only executed once in the current time and only once in the next time (the current execution can be at the beginning or at the end)

    {{keyWord}}

17.provide and inject

You all know that component value transfer. In vue2, if you want to use the data of the parent component in the descendant component, you need to transfer the value of the parent and child components layer by layer or use vuex. But now, no matter how deep the component hierarchy is, the parent component can be the dependent provider of all its child components. This feature has two parts: the parent component has a provide option to provide data, and the child component has an inject option to start using the data

//father
import { provide } from 'vue'
setup(){
 let fullname = reactive({name:'A Yue',salary:'15k'})
 provide('fullname',fullname) //Pass data to your descendant components
 return {...toRefs(fullname)}
}
//Offspring
import {inject} from 'vue'
setup(){
 let fullname = inject('fullname')
 return {fullname}
}

18. Responsive judgment

  1. isRef: check whether the value is a ref object.

  2. isReactive: checks whether the object is a reactive proxy created by reactive.

  3. isReadonly: checks whether the object is a read-only proxy created by readonly.

  4. isProxy: check whether the object is a proxy created by reactive or readonly.

    import {ref, reactive,readonly,isRef,isReactive,isReadonly,isProxy } from 'vue'
    export default {
    name:'App',
    setup(){
    let fullName = reactive({name: 'Xiao Tang', price: '20k'})
    let num = ref(0)
    let fullNames = readonly(fullName)
    console.log(isRef(num))
    console.log(isReactive(fullName))
    console.log(isReadonly(fullNames))
    console.log(isProxy(fullName))
    console.log(isProxy(fullNames))
    console.log(isProxy(num))
    return {}
    }
    }

Topics: Javascript Front-end React Webpack html