开始
本篇文章是2023暑期青训营第八篇,也是最后一篇啦!光阴似箭,岁月如梭,其实感觉自己没有学多少,但是时间就这么结束了。不过笔记还是要写的,聚沙成塔,总有一天能积累出高度来。本篇文章是一篇个人向的知识笔记,来讲讲最近在写项目过程中遇到的知识点:vue3中ref()和reactive()的差别,provide和inject的使用。
ref和reactive
写笔记之前的知识点
根据我粗浅的理解,ref与reactive有如下差异:
- ref适合用于基础数据类型,reactive适合对象和数组等引用类型。
- ref使用时需要
number.value而reactive不需要 - 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属性中,如果要对比新旧数据,还可以查看newValue和oldValue两个属性值
statusbar则是当前的状态值,一般第一个用的多
想要取消订阅可用方法unsubscribe()