18
头图

Wide sea diving, sky high the birds to fly. Hey hello! I'm Molly

Vue3 has been released for some time, and it has also been supported by major manufacturers and communities and loved by many developers. The surrounding ecology is also gradually improving. It is a thriving landscape. This article aims to help you quickly master Vue3 by sorting out the common APIs of Vue2 and comparing Vue3 through differentiation

This article assumes that you already have some vue2 practical experience, and will not describe too much api details

Why upgrade to Vue3?

Two key factors led us to consider rewriting Vue with a new major version:

  1. General browser support for the new JavaScript language feature.
  2. The current Vue codebase has exposed design and architecture issues over time.

For more details, we can listen to the answer from the ancestor in Zhihu, written by You Yuxi: What did the new Vue 3 bring?

vue2 VS vue3 (coding somatosensory)

Recently, I made a background management system project about "shared stroller". Since it is a new project, I boldly selected vue3 + vite + typescript + element plus as the basic technology stack. However, there is currently no free and easy-to-use basic template framework for the middle and backstage on the market, so I imitated the portal of the big man in flower pants: vue-admin-template wrote a vue3 version vue-element-admin and applied to the actual project. For me personally coding practices, the relative vue2 of Option api the intuitive, vue3 of Composition api you can better organize your code , support custom hooks to achieve code reuse, thereby replacing mixin , in terms of code style, you can also write similar business logic to a code block, so as to avoid code dispersion, walking reading The code needs to jump up and down repeatedly. More friendly support TS and the addition of many new features also make vue3 easier to write and more conducive to code maintenance and expansion. Combined with the use of vite , it greatly improves the development experience. Overall, let's hug vue3 and give a like to the vue team👍👍👍

Intuitive new features of vue3

  • Brand new Composition api let's organize the code differently
  • <script setup> Syntax sugar to make the code more concise
  • The root element wrapping tag of template can be omitted
  • Provides a new built-in component <teleport> , which supports the component can be mounted to any dom node
  • Provided to use ---65986e693a23dc7a73a5b04a41974fa1 css in v-bind to introduce script variable, another powerful black magic trick
  • Use createApp to create an application instance
  • more friendly TS support
  • Use proxy proxy to replace defineproperty
  • Global and internal API have been refactored to support tree-shake

option api vs composition api

composition api vue3 a major feature of vue3 , ---c32b14599340b57541780fe42cc62996---exposed a large number of functions for us to reference and combine at will

In option api we instantiate Vue and pass in the behavior object as a parameter

 new Vue({
    data(){
        return {}
    },
    methods:{},
    computed:{},
    created(){},
    ...
})

In Composition api we can pass setup as the entry function and return an object data exposed to the template for use

 <template>
  <div @click="hi">{{ msg }}</div>
</template>
<script>
export default {
    setup() {
      const msg = ref('Hello!')
      function hi() {
        console.log(msg)
      }
      // 暴露给模板
      return {
        msg,
        hi
      }
    }
  }
</script>

setup also supports another way of writing, which simplifies the code even more

 <template>
  <div @click="hi">{{ msg }}</div>
</template>

<script setup>
const msg = ref('Hello!')
function hi() {
  console.log(msg)
}
</script>

When using <script setup> , any top-level bindings declared in <script setup> (including variables, function declarations, and import imports) can be used in the template use directly in

Definition of response data

vue2 define the response data to data function return

 data(){
    return {
        ...
    }
}

vue3 we can define the response data by ref and reactive

 const num = ref(0)
const obj = reactive({name:'molly'})

ref:

  • In the template, you can directly use the data defined by ref 11a25b62b18600791f8535e91570314a---, and in js you need to use .value to take a value or assign a value
  • Use geter , seter to implement responsive
  • It is recommended to use ref to define the base data

reactive:

  • You can use toRefs to unpack it, and use the corresponding attribute directly in the template
  • Use proxy proxy to implement responsive
  • It is recommended to use reactive to define complex data

lifecycle hooks

vue2 provides 11 lifecycle hooks, which we can define and use directly on the option object

vue3 , the lifecycle hooks are separated into corresponding hooks functions, which are called in the form of onXXX . It is worth noting that the lifecycle hook registration function can only be used synchronously during setup , which means that beforeCreate and created equivalent to setup Execution phase. The usage of other cycles is basically the same, for example: mounted corresponding to onMounted

 import { onMounted } from 'vue'
setup() {
    onMounted(() => {
        console.log('mounted!')
    })
}

computed

The two versions computed are basically the same, the difference is vue3 computed is extracted into one hooks function

 // vue2
computed:{
    num:()=>this.num *2
}
 // vue3

const numVal = computed(() => num.value *2)

watch

