vue2和vue3区别


1、ref 的使用

v-for 中的 Ref 数组 | Vue.js (vuejs.org)

2、$children

$children | Vue.js (vuejs.org)

 

$children 实例 property 已从 Vue 3.0 中移除,不再支持。

3、插槽的使用

作用域插槽的写法

vue2.6以前

<template slot="t3" slot-scope="scope">
    {{scope.data}}
</template>

vue2.6以后

<template v-slot:t3="scope">
    {{scope.data}}
</template>

vue3只支持vue2.6之后的写法,vue2.6以前的写法不再支持,且vue3中可以进一步简化,用#代替v-slot:

<template #t3="scope">
    {{scope.data}}
</template>

4、响应式系统的升级

vue2

Vue2.0中使用ES5中的Object.defineProperty方法实现响应式数据
缺点
无法监测到对象属性的动态添加和删除
无法监测到数组的下标和length属性的变更
解决方案
Vue2.0提供Vue.set方法用于动态给对象添加属性
Vue2.0提供Vue.delete方法用于动态删除对象的属性
重写vue中数组的方法,用于监测数组的变更

<body>
    <script>
      // vue会做一个数据劫持,,,监视数据的变化,一旦数据变化了,更新DOM
      const data = {
        name: 'zs',
        age: 18
      }
      for (let k in data) {
        let temp = data[k]
        Object.defineProperty(data, k, {
          get() {
            console.log(`我劫持了${k}的获取`)
            return temp
          },
          set(value) {
            console.log(`我劫持了${k}的设置,值${value}`)
            temp = value
          }
        })
      }
      // Object.defineProperty有缺点
      // 1. 无法监视到新增的属性的变更和删除
      // 2. 无法劫持到数组的下标和长度
    </script>
  </body>
  <body>
    <div id="app">
      <h1>vue的例子</h1>
      <p>{{car.brand}} --- {{car.color}} ---{{car.price}}</p>
      <p>{{arr}}</p>
    </div>
    <script src="https://unpkg.com/vue@2.6.12/dist/vue.js"></script>
    <script>
      // vue中需要使用$set方法动态的增加一个响应式属性
      const vm = new Vue({
        el: '#app',
        data: {
          car: {
            brand: '奔驰',
            color: 'blue'
          },
          arr: ['张三', '李四']
        }
      })
    </script>
  </body>

vue3

通过 Proxy(代理): 拦截对data任意属性的任意(13种)操作, 包括属性值的读写, 属性的添加, 属性的删除等...
通过 Reflect(反射): 动态对被代理对象的相应属性进行特定的操作
Vue3.0中使用ES6中的proxy语法实现响应式数据
优点
可以检测到代理对象属性的动态添加和删除
可以监测到数组的下标和length属性的变更
缺点
ES6的proxy语法对于低版本浏览器不支持,IE11
Vue3.0会针对于IE11出一个特殊的版本用于支持ie11

  <body>
  <div></div>
  <script>
    const data = {
      name: 'zs',
      age: 18
    }
    // 能够监测到对象动态新增的属性以及删除的属性
    // proxy
    const proxyData = new Proxy(data, {
      get(target, name) {
        console.log(`检测到${name}的获取`)
        return target[name]
      },
      set(target, name, value) {
        console.log(`检测到${name}的设置,值为${value}`)
        target[name] = value
      },
      deleteProperty(target, key) {
        console.log(`监测到删除${key}`)
        return delete target[key]
      }
    })
  </script>
</body>

5、Composition API

5.1 composition-api解决了什么问题

1、使用传统的option配置方法写组件的时候问题,随着业务复杂度越来越高,代码量会不断的加大;由于相关业务的代码需要遵循option的配置写到特定的区域,导致后续维护非常的复杂,同时代码可复用性不高,而composition-api就是为了解决这个问题而生的。 

5.2 语法糖介绍

compositon-api提供了一下几个函数

  • reactive
  • watchEffect
  • computed
  • ref
  • toRefs
  • 生命周期的hooks

5.2.1 reactive

 import { reactive, computed } from 'vue'

  export default {
    setup() {
      const state = reactive({
        count: 0
      })
      
      function increment() {
        state.count++
      }
      
      return {
        state,
        increment
      }
    }
  }

Reactive 相当于当前的 Vue.observable () API,经过reactive处理后的函数能变成响应式的数据,类似于option api里面的data属性的值。

5.2.2 watchEffect

