Vue3

为什么要使用 Vue3

1 . 更好的 逻辑复用代码组织 ( composition 组合式 api )

2 . 更好的 检测类型 ( 类型推导 Typescript 支持 )

Vue3 新特性

1 . 数据响应式 原理重新实现 ( ES6 的 proxy 替代了 ES5 的 Object.defineProperty)

2 . 虚拟 DOM - 新算法 (更快 更小)

3 . 提供了 composition api, 可以更好的逻辑复用

4 . template 模板可以有多个根元素

5 . 源码用 typescript 重写, 有更好的 类型推导 (类型检测更为严格, 更稳定)

小结: vue3 性能更高, 体积更小, 更利于复用, 代码维护更方便

Composition API

options API

vue2 采用的就是 optionsAPI

优点 : 易于学习和使用, 每个代码有着明确的位置

缺点 : 相似的逻辑, 不容易复用, 在大项目中尤为明显

注意 : 虽然 optionsAPI 可以通过 mixins 提取相同的逻辑, 但是并不好维护

Composition API

vue3 新增的就是 compositionAPI

注意 : vue3 推荐使用 composition API, 也保留了 options API

setup 函数

composition 的使用, 需要配置一个 setup 函数

setup 函数特点

使用:

<script>
export default {
  setup () {
    console.log('setup执行了')
    console.log(this) // undefined
    // 定义数据和函数
    const msg = 'hi vue3'
    const say = () => {
      console.log(msg)
    }
    return { msg , say}
  },
  beforeCreate() {
    console.log('beforeCreate执行了')
    console.log(this)
  }
}
</script>

template 中使用

<template>
  <div>
    <h1 @click="say()">{{msg}}</h1>
  </div>
</template>

注意 : setup 中不能使用 this, this 指向 undefined

reactive 函数

setup 中默认普通的数据不是响应式的, 需要用 reactive 函数

作用 : 将复杂类型数据, 转换成响应式数据 ( 返回该对象的响应式代理 )

注意 :

使用 :

setup ()

 setup () {
    const obj = reactive({
      name: 'zs',
      age: 18
    })
    return {
      obj
    }

template 模板中

<template>
  <div>{{ obj.name }}</div>
  <div>{{ obj.age }}</div>
</template>

ref 函数

reactive 处理的数据, 必须是 复杂类型, 如果是 简单类型 无法处理成响应式, 所以有 ref 函数

作用 : 对传入的数据(一般简单数据类型),包裹一层对象, 转换成响应式。

ref 函数注意点

使用 :

setup ()

<script>
import { reactive, ref } from 'vue'
export default {
  setup() {
    let money = ref(100)
    // setup 函数中必须使用 value 属性才能修改值
    money.value++
    return {
      money
    }
  }
}
</script>

template 模板中

<template>
  <div>{{ money }}</div>
  <button @click="money++">改值</button>
</template>

注意 : 对象一般使用 reactive,其他用 ref

toRef 函数

setup 中直接定义的数据 , 不是响应式数据 reactive 函数 , 放的是复杂数据类型
作用 : 使用 toRef函数 , 将 reactive 函数的响应式对象中的指定属性转换为响应式数据

语法 : toRef(参数1, 参数2)

用法 :

setup ()

<script>
import {reactive,toRef} from  'vue'
/* 目的:setup中直接定义的数据  不是响应式数据   reactive函数  放的是复杂数据类型 */
export default {
  setup () {
    var obj2={
      name:'jack'
    }
    //  使用reactive函数将obj转变成响应式数据
    var obj=reactive({
      name:'jack',
      age:'18'
    })
    // var name=toRef(目标对象[要求是响应式对象],指定变成响应式对象的属性)
    var name=toRef(obj,'name')
    var age=toRef(obj,'age')
    const say = () => {
      // obj.name='rose'
       console.log(name.value)
       name.value='lucy'
       age.value=20
    }
    return {say,obj,name,age}
  }
}
</script>

template 模板中

<template>
  <div>
     <input  type="button" @click="say()" value="btn"/>
  </div>
</template>

toRefs 函数

作用 : 对一个 响应式对象 的所有内部属性, 都做响应式处理, 保证展开或者解构出的数据也是响应式的( 一般配合 reactive 使用)

注意 : 对一个响应数据, 进行 解构 或者 展开, 会丢失他的响应式特性

注意 :

使用 :

setup ()

<script>
import { reactive, ref, toRefs } from 'vue'
export default {
  setup() {
    // const money = ref(100) // 简单类型, ref
    // const car = reactive({ // 复杂类型, reactive
    //   brand: '赛车',
    //   price: 100
    // })
    // const name = ref('zs') // 简单类型, ref
    // money.value++ // ref需要.value取值
    const state = reactive({
      money: 100,
      car: {
        brand: '赛车',
        price: 100
      },
      name: 'zs'
    })
    return {
      ...toRefs(state)
    }
  }
}
</script>

template 模板中

<template>
  <div>{{ money }}</div>
  <div>{{ car }}</div>
  <div>{{ name }}</div>
  <button @click="money++">改值</button>
</template>

计算属性 computed 函数

computed 函数调用时, 要接收一个处理函数, 处理函数中, 需要返回计算属性的值

使用 :

computed 是一个函数, 使用前也需要导入

基本用法

<script>
import { ref, computed } from 'vue'
export default {
  setup() {
    const age = ref(10)
    // 1. 传入一个函数 getter 返回一个值
    const nextAge = computed(() => {
      return +age.value + 1
    })
      
  return {
      age,
      nextAge
    }
  }
}
</script>

完整用法

    // 2. 传入一个对象, 包括get和set
    const nextAge = computed({
      get() {
        return +age.value + 1
      },
      set(value) {
        age.value = value - 1
      }
    })

template 模板中

<template>
  <input type="text" v-model="age">
  <input type="text" v-model="nextAge">
</template>

发表回复