Vue3 compares some differences and characteristics of Vue2

  1. Style comparison between vue3 and Vue2

Vue2 is commonly referred to as the options API

Vue3 is commonly referred to as the composition API

2. Relationship between vue2 option API and Vue3 composite API

  1. The purpose of the composite API is to enhance, not replace, the optional API. vue3 supports both APIs

  2. For simple scenarios, it is easier and more convenient to use the optional API

  3. The preferred composite API for projects requiring strong TS support

  4. Composite API s are preferred for scenarios that require a lot of logical reuse

3. Some considerations of vue3 vs. Vue2

  There can only be one root element in the template tag in vue2. Replace the root element in the template directly to #app

  There is no such restriction in vue3. You can put any number of root elements and add all the root elements in the template to #app in the form of appendChild instead of replacing them

vue2 add this to all data accessing data in methods, which can not be used in template

Data declared by vue3 using ref needs to be added with. value when accessing, which can not be used in template

The data of the composition API in vue3 is not declared in data, but in the new hook function setup()

To return an object in the setup function, the members in the object can be used directly in the template

four    Using the lifecycle hook function in the setup function

Use steps

  1. First, import the life cycle hook function starting with on from vue

  2. Calling the lifecycle function in the setup function and passing in the callback function

  3. The lifecycle hook function can be called multiple times

Example:

<template>
  <div id="dd"></div>
</template>

<script>
// 1. Import onMounted function
// onCreated no
import { onMounted, onBeforeMount  } from "vue";
export default {
  // Vue 2 life cycle review:
  // Initialization phase: beforeCreate created is executed only once
  // Mount phase: beforeMount mounted is executed only once
  // Update phase: beforeUpdate updated zero or N times
  // Destruction phase: beforeDestroy destroyed is executed only once
  setup() {
    // let dd = document.querySelector('#dd')
    // console.log(dd)
    // How to use life cycle hook functions in setup?
    // 2. calling onMounted in setup
    // Parameter: callback function, executed during the mounted life cycle
    onMounted(() => {
      let dd = document.querySelector("#dd");
      console.log(dd);
      console.log("onMounted Yes");
    });
    onMounted(() => {
      console.log("on also Mounted Yes");
    });

    onBeforeMount(() => {
      console.log('onBeforeMount Yes')
    })

    // Note: vue does not provide two hook functions in the initialization phase: onBeforeCreate onCreated
    // Vue3 thinks that the things to be done in these two phases can be done directly in setup
    // console.log(onCreated)
    // onCreated(() => {
    //   console.log('onCreated ')
    // })
  },
  mounted() {
    console.log("mounted Lifecycle hook function");
  }
};
</script>

5. Life cycle comparison of vue2 and Vue3  

Use of life cycle function under optional APILife cycle function usage under composite API
beforeCreateNo (write directly to the setup function)
createdNo (write directly to the setup function)
beforeMountonBeforeMount
mountedonMounted
beforeUpdateonBeforeUpdate
updatedonUpdated
beforeDestroy Vue 3: beforeUnmountonBeforeUnmount
destroyed          Vue 3: unmountedonUnmounted

six   Parent-child communication

In vue3's combinatorial API, the basic routine of passing from parent to child is exactly the same. The basic idea is still as follows: the transfer from parent to child is passed in through prop, and the transfer from child to parent is completed by calling user-defined events

Implementation steps

  1. The setup function provides two parameters. The first parameter is props and the second parameter is an object context

  2. props is an object, which contains all the prop data passed by the parent component. The context object contains attrs, slots and emit attributes, in which emit can trigger the execution of user-defined events to complete the transfer of child to parent

Example:

Father.vue

<template>
  <Son
    msg="This is the news from dad"
    :title="title"
    :list="list"
    @getValue="getValueHandler"
  ></Son>
</template>

