青训营学习知识笔记 | 青训营

62 阅读2分钟

开始

本篇文章是2023暑期青训营第八篇,也是最后一篇啦!光阴似箭,岁月如梭,其实感觉自己没有学多少,但是时间就这么结束了。不过笔记还是要写的,聚沙成塔,总有一天能积累出高度来。本篇文章是一篇个人向的知识笔记,来讲讲最近在写项目过程中遇到的知识点:vue3中ref()和reactive()的差别,provide和inject的使用。

ref和reactive

写笔记之前的知识点

根据我粗浅的理解,ref与reactive有如下差异:

  • ref适合用于基础数据类型,reactive适合对象和数组等引用类型。
  • ref使用时需要number.valuereactive不需要
  • ref虽然可以设置对象类型,但对象内部的数据不是响应式的,对ref({...})的对象进行修改,不会反应在视图上;而reactive是响应式的,修改内部任意数据都会产生响应式。

根据使用的感受来说,上面的3条差异已经足够日常使用了,但知其然,还要知其所以然。

provide和inject

这两个语法的作用是暴露组件的属性和方法,有些类似export 父组件使用provide来进行数据传递,如下:

// Parent.vue

<template>
  <Child></Child>
</template>

<script setup>
import { ref, provide, readonly } from 'vue'
import Child from './components/Child.vue'

const name = ref('测试1')
const msg = ref('测试2')

// 使用readonly可以让子组件无法直接修改,需要调用provide往下传的方法来修改
provide('name', readonly(name))
provide('msg', msg)
provide('changeName', (value) => {
  name.value = value
})
</script>

孙子,使用inject获取父组件或往上的组件传递的数据

// Child.vue
<template>
  <div>
    <div>msg: {{ msg }}</div>
    <div>name: {{name}}</div>
    <button @click="handleClick">修改</button>
  </div>
</template>

<script setup>
import { inject } from 'vue'

const name = inject('name', 'hello') // 看看有没有值,没值的话就适用默认值(这里默认值是hello)
const msg = inject('msg')
const changeName = inject('changeName')

function handleClick() {
  // 这样写不合适,因为vue里推荐使用单向数据流,当父级使用readonly后,这行代码是不会生效的。没使用之前才会生效。
  // name.value = '雷猴'
  // 正确的方式
  changeName('修改名字')
  // 因为 msg 没被 readonly 过,所以可以直接修改值
  msg.value = '世界'
}
</script>

如果想要使子孙传递给爷爷,则比较建议使用pinia,pinia作为vueX的升级版,可以供整个项目的组件使用,更为快捷方便

store.$subscribe

想要监视仓库数据发生变化并修改数据,可以使用store.$subscribe方法进行监听,监听方法如下:

store.$subscribe((mutations,statusbar)=>{
  console.log(mutations)
  console.log(statusbar)
})

mutations是进行变更的数据,变更数据保存在target属性中,如果要对比新旧数据,还可以查看newValueoldValue两个属性值 statusbar则是当前的状态值,一般第一个用的多 想要取消订阅可用方法unsubscribe()