vue3

vue3带来了什么

  • 性能提升(打包体积减少, 内存减少, 渲染更快)
  • 源码升级(proxy代替defineProperty实现响应式)
  • 拥抱TS(更好支持TS)
  • 新特性

创建vue3工程

使用vue-cli创建

  1. 查看版本 vue --version
  2. 安装或升级 npm install -g @vue/cli
  3. 创建 vue create vue_test
  4. 启动 cd vue_test
    npm run serve

分析工程结构

//引入不再是vue构造函数,这就是与vue2区别, 引入一个createApp的工厂函数
import { createApp } from 'vue'
import App from './App.vue'

// createApp(App).mount('#app')
// 创建应用实例对象--app(类似于之前vue2里面的vm, app比vm更加轻盈)
const app = createApp(App)
// 挂载
app.mount('#app')

// const vm = new Vue({
//     render: h => h(App)
// })
// vm.$mount('#app')

当出现这种错误,表示没有挂载, 但是在测试的时候可以通过以下来改变当出现这种错误,表示没有挂载, 但是在测试的时候可以通过以下来改变
在vue.config.js中添加关闭语法检查即可
在这里插入图片描述


常用Composition API

1. setup

vue3的一个新配置, 值为一个函数.

组件中所用到的: 数据, 方法等均配置在setup中
setup函数有两个返回值:

  1. 若返回一个对象, 则对象中的属性和方法在模板中均可以直接使用.
  2. 若返回一个渲染函数, 则可以自定义渲染内容.
>`import { h } from 'vue'
> export default {
>  render() {
    return h('div')//h('div', 'hhhhhh')可以接收两个参数,
    //第一个是渲染的标签, 第二个是值
  }
}`

注意:

  1. 不要配合vue2使用, 因为vue2配置的data, methods等可以访问setup中的属性和方法, 而setup不能访问vue2配置, 若有重名,以setup优先.
  2. setup不能是一个async函数.因为返回值为一个promise,不再是一个对象,模板无法访问到return对象中的属性.

2. ref函数

ref标签属性打标识(vue2)
作用: 定义一个响应式数据.
语法: const xxx = ref(initValue)

  • 创建一个包含响应式数据的引用对象(reference对象, 简称ref对象).
  • JS中操作数据: xxx.value
  • 模板中读取数据,不需要.value,因为vue会自动解析加上.value

注意:

  1. 接收数据类型可以是: 基本数据类型, 对象类型.
  2. 基本数据类型: 响应式数据依靠Object.defineProperty()的get和set完成的
  3. 对象类型: 内部求助vue3中的reactive函数.

3. reactive函数

作用: 定义一个对象类型的响应式数据(基本数据类型不要, 用ref函数)
语法: const 代理对象 = reactive(源对象) 接收一个对象(或数组), 返回一个代理对象(Proxy的实例对象, 简称Proxy对象)

注意:

  1. reactive定义的响应式数据是深层次的
  2. 内部基于ES6Proxy实现, 通过代理对象操作源对象内部数据进行操作.

4. vue3中的响应式原理

1. vue2的响应式

实现原理:

  • 对象类型: 通过Object.defineProperty()对属性的读取, 修改进行拦截(数据劫持)
  • 数组类型: 通过重写更新数组的一系列方法来实现拦截.

存在问题:

  1. 新增属性, 删除属性, 界面不会更新
  2. 直接通过下标改变数据,界面不会自动更新

若想响应式添加:
this.$set(添加到某个位置中, 属性名, 属性值) --(this.person, ‘sex’, 女)
Vue.set(this.person, ‘sex’, 女)

响应式删除:
this.$delete(删除数据的位置, 属性名, 属性值) --(this.person, ‘sex’, 女)
Vue.delete()

修改数组中的数据:
this.$set(this.person.hobby, 0, ‘学习’) —第一个值为修改的位置, 第二个为下标, 第三个为修改的值.
this.person.hobby.splice(0, 1, ‘学习’) —第一个参数为下标, 第二个为删除个数, 第三个为修改的值

注意: splice()函数可以删除, 增加(第二个参数为0), 替换(先删除,再添加)

2. vue3的响应式

实现原理:

  • 通过Proxy(代理) : 拦截对象中任意属性的变化. 包括属性值读写, 添加, 删除等 (Proxy是一个vue中的构造函数)
  • 通过Reflect(反射) : 对源对象的属性进行操作.(响应式数据)

注意:
[ ]运算符可以使用字符串变量的内容作为属性名, 点运算符不能.
eg: obj = { name: ‘ly’}
读取到"name"字符串
obj[name] //输出ly , 不能通过obj.name