<script>
import { ref } from "vue";
// Parent child communication: parent to child
// 1. Transfer data from parent component to child component and bind attributes
// 2. Define props receive and use in sub components
// props features: one-way data flow and one-way downlink binding (when the father changes, the son will synchronize, but the son changes the data, I don't recognize it)
// If the reference data type is passed in, it is feasible to modify the properties of the object, but ESLint will check and report an error by default, so ESLint needs to be configured or closed separately

// Parent child communication: child to parent
// 1. Customize an event for the child component in the parent component
// 2. Sub components trigger events and transfer data at the right time
import Son from "./components/Son.vue";
export default {
  components: {
    Son,
  },
  setup() {
    const title = ref("This is Dad's title");

    function getValueHandler(value) {
      console.log('Received data from my son:', value)
    }

    const list = ref([1, 2, 3]);
    return { title, list, getValueHandler };
  },
};
</script>

Son.vue

<template>
  <div>
    <p>Here are the subcomponents</p>
    <p>Received from parent component msg: {{ msg }}</p>
    <p>Received from parent component title: {{ title }}</p>
    <button @click="title = 'Changed to son's title'">I modified dad's title</button>
    <ul>
      <li v-for="(item, index) in list" :key="index">{{ item }}</li>
    </ul>
    <button @click="list.push(4)">Let me go list China Canada data</button>
    <hr>
    <button @click="sendValue">I'll send a message to Dad</button>
  </div>
</template>