vue2:

watch Monitor the result change of a specific data source, and the parameters obtained by the callback function are the new value and the old value. In addition to listening data data can also listen props , $route , $emit , computed . The option parameter deep can be used for deep monitoring, and specifying immediate: true will trigger the callback immediately

 watch:{
    obj:(val,old)=>{
        deep: true,
        immediate: true
    }
}

vue3

vue3 's computed properties have been greatly enhanced to support monitoring multiple data sources and executing side effects

 // 监听单个数据源
const count = ref(0)
watch(count, (val, old) => {
  /* ... */
})
// 假设count是一个对象,也支持监听整个对象,而无需指定deep属性
 // 监听多个数据源
const count = ref(0)
const obj = reactive({name:'molly'})
watch([() => obj.name, count], ([newName, newCount], [oldName, oldCount]) => {
    /* ... */
})
// 监听多个数据源时,watch函数的第一个参数可传入数据源数组,第二个回调函数的参数也是一个数组

vue3 also added watchEffect , which means that a function passed in is executed immediately, while its dependencies are tracked responsively, and the function is rerun when its dependencies change.

Compared with watch , watchEffect does not need to pass in the specified monitoring data source, it will automatically collect dependencies. There is also no concept of new value and old value, as long as the dependency changes, the function will be re-executed

 const count = ref(0)
watchEffect(() => console.log(count.value))
setTimeout(() => {
  count.value++
}, 100)

watchEffect will return a function to stop this listener

When watchEffect in a component's setup function or lifecycle hook is called, the listener is linked to that component's lifecycle and automatically stops when the component is unloaded.

 const stop = watchEffect(() => {
  /* ... */
})
stop()

filters

vue2 , we can easily use the filters filter to process some text format conversion and process the data.

 filters: {
  sum(num1,num2) {
    return num1+num2
  }
}

PLEASE NOTE: In vue3 the filter will be removed and is no longer supported. Officials recommend that we use method calls or computed properties to replace filters

As for why this was removed api the official explanation is: although this seems convenient, it requires a custom syntax that breaks the expression inside the curly brackets "just JavaScript " assumption, this has not only a learning cost, but also an implementation cost.

My understanding is: api function design is repeated, filters can do things, calculated properties and function calls can also be done, and they can be done better. So Youda tearfully removed filters , poor filters can only be discarded

The same is true of life, the survival of the fittest in the workplace, I hope we will never be the one that is optimized filters 😭😭😭

components

vue2 we need to register the component through the option components , and in vue3 , we can use the component directly

 //vue2 
import A from './a.vue'
components:{
    A
}
 //vue3
<template>
  <A/>
</template>
<script setup>
    import A from './a.vue'
</script>

Instructions: vue2 VS vue3

The command usage of the two versions is basically the same, here I only list the differences vue3

v-model

vue2 We implement a custom v-model can write like this

 // vue2
props:{
    title:{
        type:String,
        default: 'molly'
    }
},
model: {
    prop: 'title',
    event: 'change',
},
methods:{
    change(val){
        this.$emit('input',val)
    }
},

vue3 can be defined in v-model parameter name, and also supports setting multiple v-model

 // vue3
props:{
    title:{
        type:String
    },
    num:{
        type:Number
    },
},
setup(props,{emit}){
    function change1(val){
        emit('update:title',val)
    }
    function change2(val){
        emit('update:num',val)
    }
    return {
        change1,
        change2
    }
}

// 在父组件中使用
<Son v-model:title="molly" v-model:num="18" />

add command

  • v-memo , which remembers a subtree of a template. Available on both elements and components. This instruction accepts a fixed-length array as a dependency value for memory comparison. If every value in the array is the same as when it was last rendered, the entire subtree update is skipped. Equivalent to memory for time, the same rendering content is read from memory. This is useful for long list scenarios

Other changes

  • For v-if / v-else / v-else-if each branch- key it will no longer be necessary, because now vue3 will automatically generate a unique key
  • The <template v-for> of key should be set on the <template> label (not on its children).
  • When acting on the same element, v-if will have higher priority than v-for .
  • The v-on .native modifier for ---aa7ff23bf098c58df8258d6d69e333ae--- has been removed.
  • v-for in ref no longer registered ref array
  • When using v-bind="object" with the same name as component individual properties, then the order in which the bindings are declared will determine how they are combined. The latter is the standard

     <!-- 模板 -->
    <div id="red" v-bind="{ id: 'blue' }"></div>
    <!-- 结果 -->
    <div id="blue"></div>
    
    <!-- 模板 -->
    <div v-bind="{ id: 'blue' }" id="red"></div>
    <!-- 结果 -->
    <div id="red"></div>