const person = {
      name:'ly',
      age:20
    }
    //p为代理对象, person为源对象
    const p = new Proxy(person, {
      // 拦截读取属性值
      get(target, propName){
        // target为源对象, propName为属性名
        return Reflect.get(target, propName)
      },
      // 拦截修改或增加新属性
      set(target, propName, value){
        return Reflect.set(target, propName, value)
      },
      // 拦截删除属性
      deleteProperty(target, propName){
        return Reflect.deleteProperty(target, propName)
      }
    })

5. reactive对比ref

  • 从定义数据角度:

    • ref用来定义: 基本数据类型
    • reactive用来定义: 对象(或数组)类型数据

注意: ref也可以用来定义对象(或数组)类型数据, 内部会自动通过reactive转为代理对象.

  • 从原理角度对比:

    • ref通过Object.defineProperty()的get与set来实现响应式(数据劫持)
    • reactive通过使用Proxy来实现响应式(数据劫持), 并通过reflect操作源对象内部的数据.
  • 使用角度对比:

    • ref定义的数据: 操作数据需要.value, 读取数据时模板中直接读取不需要.value
    • reactive定义的数据: 操作数据与读取数据: 均不需要.value.

6. setup注意点

  • setup执行的时机

    • beforeCreate之前执行一次, this是undefined.
  • setup的参数(只有两个参数)

    • props: 值为对象, 包含: 组件外部传递过来, 且组件内部声明接收了的属性

    • context: 上下文对象

      • attrs : 值为对象, 包含: 组件外部传递过来, 但没有props配置中声明的属性, 相当于vue2中this.$attrs.
      • slots : 收到的插槽内容, 相当于this.$slots, (若想使用具名插槽, 最好用v-slot:qqq,若用slot = “qqq”, 在子组件中会出现警告)
      • emit : 分发自定义事件的函数, 相当于this.$emit, 需要在子组件中进行emits配置, 否则会出现警告.

7. 计算属性和监视

1. computed函数
  • 与vue2中computed配置功能一致
  setup(){
    const person = reactive({
      fName : 'l',
      lName : 'y'
    })
    // 简写的计算属性, 只是可读, 不能修改
    // person.fullName = computed(() => {
    //   return person.fName + '-' + person.lName
    // })
    // 完整写法, 可以修改
    person.fullName = computed({
      get(){
        return person.fName + '-' + person.lName
      },
      set(value){
        const nameArr = value.split('-')
        person.fName = nameArr[0]
        person.lName = nameArr[1]
      }
    })
    return {
      person
    }
  }

2. watch函数

与vue2 中watch配置一样.

注意:

  1. 监视reactive定义的响应式数据时 : oldValue无法正确获取, 强制开启深度监视(deep配置失效)
  2. 监视reactive定义的响应式数据中某个属性时: deep配置有效.
watch(sum, (newValue, oldValue) => {
      console.log(newValue, oldValue);
    }, {immediate: true})
    //可以带有三个参数,第一个是监视的属性, 当属性值发生变化的时候,
    //自动调用第二个回调函数, 第三个参数是{immediate 表示立即监视, deep 表示深度监视}
    // 监视多个属性的时候第一个参数可以写成[sum, a, b] ref定义的响应式数据

    watch(person, (newValue, oldValue) => {
      console.log(newValue, oldValue);
    }, {immediate: true})
    // 当监视reactive定义的响应式数据, 此时无法获取oldValue, 
    //监视的是reactive响应式数据, 强制开启深度监视.

    watch(() => person.name, (newValue, oldValue) => {
      console.log(newValue, oldValue);
    }, {immediate: true})
    // 当监视的是reactive定义的响应式数据中某个属性的时候, 
    //deep才有效果, 并且第一个参数为一个函数, 
    //当监视多个属性的时候也可以用数组
3. watchEffect函数
  • watch的套路是: 既要指明监视的属性, 也要指明监视的回调.

  • watchEffect的套路是 : 不用指明监视那个属性, 监视的回调中用到那个属性, 就要监视哪个属性.

  • watchEffect有点像computed:

    • computed注重的计算出来的值(回调函数的返回值), 所以必须要写返回值.
    • watchEffect更注重的是过程(回调函数的函数体), 所以不用写返回值.
watchEffect(() => {
      const x1 = sum.value
      console.log('回调执行了');
    })

8. 生命周期