import { reactive, computed, watchEffect } from 'vue'

export default {
    setup() {
      const state = reactive({
        count: 0
      })

      const double = computed(() => state.count * 2)

      function increment() {
        state.count++
      }

      watchEffect(() => {
        console.log(double.value)
      })
      return {
        state,
        increment
      }
    }
}

Vue 中检测状态变化的方法,我们可以在渲染期间使用它。 由于依赖关系跟踪,当反应状态发生变化时,视图会自动更新。 在 DOM 中呈现某些内容被认为是一种“副作用” : 我们的程序在程序本身(DOM)之外修改状态。 要应用并自动重新应用基于反应状态的副作用,我们可以使用 watchEffect API。

5.2.3 computed

import { reactive, computed } from 'vue'

export default {
    setup() {
      const state = reactive({
        count: 0
      })
    
      const double = computed(() => state.count * 2)
    
      function increment() {
        state.count++
      }
    
      return {
        state,
        increment
      }
    }
}

有时我们需要依赖于其他状态的状态——在 Vue 中,这是通过计算属性来处理的。 要直接创建一个计算值,我们可以使用computed API。

5.2.4 ref

上面计算属性返回计算结果是什么? 如果我们猜测一下内部是如何实现 computed 的,我们可能会得出这样的结论

function computed(getter) {
  let value
  watchEffect(() => {
    value = getter()
  })
  return value
}

但是我们知道这是行不通的: 如果 value 是一个类似 number 的基本类型,那么一旦返回,它与 computed 内部的更新逻辑的连接就会丢失。 这是因为 JavaScript 基本类型是按值传递的,而不是按引用传递的

当一个值作为属性分配给一个对象时,同样的问题也会发生。 如果被赋为属性或从函数返回时,反应值不能保持其响应性,那么它就没有多大用处。 为了确保我们总是可以读取计算的最新值,我们需要将实际

值包装在一个对象中,然后返回该对象

function computed(getter) {
  const ref = {
    value: null
  }
  watchEffect(() => {
    ref.value = getter()
  })
  return ref
}

所以要拿到ref与computed的值应该是拿返回值下面的value

let count = ref(1)

console.log(count.value) // 1

let double = computed(() => count.value * 2) // 2

值得注意,当我们在template里面使用ref或者computed的时候,vue会自动把它们用reactive处理无需用count.value或者double.value的值,既<div>{{ count }} {{ double }}</div>即可

5.2.5 toRefs

toRefs API提供了一个方法可以把reactive的值处理为ref

5.2.6 生命周期的hooks

你可以通过在生命周期钩子前面加上 “on” 来访问组件的生命周期钩子。

下表包含如何在 setup () 内部调用生命周期钩子:

注意:因为 setup 是围绕 beforeCreate 和 created 生命周期钩子运行的(生命周期执行顺序:setup => beforeCreate() => created()),所以不需要显式地定义它们。换句话说,在这两个钩子中编写的任何代码都可以(应该)直接在 setup 函数中编写。

import { onBeforeMount, onMounted, reactive, watchEffect } from 'vue'

export default {
    setup() {
      const state = reactive({
        count: 0
      })

      const double = computed(() => state.count * 2)

      function increment() {
        state.count++
      }

      watchEffect(() => {
        console.log(double.value)
      })
      
      onMounted(() => {
        document.title = 'hello'
      })
      return {
        state,
        increment
      }
    }
}

5.3 最后讲讲关于使用composition api如何组织代码

往往是把一个功能的所有状态、方法、都封装到一个函数里面,方便统一管理,如果你按照这种方式来写代码,那么代码的结构大致如下

export default {
  setup() { // ...
  }
}

function useCurrentFolderData(networkState) { // ...
}

function useFolderNavigation({ networkState, currentFolderData }) { // ...
}

function useFavoriteFolder(currentFolderData) { // ...
}

function useHiddenFolders() { // ...
}

function useCreateFolder(openFolder) { // ...
}

当我们哪个功能需要在其他组件被复用的时候,直接把相关的方法提取出去,然后再引用进来就可以了

可以看出composition api的面向人群主要是经常写轮子或者框架的开发者,因为他更灵活,可以写出高内聚、低耦合的代码

使用vue3的过程中也不是一定要用composition api的,如果业务不是很复杂使用option api也是没什么问题的。

composition api和options api可以公用,但是vue3 推荐使用 composition api。

生命周期执行顺序:setup => beforeCreate() => created()

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM