vue3对比vue2的改变

vue3正式版本刚刚发布,虽然之前就看过预览文档, 但是这次是发布的正式版本值得好好总结一番
在阅读vue3文档之前应当先了解proxy以便更好的理解 Composition Api(组合api)
vue3文档地址

vue3对比vue2的改变

对比

  1. main.js中的改变

    import { createApp } from 'vue'
    // 创建App
    const app = createApp({})
    // 挂载路由, 全局组件, 全局指令等操作
    // 按道理来说vue2的挂载组件库的操作也是在这个中间执行的
    app.use(VueRouter)
    // 将app链接到#app元素中
    app.mount('#app')
    
    
  2. 删除了filters 官方建议使用计算属性或者方法代替过滤器

  3. template中可以写多个标签

    <template>
      <header>...</header>
      <main v-bind="$attrs">...</main>
      <footer>...</footer>
    </template>
    
  4. 新的动态绑定ref的方式

    <child-component :ref="(el) => child = el"></child-component>

  5. key属性

    • 对于 v-if/v-else/v-else-if 的各分支项 key 将不再是必须的,因为现在 Vue 会自动生成唯一的 key
    • <template v-for>key 应该设置在 <template> 标签上 (而不是设置在它的子结点上)
  6. transition 内置组件过度类名更改

    • leave-class 已经被重命名为 leave-from-class
    • enter-class 已经被重命名为 enter-from-class
  7. teleport 内置组件

    拥有to属性, 参数为css选择器, 将组件移动到对应选择器中, 会保持vue的特性,仅仅是迁移节点

    <teleport to=".some-class" /> // 该dom插入到 *.some-class 元素中
    

    将弹框插入到body中

  8. v-model用法拓展

    在vue2中修改父组件传入的props是一件很麻烦的事情

    大部分情况我们会使用 .sync 修饰符以及 $emit(“update:xx”,xx)来修改

    在vue3中如果子元素需要修改父元素传入的props的值, 父元素在传入该值的时候应该使用v-model传入

    传入v-model相当于

    <ChildComponent v-model:title="pageTitle" v-model:content="pageContent" />
    
    <!-- 上方代码等价于 -->
    
    <ChildComponent
      :title="pageTitle"
      @update:title="pageTitle = $event"
      :content="pageContent"
      @update:content="pageContent = $event"
    />
    
  9. Composition Api

    建议阅读响应式原理, Composition API , 响应性基础 API, Refs, Computed 与 watch, setup 这几篇文章

    总结以下常用的api

    • reactive 创建对象类型的响应式对象 , 注意该api创建的响应式对象解构时会失去响应, 可以使用toRef或者toRefs进行响应式绑定

      声明类型

      function reactive<T extends object>(target: T): UnwrapNestedRefs<T>
      
    • readonly 创建只读类型的响应式对象

    • shallowReactive 创建一层浅响应式对象 (不会对对象内部的对象进行响应式绑定)

    • shallowReadonly 创建一层只读的浅响应式对象(不会对对象内部的对象进行响应式以及只读绑定)

    • ref 创建一个响应式且可变ref对象

      类型声明

      interface Ref<T> {
        value: T
      }
      
      function ref<T>(value: T): Ref<T>
      
    • toRef 可以用来为源响应式对象上的 property 性创建一个ref。然后可以将 ref 传递出去,从而保持对其源 property 的响应式连接。

      const state = reactive({
            foo: 1,
            bar: 2
      })
      
      const fooRef = toRef(state, 'foo')
      
      fooRef.value++
      console.log(state.foo) // 2
      
      state.foo++
      console.log(fooRef.value) // 3
      

      当您要将 prop 的 ref 传递给复合函数时,toRef 很有用:

      export default {
            setup(props) {
              useSomeFeature(toRef(props, 'foo'))
            }
      }
      
    • toRefs 将响应式对象转换为普通对象,其中结果对象的每个 property 都是指向原始对象相应 property 的 ref

      const state = reactive({
            foo: 1,
            bar: 2
      })
      /*
       // 相当于执行操作
       stateAsRefs = {
       	foo: ref(state.foo),
       	bar: ref(state.bar)
       }
       // 所以解构也不会丢失响应性
      */
      
      const stateAsRefs = toRefs(state)
      /*
      Type of stateAsRefs:
      
      {
        foo: Ref<number>,
        bar: Ref<number>
      }
      */
      
      // ref 和 原始property “链接”
      state.foo++
      console.log(stateAsRefs.foo.value) // 2
      
      stateAsRefs.foo.value++
      console.log(state.foo) // 3
      

      当从合成函数返回响应式对象时,toRefs 非常有用,这样组件就可以在不丢失响应式的情况下对返回的对象进行分解/扩散:

      function useFeatureX() {
        const state = reactive({
          foo: 1,
          bar: 2
        })
      
        // 逻辑运行状态
      
        // 返回时转换为ref
        return toRefs(state)
      }
      
      export default {
            setup() {
              // 可以在不失去响应式的情况下破坏结构
              const { foo, bar } = useFeatureX()
      
              return {
                foo,
                bar
              }
            }
      }
      
    • Computed , watchEffect 与 watch 计算属性与观察属性, 具体查看文档,本文不做过多的复制

      watchEffect与watch的区别在于

      • watchEffect会自动根据函数内的依赖而重新运行, 不需要明确的指明监听那个数据
      • watch与vue2并无太大区别
    • setup中新的生命周期钩子

      • beforeCreate -> use setup()
      • created -> use setup()
      • beforeMount -> onBeforeMount
      • mounted -> onMounted
      • beforeUpdate -> onBeforeUpdate
      • updated -> onUpdated
      • beforeUnmount -> onBeforeUnmount
      • unmounted -> onUnmounted
      • errorCaptured -> onErrorCaptured
      • renderTracked -> onRenderTracked
      • renderTriggered -> onRenderTriggered

说一下ref与reactive的区别

网上有人说ref只能包裹基本数据类型(字符串,数字,布尔,undefined,null),我翻遍了官网也没找到对应的说明, 相反,我在官网中发现了如下示例代码
在这里插入图片描述
而在API文档中有如下说明如果将对象分配为 ref 值,则可以通过 reactive 方法使该对象具有高度的响应式。从侧面印证出ref是可以包裹对象和数组的。
以及我在网上找到了一篇和我看法相同的文章: 来自 太_2_真_人vue3的ref和reactive分别何时使用?
并且查看了文章中去gethub上提的issues进一步印证了我的想法
引用文章中的原话

所以,ref和reactive并不是用来区分基本数据类型和引用数据类型的,反而他们的功能是一样的,只不过适用场景不太一样,了解这点之前先看下下面的代码:

// 风格1
let age = 10
let name = 'zhangsan'

function updatePerson() {
 age = 20
}
// 风格2
let person = {
 age: 10,
 name: 'zhangsan',
 sex: 'male'
}

function updatePerson() {
 person.age = 20
}

以上两种写法其实都对,只不过适用的写代码的风格不太一样,ref和reactive的区别就分别类似上面的风格1和风格2:

// ref
let age = ref(10)
let name = 'zhangsan'
// reactive
let person = reactive({
 age: 10,
 name: 'zhangsan'
})

粗略总结, 如有错误以及未写入的新特性请各位评论区指出

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值