<script>
export default {
  props: {
    // The data to be transferred by the parent component is defined here, which must be defined here
    msg: String,
    title: String,
    list: Array
  },
  // There are two parameters in the setup hook function:
  // Parameter 1: the data transmitted from the props parent component will be mounted on this object
  // Parameter 2: context object. There are some global instance methods, such as emit slots attrs
  // setup(props, context) {
  setup(props, { emit }) {
    // props data used previously: this.msg
    // Now there is no this. If you want to use props data in setup, you need to accept the first parameter: props
    // console.log(props)
    // console.log(context)
    // This / / no this
    function sendValue() {
      // A custom event is triggered here to carry data to the parent component
      // this here refers to the object returned by setup, so there is no way to call the $emit function
      // Therefore, this.$emit() cannot be used here to trigger events. What should I do?
      // console.log(this.$emit) 
      // Parameter 1: event name
      // Parameter 2~n: parameter to pass
      emit('getValue', 'This is the data of your son's filial piety to you')
      // Why do Vue2 instance methods start with $? 
      // Because when Vue2 is designed, all methods are put on the prototype
      // Members of data and methods will also be mounted to the object itself, this.msg
      // If the members on the prototype don't start with $, it's easy to have naming conflicts and the results after naming conflicts
      // this.$set this.$nextTick() this.$emit() this.$mount()
      // Vue3 is not designed like this. It is exposed to users in the form of context objects. The emergence of composition API design makes us less dependent on data and methods
    }
    return {sendValue}
  }
};
</script>

seven   provide and inject

Usually, we use props to transfer data between parents and children, but if the component nesting level is deep, it will become very cumbersome to transfer from one layer to the next. provide and inject, together, can easily complete the effect of transferring data from top-level components to any bottom-level components

Implementation steps

  1. The top-level component uses the provide function in the setup method to provide data

    provide('key ', data)

  2. Any underlying component uses the inject function in the setup method to get data

    const data = inject('key')

Example:

App.vue

<template>
  <Father></Father>
  <button @click="msg = 'stay App New data modified in'">stay App Modify data in</button>
</template>

<script>
// Objective: transfer data from App to Son
// Implemented using provide and inject
// 1. Import the provide function in App
// 2. call the provide function to provide data in setup.
// 3. Import the inject function in Son
// 4. call the inject function in setup to get data.
import Father from './components/Father.vue'
import { provide, ref } from 'vue'
export default {
  components: {
    Father
  },
  setup() {
    // Parameter 1: string, key, provided data ID
    // Parameter 2: Data
    // let msg = 'this is App data' / / static data
    const msg = ref('This is App Data')  // Responsive data
    // Provide ('msg ', MSG. value) / /. value means that the data is taken out and passed to the sub component, which loses the characteristics of responsiveness. If you want the data to be passed in a responsive manner, you can't add. value
    // If you do not add. value to indicate the transfer object, adding it is to obtain static data and pass it to the past
    provide('msg', msg)

    return {
      msg
    }
  }
};
</script>

Father.vue 

<template>
  This is Father assembly
  <Son></Son>
</template>

<script>
import Son from './Son.vue'
export default {
  components: {
    Son
  }
}
</script>

Son.vue 

<template>
  <div>
    This is Son assembly
    <p>This is the data received: {{ msg }}</p>
  </div>
</template>

<script>
import { inject } from 'vue';
export default {
  setup() {
    // Parameter: data ID key to get
    // Return value: Data
    let msg = inject('msg')
    return {
      msg
    }
  }
};
</script>

8. TemplateRef

When using ref in a template, we all know that it generally has three usage scenarios

  1. Ref + ordinary dom tag to get the real dom object < div ref = "box" > < / div > this. $refs.box

  2. Ref + component tag get component instance object < form ref = "form" / > this. $refs. Form. Validate()

  3. ref + v-for gets an array of dom objects (instance objects) (infrequently used)

Implementation steps

  1. Use ref function to pass in null to create ref object = > const href = ref (null)

  2. In the template, the association is established by defining the ref object name created in the ref attribute equal to 1 = > < H1 ref = "href" ></h1>

  3. Get the hrefleturn out

  4. Use = > href.value

Example:  

<template>
  <!-- Vue2 Practice -->
  <!-- <p ref="cuteP">This is a lovely p</p>
  <Father ref="dad"></Father> -->
  
  <!-- 3. Use on the label that needs to get the object ref Binding returned data -->
  <p ref="cp">This is a lovely p</p>
  <Father ref="father"></Father>
</template>

<script>
import { onMounted, ref } from 'vue';
// Objective: use ref in the setup function to get the native DOM object
import Father from './components/Father.vue'
export default {
  components: {
    Father
  },

  setup() {
    // 1. Use ref to create an empty data for later Association
    const cp = ref(null)
    const father = ref(null)

    // It cannot be obtained at this time. They are all null because setup is executed before beforeCreate
    console.log(cp.value)
    console.log(father.value)

    onMounted(() => {
      // 4. Use the data. value at the right time to access the native DOM
      // Execute after the native DOM is mounted
      console.log(cp.value)
      console.log(father.value)
    })

    // 2. Return the data for template use
    return {
      cp,
      father
    }
  }

  // mounted() {
  //   //Vue2's approach: it must be obtained in mounted
  //   console.log(this.$refs.cuteP)
  //   console.log(this.$refs.dad)
  // }
};
</script>

9. Incompatible syntax of vue3

  vue3 is compatible with most of the syntax of vue2, but there are some destructive syntax updates, which should be paid special attention to.

1. Remove the instance method $on (the existing implementation mode of eventBus is no longer supported and can be replaced by a third-party plug-in)

event Bus
 1. Vue.prototype.$eventBus = new Vue()
  2. In the component receiving data   this.$eventBus.$on('get-msg',(msg)=>{ })
  3. In the component that sends data   This. $eventbus. $emit ('Get MSG ',' transferred data ')
  eventBus mode is not supported by default in vue3   Use third-party plug-ins instead

2. Remove the filter (the filter can no longer be used in the interpolation expression, but can be replaced by methods)

Filter filter
For example: string formatting   Method receives the original string and returns the formatted string

{{ msg | formatMsg }}

vue3 removes this syntax directly   You can directly use methods instead  

{{ formatMsg('this is msg') }}  // The result of rendering is the function return value
methods:{
  formatMsg(msg){
     return msg + 'zs'
  }
}

3. Remove sync syntax (merge with v-model syntax)

. sync syntax
elementUI  -> Dialog  visible.sync="showFlag"
Function: simplify the triggering of custom events for parent-child communication
. sync - > V-model (key)

Tags: Javascript Front-end Vue.js

Posted on Sun, 28 Nov 2021 09:02:26 -0500 by Sindarin