The opening

The syntax difference between Vue3 and Vue2 is the new combined API, which can greatly improve the readability and maintainability of the code.

Recall that when we use Vue2 syntax to modify a function, we first route to the corresponding view (.vue file), then use templete to locate the corresponding template element, and then go to methods to find the binding method on the element, which also involves data in data(). The data in data() may come from props or from API calls in lifecycle functions, or, in a purely presentable module, may involve computed (computed attributes). If there is more than one business logic involved in the component, the code in the entire file can be quite lengthy, leading to the official “separation of concerns” problem that the composite API is designed to address. (Personal understanding, light spray)

Vue3 new features

1.Composition API

There are a lot of things that can be covered in the combined API, so let’s show them one by one. First, create a Vue3 project using VUE-CLI (not the focus of this article, check out the official documentation).

1.1 the setup (), ref

<template>
    <div>
        <ul>
            <li v-for="(item,index) in menu" :key="item+index" @click="choose(index)">
                {{`${index}---${item}`}}
            </li>
        </ul>
        <h2>{{chooseFood}}</h2>
    </div>
</template>

<script>
import { ref } from 'vue'
    export default {
        name:'test'.setup() {
            const menu = ref(['Braised eggplant'.'Braised eggplant'.'Dried eggplant'])
            console.log('menu----',menu);
            console.log('created');
            const chooseFood = ref(' ')
            const choose = index= >{
                chooseFood.value = menu.value[index]
                console.log(menu.value[index]);
            }
            return{
               menu,
               chooseFood,
               choose
            }
        }
    }
</script>
// The setup() function is the same as the beforecreate () function, and the effect is equal to the beforecreate+created function, which can dynamically fetch data instead of data and methods.
// Use the ref function to declare reactive data. The data and methods used in the view are returned by return.

Copy the code

1.2 reactive

<template>
    <div>
        <ul>
            <li v-for="(item,index) in data.menu" :key="item+index" @click="data.choose(index)">
                {{`${index}---${item}`}}
            </li>
        </ul>
        <h2>{{data.chooseFood}}</h2>
    </div>
</template>

<script>
import { ref,reactive } from 'vue'
    export default {
        name:'test'.setup() {
            const data = reactive({
                menu : ['Braised eggplant'.'Braised eggplant'.'Dried eggplant'].chooseFood:' '.choose : index= >{
                    data.chooseFood = data.menu[index]
                    console.log(data.menu[index]); }})console.log('menu----',data.menu);
            console.log('created');
            return{
               data
            }
        }
    }
</script>
// Reactive proxies data and methods in data objects to achieve the same effect as 1.1.
Copy the code

1.3 toRefs

<template>
    <div>
        <ul>
            <li v-for="(item,index) in menu" :key="item+index" @click="choose(index)">
                {{`${index}---${item}`}}
            </li>
        </ul>
        <h2>{{chooseFood}}</h2>
    </div>
</template>

<script>
import { ref,reactive,toRefs } from 'vue'
    export default {
        name:'test'.setup() {
            const data = reactive({
                menu : ['Braised eggplant'.'Braised eggplant'.'Dried eggplant'].chooseFood:' '.choose : index= >{
                    data.chooseFood = data.menu[index]
                    console.log(data.menu[index]); }})const refData = toRefs(data)
            console.log('refData---',refData);
            return{
               ...refData
            }
        }
    }
</script>
// Return {... Data} is not reactive;
// After toRefs wraps, return{... RefData} equivalent to return{menu: Ref,chooseFood:Ref
       
        ,choose: Ref
        
       
}
Copy the code

ToRefs: Converts a reactive object into a normal object, where each property of the resulting object is a REF pointing to the corresponding property of the original object.

1.4 Life cycle function

Vue2--------------vue3 Added: BeforeCreate -> setup() onRenderTracked (tracking each value) created -> setup() onRenderTriggered (tracking changed values) beforeMount -> onBeforeMount mounted -> onMounted beforeUpdate -> onBeforeUpdate updated -> onUpdated beforeDestroy -> onBeforeUnmount destroyed -> onUnmounted activated -> onActivated deactivated -> onDeactivated errorCaptured -> onErrorCapturedCopy the code

First the new setup function, then the name change, the lifecycle function in Vue2 can still be used as usual (but the new hooks are recommended), then the two new ones for tracking data state, Hooks that simplify debugging (onRenderTracked, onRenderTriggered) and setup to use other lifecycle functions need to be introduced first;

<template>
    <div>
        <ul>
            <li v-for="(item,index) in menu" :key="item+index" @click="choose(index)">{{`${index}---${item}`}}</li>
        </ul>
        <h2>{{chooseFood}}</h2>
    </div>
</template>

<script>
import { ref,reactive,toRefs,onBeforeMount,onMounted,onBeforeUpdate,onUpdated,onRenderTracked,onRenderTriggered } from 'vue'
    export default {
        name:'test'.setup() {
            const data = reactive({
                menu : ['Braised eggplant'.'Braised eggplant'.'Dried eggplant'].chooseFood:' '.choose : index= >{
                    data.chooseFood = data.menu[index]
                    console.log(data.menu[index]); }})const refData = toRefs(data)
            console.log('1- Start creating component -----setup()',);
            onBeforeMount(() = > {
                console.log("2- Execute -----onBeforeMount() before mounting components to page");
            })

            onMounted(() = > {
                console.log("3- Execute -----onMounted() after the component is mounted to the page");
            })
            onBeforeUpdate(() = > {
                console.log("4- Component update before -----onBeforeUpdate()");
            })

            onUpdated(() = > {
                console.log("5- Component after update -----onUpdated()");
            })
            // onRenderTracked((event)=>{
            // console.log("onRenderTracked--------------->");
            // console.log(event);
            // }),
            onRenderTriggered((event) = >{
                console.log("onRenderTriggered--------------->");
                console.log(event);
            })

             return{
               ...refData
            }
        }
    }