Component communication: vue2 VS vue3

A variety of ---1c3272c96cfa30421b7dac81621a8537 vue2 are provided in api for our component communication:

  • props / $emit / $on
  • $attrs / $listeners
  • provide / inject
  • $parent / $children / ref

Most of the --- vue3 are still supported in api , and have been adjusted appropriately

  • Removed $on , $off , $once instance methods
  • Removed $children instance property
  • $attrs now includes all attribute fa6f296176cd198f6eb465ad4c8dd346--- passed to the component, including class and style
  • In <script setup> you must use defineProps and defineEmits API to declare props and emits , they have the full type Inferred and directly available in <script setup>

slot vue2 vs vue3

In the slot, the two versions are basically the same, and there are not many changes, and the original use method is still retained. vue3 made a little update

  • this.$slots now exposes slots as functions
  • Removed this.$scopedSlots

Code reuse vue2 VS vue3

vue2 There are many ways of code reuse, mainly in the following ways

  • Component extraction
  • custom directive
  • Instances are mounted globally
  • Plug-in package
  • mixin
  • extend

vue3 also covers the above methods, and makes corresponding optimizations and updates

  • The method of instance global mount is in vue2 , we generally use prototype to mount the behavior object to vue prototype, this way Although simple and straightforward, there is also the problem of global pollution.
 Vue.prototype.$xxx = {name:'molly'}

Corresponding to vue3 , we are not allowed to do this, and replaced by app.config.globalProperties

  • mixin is also a great tool for code reuse, but it also exposes some problems. When mixin is abused or used heavily, it can lead to unclear dependencies and difficult maintenance. In vue3 it is recommended that we use the custom hooks method to reuse code.

Implement a custom hook

We can extract data and logic related to a function and maintain it together, such as implementing an accumulator

 import {ref, onUnmounted} from 'vue'
export function useAccumulator(){
    const count = ref(0)
    let timer = null
    timer = setInterval(()=>{
        count.value ++
    },1000)
    onUnmounted(()=>{
        clearInterval(timer)
    })
    return {count}
}

We define an accumulator hooks function, which can be used like a normal function at the component entry useAccumulator()

 import {useAccumulator} from '../utils'

let {count} = useAccumulator()

script setup added

Paste the description on the official website

<script setup> is a compile-time syntactic sugar for using the composition API in a single file component (SFC). Compared to the normal <script> syntax, it has more advantages:

  • Less boilerplate, cleaner code.
  • Can use plain Typescript declare props and throw events.
  • Better runtime performance (its templates are compiled into render functions in the same scope, without any intermediate proxies).
  • Better IDE type inference performance (reduces the language server's work to extract types from the code).

<script setup> has brought us great convenience, the advantages are as follows:

  • All top-level bound variable contents can be used directly in the template
  • <script setup> The value in the range can also be used directly as the label name of the custom component, which means that we can register the component without passing components
  • Support using :is to bind dynamic components
  • Support the top layer await , firstly than JavaScript to realize this feature in one step is cool

Powerful style features

Powerful style characteristic is vue3 another magic weapon

depth selector

In order to make the styles between components do not affect each other, we can write <style scoped> , when in scoped and want to make deep selection, you can use :deep() pseudo-class

 <style scoped>
.a :deep(.b) {
  ...
}
</style>

slot selector

By default, the scope style does not affect the <slot/> content, you can use the :slotted pseudo-class to select the slot

 :slotted(div) {
  color: red;
}

global selector

Global styles can be implemented through the :global pseudo-class

 :global(.red) {
  color: red;
}

css module support

CSS classes can be exposed to components as $style objects through <style module> , and custom names are also supported: <style module=“molly” >

 <template>
  <p :class="molly.red">red</p>
</template>

<style module="molly">
.red {
  color: red;
}
</style>

state driven dynamic css

This is the most convenient feature in my opinion, it allows us to write a lot less code, which is very cool

In style allows us to use v-bind to dynamically associate css values to components

 <template>
  <div class="text">hello</div>
</template>

<script>
export default {
  data() {
    return {
      color: 'red'
    }
  }
}
</script>

<style>
// v-bind可以直接引入script中的响应数据作为值
.text {
  color: v-bind(color);
}
</style>

Well, at this point, it should be easy to get started with the vue3 project. Friends who like it are welcome to like and leave a message for discussion. Like more than 30, I will continue to update the differentiated comparison vue-router4.x and vuex 4.x series

grateful

scatter flowers✿✿ヽ(°▽°)ノ✿

Click to follow me and let's play with the front end in a different posture. May you go all the way with light in your eyes!

scatter flowers✿✿ヽ(°▽°)ノ✿


前端有猫腻
556 声望638 粉丝