美文网首页
Vue3和Vue2的区别

Vue3和Vue2的区别

作者: 黑白i | 来源:发表于2022-05-23 17:04 被阅读0次

    根标签


    Vue2

    • Templata只支持一个根标签
    <template>
      <div></div>
    </template>
    

    Vue3

    • Templata支持多个根标签
    <template>
      <div></div>
      <img/>
    </template>
    

    初始化方法


    Vue2

    • 使用 new Vue(), 参数是new Vue({template, render})
    import Vue from 'vue';
    import router from './routers/';
    import store from './stores';
    import App from './App.vue';
    const app =  new Vue({
      router,
      store,
      render: h => h(App)
    }).$mount('#app');
    

    Vue3

    • 使用 createApp() 参数是 createApp(组件)
    import { createApp } from 'vue';
    import App from './App.vue';
    import { router } from './router';
    const app = createApp(App).use(router).mount('#app');
    

    挂载容器


    Vue2

    • 可以通过el选项和$mount()方法来挂载容器
    new Vue({
    el:'容器名字 '
    })
    new Vue({
    }).$mount('容器名字')
    

    Vue3

    • 只能通过mount()方法来挂载容器
    Vue.createApp({
    }).mount('容器名字')
    

    data选项


    Vue2

    • data选项可以是一个对象,也可以是一个方法(由方法返回一个对象)
    new Vue({
    el:'容器名字 ',
    data:{
    }
    //或者
    new Vue({
    el:'容器名字 ',
    data () {
      return { }
    }
    })
    })
    

    Vue3

    • data选项只能是一个方法,由方法返回一个对象
    Vue.createApp({
    data(){
    return{}
    }
    }).mount('容器名字')
    

    响应式原理


    Vue2的响应式

    核心:

    • 对象: 通过defineProperty对对象的已有属性值的读取和修改进行劫持(监视/拦截)
    • 数组: 通过重写数组更新数组一系列更新元素的方法来实现元素修改的劫持
    Object.defineProperty(data, 'count', {
        get () {}, 
        set () {}
    })
    

    问题:

    • 对象直接新添加的属性或删除已有属性, 界面不会自动更新
    • 直接通过下标替换元素或更新length, 界面不会自动更新 arr[1] = {}

    Vue3的响应式

    核心:

    • 通过 Proxy(代理):拦截对data任意属性的任意(13种)操作, 包括属性值的读写, 属性的添加, 属性的删除等...
    • 通过 Reflect(反射):动态对被代理对象的相应属性进行特定的操作
    new Proxy(data, {
        // 拦截读取属性值
        get (target, prop) {
            return Reflect.get(target, prop)
        },
        // 拦截设置属性值或添加新属性
        set (target, prop, value) {
            return Reflect.set(target, prop, value)
        },
        // 拦截删除属性
        deleteProperty (target, prop) {
            return Reflect.deleteProperty(target, prop)
        }
    })
    
    proxy.name = 'tom'   
    

    Vue3的响应式数据的核心原理
    简单实现,代码如下:

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Proxy 与 Reflect</title>
    </head>
    <body>
      <script>
        
        const user = {
          name: "John",
          age: 12
        };
    
        /* 
        proxyUser是代理对象, user是被代理对象
        后面所有的操作都是通过代理对象来操作被代理对象内部属性
        */
        const proxyUser = new Proxy(user, {
    
          get(target, prop) {
            console.log('劫持get()', prop)
            return Reflect.get(target, prop)
          },
    
          set(target, prop, val) {
            console.log('劫持set()', prop, val)
            return Reflect.set(target, prop, val); // (2)
          },
    
          deleteProperty (target, prop) {
            console.log('劫持delete属性', prop)
            return Reflect.deleteProperty(target, prop)
          }
        });
        // 读取属性值
        console.log(proxyUser===user)
        console.log(proxyUser.name, proxyUser.age)
        // 设置属性值
        proxyUser.name = 'bob'
        proxyUser.age = 13
        console.log(user)
        // 添加属性
        proxyUser.sex = '男'
        console.log(user)
        // 删除属性
        delete proxyUser.sex
        console.log(user)
      </script>
    </body>
    </html>
    

    Vue3更好的 ts 支持

    • vue2 不适合使用 ts,在于它的 Options API 风格。
    • options 是一个简单的对象,而 ts 是一种类型系统、面向对象的语法,两个不匹配。
    • vue3 新增了 defineComponent 函数,使组件在 ts 下,更好的利用参数类型推断。如:reactive 和 ref 很具有代表性。

    Vue3更先进的组件

    Fragment

    • vue2 中,每个模板必须有一个根节点,否则就会报错。
    • vue3 中可以不需要根节点,多个元素或标签可并列存在。

    Teleport

    • 可以把 teleport 中的内容添加到任意的节点内,对于嵌套较深的组件来说绝对是一个福音。

    Supense

    • 允许程序在等待异步组件渲染一些后备的内容,可以让我们创建一个平滑的用户体验。

    Vue3新推出的组合式API

    • Vue2:定义方法的时候需要写在methods里面,后添加的属性是非响应式的。页面不更新。需要用get()和set()方法
    • Vue3:组合式API的作用是将原来分散开来定义的数据、方法、计算属性、监听器、组合起来定义一个完整的业务。

    生命周期


    vue2的生命周期

    vue2.png

    vue3的生命周期

    vue3.png
    与 2.x 版本生命周期相对应的组合式 API
    • beforeCreate -> 使用 setup()
    • created -> 使用 setup()
    • beforeMount -> onBeforeMount
    • mounted -> onMounted
    • beforeUpdate -> onBeforeUpdate
    • updated -> onUpdated
    • beforeDestroy -> onBeforeUnmount
    • destroyed -> onUnmounted
    • errorCaptured -> onErrorCaptured

    组合式 API 还提供了以下调试钩子函数:

    • onRenderTracked
    • onRenderTriggered

    例子
    演示各个生命周期钩子
    父组件App

    <template>
      <h2>App</h2>
      <button @click="isShow=!isShow">切换</button>
      <hr>
      <Child v-if="isShow"/>
    </template>
    
    <script lang="ts">
    import Child from './Child.vue'
    export default {
    
      data () {
        return {
          isShow: true
        }
      },
    
      components: {
        Child
      }
    }
    </script>
    

    子组件Child

    <template>
    <div class="about">
      <h2>msg: {{msg}}</h2>
      <hr>
      <button @click="update">更新</button>
    </div>
    </template>
    
    <script lang="ts">
    import {
      ref,
      onMounted,
      onUpdated,
      onUnmounted, 
      onBeforeMount, 
      onBeforeUpdate,
      onBeforeUnmount
    } from "vue"
    
    export default {
      beforeCreate () {
        console.log('beforeCreate()')
      },
    
      created () {
        console.log('created')
      },
    
      beforeMount () {
        console.log('beforeMount')
      },
    
      mounted () {
        console.log('mounted')
      },
    
      beforeUpdate () {
        console.log('beforeUpdate')
      },
    
      updated () {
        console.log('updated')
      },
    
      beforeUnmount () {
        console.log('beforeUnmount')
      },
    
      unmounted () {
         console.log('unmounted')
      },
      
      setup() {
    
        const msg = ref('abc')
    
        const update = () => {
          msg.value += '--'
        }
    
        onBeforeMount(() => {
          console.log('--onBeforeMount')
        })
    
        onMounted(() => {
          console.log('--onMounted')
        })
    
        onBeforeUpdate(() => {
          console.log('--onBeforeUpdate')
        })
    
        onUpdated(() => {
          console.log('--onUpdated')
        })
    
        onBeforeUnmount(() => {
          console.log('--onBeforeUnmount')
        })
    
        onUnmounted(() => {
          console.log('--onUnmounted')
        })
        
        return {
          msg,
          update
        }
      }
    }
    </script>
    

    相关文章

      网友评论

          本文标题:Vue3和Vue2的区别

          本文链接:https://www.haomeiwen.com/subject/wtnrprtx.html