</script>
Copy the code

1.5 watch

It takes three arguments:

  • A reactive reference or getter that you want to listen for
  • A callback
  • Optional configuration options

Compared with watch in Vue2, first of all, when listening to multiple data, array is used instead of writing multiple Watches. To listen on variables declared by reactive functions, use the form of getters, which is equivalent to Vue’s deep: true property for listening on complex types.

<template>
    <div>
        <ul>
            <li v-for="(item,index) in menu" :key="item+index" @click="choose(index)">
              {{`${index}---${item}`}}
            </li>
        </ul>
        <h2>{{chooseFood}}</h2>
        <div>
            <h3>{{name}}</h3>
            <button @click="rename">rename</button>
        </div>
    </div>
</template>

<script>
import { ref,reactive,toRefs, watch } from 'vue'
    export default {
        name:'test'.setup() {
            const name = ref('luo')
            const rename = () = >{
                name.value = 'joker'
            }
            const data = reactive({
                menu : ['Braised eggplant'.'Braised eggplant'.'Dried eggplant'].chooseFood:' '.choose : index= >{
                    data.chooseFood = data.menu[index]
                    console.log(data.menu[index]); }})console.log(name);
            console.log(data);
            watch([() = >data.chooseFood,name],(newValue,oldValue) = >{
                console.log(`new--->${newValue}`);
                console.log(`old--->${oldValue}`);    
            })            
            const refData = toRefs(data)
             return{
               ...refData,
               name,
               rename
            }
        }
    }
</script>
Copy the code

1.6 the computed

<template>
    <div>
        <ul>
            <li v-for="(item,index) in menu" :key="item+index" @click="choose(index)">
               {{`${index}---${item}`}}
            </li>
        </ul>
        <h2>{{chooseFood}}</h2>
        <div>
            <h3>{{name}}</h3>
            <h3>{{`doubleName:${doubleName}`}}</h3>
            <button @click="rename">rename</button>
        </div>
    </div>
</template>

<script>
import { ref,reactive,toRefs,computed,watch } from 'vue'
    export default {
        name:'test'.setup() {
            const name = ref('luo')
            const rename = () = >{
                name.value = 'joker'
            }
            const data = reactive({
                menu : ['Braised eggplant'.'Braised eggplant'.'Dried eggplant'].chooseFood:' '.choose : index= >{
                    data.chooseFood = data.menu[index]
                    console.log(data.menu[index]);
                }
            })
            watch([() = >data.chooseFood,name],(newValue,oldValue) = >{
                console.log(`new--->${newValue}`);
                console.log(`old--->${oldValue}`);    
            })         
            const doubleName = computed(() = >{return name.value+name.value})   
            const refData = toRefs(data)
             return{
               ...refData,
               name,
               rename,
               doubleName
            }
        }
    }
</script>
Copy the code

1.7 Teleport components

In Vue2, all components are mounted under the #app node, which requires complex nesting to avoid style intrusions, while Vue3’s Teleport component lets you mount components to any node.

//Modal.vue
<template>
        <div id="center">
            <h2>test demo</h2>  
        </div>
</template>

<script>
export default {}
</script>

<style scoped>
    #center {
        width: 200px;
        height: 200px;
        border: 2px solid black;
        background: white;
        display: flex;
        justify-content: center;
        align-items: center;
        }
</style>

//App.vue
<template>
      <Modal />
</template>

<script lang="ts">
import Modal from '.. /src/components/Modal.vue'
const app = {
  name: "App".components: {
    Modal
  }
};
export default app;
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

Copy the code

Use the Teleport component//Modal.vue
<template>
    <teleport to='#modal'>
        <div id="center">
            <h2>test demo</h2>  
        </div>
    </teleport>
</template>
Copy the code

1.8 Suspense components

//AsyncShow.vue
<template>
    <div>
        <h1>{{ result }}</h1>
    </div>
</template>

<script>
export default ({
    setup() {
        return new Promise((resolve,reject) = >{
            setTimeout(() = > {
                return resolve({result: 'check suspense'})},3000); })}})</script>
 
 //App.vue
 <template>
      <Suspense>
    <template #default>
      <AsyncShow />
    </template>
    <template #fallback>
      <div>
         Loading....
      </div>
    </template>
  </Suspense>
</template>
Copy the code

Setup () is used to do mixin work

In Vue2 we used mixins to reuse some common logic code blocks, such as Pagination. It does improve development efficiency, but on specific business pages, it’s hard to tell where attributes come from;

    //timeHooks.js
    import {ref} from "vue"
    const nowtime = ref("00:00:00");
    const getNowTime = () = > {
      const now = new Date(a);const hour = now.getHours() < 10? "0" + now.getHours() : now.getHours();
      const minutes = now.getMinutes() < 10? "0" + now.getMinutes() : now.getMinutes();
      const seconds = now.getSeconds() < 10? "0" + now.getSeconds() : now.getSeconds();
      nowtime.value =  hour + ":" + minutes + ":" +seconds
      setTimeout(getNowTime,1000);  
    };

    export {nowtime , getNowTime}
    
    //App.vue
    </template>
     <div>
        {{nowtime}}
     </div>
    </template>
    <script>
    import {getNowTime,nowtime} from '.. /src/hooks/timeHooks.js'
    const app = { 
      name: "App".setup() {
        getNowTime()
        return{ nowtime }; }};export default app;
    </script>
    
Copy the code

It’s more intuitive.

The above content is a combination of vuE3 official documents and teacher fat's tutorial study notes, welcome correction.Copy the code

V3.cn.vuejs.org/guide/intro…

Jspang.com/detailed?id…