Vue3相较于Vue2写法上的区别

764 阅读1分钟

引言

从Vue2开始学习Vue,到如今已经出现Vue3啦,从Vue2跨入Vue3 我们一起来学习之间的不同

区别

一、工程结构的区别

对比两者入口写法的不同

* Vue2写法 *
import Vue from 'vue'
import App from './App.vue'
new Vue({
  render: h => h(App),
  router
}).$mount('#app')

vue2使用的还是构造函数

* vue3写法 *
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')

vue3引入的不再是Vue构造函数了,引入的是一个名为createApp的工厂函数

Vue3使用工厂函数,可以直接将App组件放在createApp函数里直接注册,而且不再需要new,写法上更为简洁,且符合我们使用的逻辑

Vue3不支持Vue2的入口写法

模版结构不同

在Vue3里,template不再需要根标签,而vue2必须要根标签

二、Composition API

setup

setup是Vue3中新的配置项,组件中数据、方法都要放到setup里面最后一个对象的方式返回

 setup() {
    let name = 'suoshilei'
    let age = 18
    function sayHello() {
    alert('hello')
    }
    return {
      name,
      age,
    sayHello,
  }

相比于vue2中的data,methods配置项,vue3所有数据方法写到setup里,数据,函数直接定义

  • 虽然Vue3里也可以直接用Vue2 的写法,而且可以访问到setup中的值。但最好不要这么做,因为setup访问不到data,methods,computed...
  • 如果有重名,setup优先
  • setup不能用async,因为返回的是一个promise,模版看不到

vue2中的响应式只要是配置项里都是响应式的而vue3中要自己决定谁是响应式的

ref写法

在vue2中,ref作为标识符相当于id的作用; 而vue3中,ref则是创建一个响应式的引用对象,在里面的value属性里存在get,set实现了响应式

setup() {
    let name = ref('suoshilei')
    let age = ref(18)
    let position = ref({
      postMsg: '学生助理',
      salary:250
      
    })
    function change() {
      age.value = 19
      name.value = 'suo'
      position.value.postMsg = '助教'
      position.value.salary = 200
    
    }
    return {
      name,
      age,
      change,
    position
  }
}

原理上来说 对于基本类型 vue2、vue3依旧用的是defineProperty,但是在vue3中处理对象的响应则使用了reactive函数

reactive函数

vue3增加了reactive处理对象的响应

reactive函数不能处理基本类型的响应

import { reactive} from 'vue'
export default {
  setup() {
    let person = reactive({
      name: 'suoshilei',
      age: 18,
      position: {
        postMsg: '学生助理',
        salary: 250
      },
    })
    // 方法
    function change() {
      person.name = 'suo'
      person.age = 20
      person.position.postMsg = 'qwe'
      person.position.salary=230
    }
    return {
      person,change
  }
}
}

reactive运用原理是es6的Proxy实现响应式

Proxy代理:拦截对象中任意属性变化,包括对象的读写,属性的增删等

运用Proxy的好处在于,如果想在对象中添加属性就不再像vue2需要$set、$delete.直接添加属性即可

setup注意事项

  • setup在beforeCreate之前执行一次,this指向为undefined
  • setup函数有两个参数,一个是props,另一个是context

props可以接收外部传来的,且组件内部声明的属性

context:上下文

  • attrs:是一个对象,是外部传过来但没有声明的属性,相当于vue2中this.$attrs
  • slots:收到的插槽内容,相当于this.$slots
  • emit:分发自定义的函数 相当于this.$emit

computed计算属性

在vue3中computed变为函数式写法

import { reactive,computed} from 'vue'
    export default { 
        setup() {
            // data
            let person = reactive({
                    firstName: '张',
                    lastName: '三',
            })
            //计算属性
                person.fullName = computed(() => {
                return person.firstName + '-' + person.lastName
            })
            return { person}
        }
    }

watch监听属性

在vue3中watch也是函数式写法

import { ref, watch} from 'vue'
export default { 
    setup() {
        // data
        let sum = ref(0)
        let msg = ref('hello')
        //监听属性
        watch([sum,msg], (newvalue, oldvalue) => {
            console.log('我检查到sum值改变',newvalue,oldvalue);
        },{immediate:true})
        return {sum,msg}
    }
}

三个配置项,第一个配置项是要监视的目标,第二个配置项是一个函数类似于vue2中函数,第三个配置项是其他配置,包括immediate,deep

vue3中watch的坑

  1. 如果监听的是一个对象,那么不能获得oldvalue值,且deep值无效
  2. 如果监听的是对象里某一个值要用函数返回值写法
  3. 如果监听的是对象里某些值要用数组且必须用函数返回值写法