在vue3中都是组合式API
beforeCreate ==> setup
create ==> setup
beforeMounted ==> onBeforeMounted
mounted ==> onMounted
beforeUpdate ==> onBeforeUpdate
updated ==> onUpdated
beforeUnmount ==> onBeforeUnmounted
unmounted ==> onUnmounted

9. 自定义hook函数

  • 本质是一个函数, 将setup函数中使用的Composition API进行封装.
  • 自定义hook优势: 复用代码, 让setup中的逻辑更清楚易懂

10. toRef

  • 作用: 创建一个ref对象, 其value值指向另一个对象中的某个属性.
  • 语法: const name = toRef(person, ‘name’)
  • 应用: 要将响应式对象中某个属性单独提供给外部使用时.
  • 扩展: toRefs与toRef功能一致, 但可以批量创建多个ref对象, toRefs(person)

其他Composition API

1. shallowReactive 与 shallowRef

  • shallowReactive : 只处理对象最外层属性的响应式(浅响应式).

  • shallowRef : 只处理基本数据类型的响应式, 不进行对象的响应式处理.

  • 什么时候使用?

    • 如果有一个对象数据, 结构比较深, 但变化只是外层属性变化 ==> shallowReactive
    • 如果有一个对象数据, 后续功能不会修改该对象中的属性, 而是新生成的对象来替换 ===> shallowRef

2. readonly 与 shallowReadonly

  • readonly: 让一个响应式数据变为只读的(深只读).
  • shallowReadonly: 让一个响应式数据变为只读的(浅只读)
  • 当希望数据不被修改时.

3. toRaw 与 markRaw

  • toRaw:

    • 作用: 将一个由reactive生成的响应式对象转为普通对象.
    • 使用场景: 用于读取响应式对象对应的普通对象, 对这个普通对象的所有操作, 不会引起页面更改.
  • markRaw:

    • 作用: 标记一个对象, 使其永远不会再成为响应式对象.

    • 应用场景:

      1. 有些值不应被设置为响应式的, 例如复杂的第三方类库等.
      2. 当渲染具有不可变的数据源的大列表时, 跳过响应式转换可以提高性能.

4. customRef

  • 作用: 创建一个自定义的ref, 并对其依赖项跟踪和更新触发进行显示控制.
  • 实现:
   function myref(value){
      return customRef((track, trigger) => {
        return {
          get(){
            track()//追踪
            return value
           },
          set(newValue){
            value = newValue
            trigger()//重新解析模板
          }
        }
      })
    }
    let p = myref('hhh')

5. provide 与 inject

  • 作用: 实现祖与后代组件通信
  • 父组件有一个provide选项来提供数据, 后代组件有一个inject选项来开始使用这些数据.
//父组件
  let car = reactive({
      name :'ly',
      age: 20
    })
    provide('cat', car)
 //孙组件
    setup(){
        const cat = inject('cat')
        console.log(cat);
    }

6. 响应式数据的判断(返回都为布尔值)

  • isRef : 检查一个值是否为一个ref对象.
  • isReactive : 检查一个对象是否由reactive创建的响应式代理.
  • isReadonly : 检查一个对象是否是由readonly创建的只读对象.
  • isProxy : 检查一个对象是否是由reactive或者readonly方法创建的代理.

新组件

1. Fragment

  • vue2中 : 组件必须有一个根标签.
  • vue3中 : 组件可以没有根标签, 内部会将多个标签包含在一个Fragment虚拟元素中
  • 好处 : 减少标签层次, 减小内存占用

2. Teleport

  • 作用 : 将我们的组件html结构移动到指定位置的技术.
//to = "移动位置"
 <teleport to = "body">
    <div>
      <h3>哈哈哈哈</h3>
    </div>
  </teleport>

3. Suspense

  • 等待异步组件时渲染一些额外内容, 让应用更好的用户体验.
 <!-- 使用Suspense包裹组件, 并配置好default, fallback -->
  <Suspense>
    <template v-slot:default>
      <child/>
    </template>
    <template v-slot:fallback>
      <child/>
    </template>
  </Suspense>
// 异步引入 组件
import {defineAsyncComponent} from 'vue'
const child = defineAsyncComponent(() => import ('./components/Child.vue'))

vue3改变

  • data选项应始终被声明一个函数.
  • 类名修改: 过渡 v-enter改为v-enter-from, v-leave改为v-leave-from
  • 自定义别名按键keyup Vue.config.keyCodes.HH = 13 @keyup.hh = “show”, vue3中移除keyup, 并且不再支持config.keyCodes
  • 移除v-on.native修饰符
  • 移除过滤器…
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值