Vue3新特性概述

一、双向数据绑定(响应式)原理

1. Vue2中的绑定

vue2的双向数据绑定是利用了es5 的一个API Object.definepropert() 对数据进行劫持 结合发布订阅模式来实现的。

new Vew({
    data:{ n: 0 } //n被隐藏,外界不能直接使用
    
    //给n添加get set方法,监听变化
    n:{
      get n(){ return this.n },
      set n(value){
          this.n = value;
          通知函数() => 更新虚拟DOM树
      }
    }
    
    methods:{
        add(){ this.n++ } //修改外界的n,并非真正的data里面的n
    }
})

缺点:

  • 只能在首次创建的new Vue()对象里本就有的属性添加监听方法(访问器属性),后来添加的成员无法添加,因此不能监听到变化。
  • 无法给索引数组的数字下标添加访问器属性。
  • 结果:后来添加的成员、通过下标修改索引数组中的元素值,页面都不自动更新。

2. Vue3中的绑定

vue3中使用了es6的proxyAPI对数据进行处理。proxy在目标对象的外层起到一层拦截器作用,外界对目标对象的所有操作都必须通过这层拦截,因此后来添加的成员一样得到监视。

<body>
  <script>
    var arr = [1, 2, 3]

    arr = new Proxy(arr, {
      get(currentObject, toGetValuePoint) {
        console.log(`有人视图获取arr中${toGetValuePoint}位置的元素值`)
        return currentObject[toGetValuePoint]
      },

      set(currentObject, toGetValuePoint, newValue) {
        console.log(`有人视图获取arr中${toGetValuePoint}位置的元素值为新值${newValue}`)
        currentObject[toGetValuePoint] = newValue
      }
    })

    let val = arr[3] //有人视图获取arr中3位置的元素值
    arr[1] = 4 //有人视图获取arr中1位置的元素值为新值4
  </script>
</body>

缺点:兼容性问题

二、脚手架创建的项目中的变化

1. main.ts文件 (了解)、axios模块化引入

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

// 模块化引入axios,不用像vue2一样挂到原型对象上,总是用this访问
import axios from 'axios'
axios.default.baseURL = '/。。。'

// 代替new Vew()
createApp(App).usu(router).use(store).mount(#app)

 2. setup()  

<template></template>

<script>
import { defineComponent, ref } from 'vue'

//vue3中引入defineComponent声明组件
export default defineComponent({
  //setup代替了vue2的beforeCreate、created
  //数据不再由data管理,而写在setup中
  setup(props) {
    let n = ref(10) //用ref包裹:起响应式作用 n={value:10}
    let b = ref('zs')
    
    const add = () => { n.value++ } //不可直接访问n,需通过n.value

    //必须将数据return才可以在模板中使用 数据 和 方法
    return { n, b, add }
  }
})
</script>

<style></style>
  • ref和toRefs配合使用集中监听 
<template></template>

<script>
import { defineComponent, ref } from 'vue'

export default defineComponent({
  setup(){
    const mydata = ref({
      n: 10,
      arr: [1,2,3],
      obj: { name: 'zs', age: 18 }
    })

    //结构出来,并用toRefs保持其响应式特性
    let { n, arr, obj } = toRefs(mydata.value)

    const myMethods = {
      add(){ n.value++ },
      change(){ arr[1] = 10 }
    }

    return {
      ...toRefs(mydata.value), ...myMethods
    }    
  }
})
</script>

<style></style>

3. watch监听函数

vue3中可写多个watch函数

<template></template>

<script>
import { defineComponent, ref, watch } from 'vue'

export default defineComponent({
  setup() {
    const mydata = ref({
      n: 10,
      arr: [1, 2, 3],
    })

    // 以便直接操作数据,不用 .value
    let { n, arr } = toRefs(mydata.value)

    watch(n,(newVal, oldVal) => { })
    watch(arr,(newVal, oldVal) => { })

    const myMethods = {
    }

    return {
      ...toRefs(mydata.value),
      ...myMethods
    }
  }
})
</script>

<style></style>

三、自定义指令

1. 全局自定义指令 main.ts 中

注:vue3中用mounted()函数代替了vue2中的inserted函数,其他用法一致。

<template>
    <input v-my-focus>
</template>

var app = createApp(App)

app.directive('my-focus',{
    mounted(el){
        el.focus()
    }
})

app.use(store).use(router).mount('#app')

2. 组件内有效的自定义指令

<template></template>

<script>
import { defineComponent, ref, watch } from 'vue'

export default defineComponent({
  directive:{
      'my-focus':{
         mounted(el){
           el.focus()
         }
      }
})
</script>

<style></style>

四、computed计算属性 

<template></template>

<script>
import { defineComponent, ref, computed } from 'vue'

export default defineComponent({
  setup() {
    const mydata = ref({
      phone:[
        {id:1, name: 'huawei', price: 10, count: 2},
        {id:2, name: 'iPhone', price: 30, count: 3},
        {id:3, name: 'xiaomi', price: 20, count: 4}

      ]
    })

    //结构出来,并用toRefs保持其响应式特性
    let { phone } = toRefs(mydata.value)

    const myMethods = {
      total: computed(() => {
        return phone.value.reduce((box, elem) => {
          box+elem.price*elem.count
        },0)
      })
    }

    return {
      ...toRefs(mydata.value),
      ...myMethods
    }
  }
})
</script>

<style></style>

五、过滤器

vue3中用计算属性代替过滤器

六、全局组件 main.ts 中

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

import MyCom from './MyCom.vue'
app.component('my-com',MyCom)

createApp(App).usu(router).use(store).mount(#app)

七、props属性

https://www.jb51.net/article/240862.htm

八、其他变化

posted @ 2022-09-04 00:46  RHCHIK  阅读(120)  评论(0编辑  收藏  举报