Vue响应式进阶
shallowRef()、triggerRef()
shallowRef()
shallowRef():只有第一层数据变了组件才会重新渲染,深层数据变了组件不会重新渲染,watch也监听不到变化。
简而言之就是第一层是响应式数据,非第一层数据不是响应式数据
triggerRef()
上面的shallowRef()的作用是只有第一层数据变了才会重新渲染,那如果某种情况需要改变深层的某个数据怎么办?这时候就可以用triggerRef()
改变深层数据时强制渲染组件。
shallowRef()和triggerRef()是一对死对头,前者是深层数据改变的时候不让重新渲染组件,后者则是深层数据改变的时候偏偏就要重新渲染组件。
<script setup>
import { shallowRef, triggerRef } from 'vue'
const state = shallowRef({ count: 1 })// shallowRef: 只有第一层数据变了组件才会重新渲染,深层数据变了组件不会重新渲染// 按钮触发事件
function change() {// 数据会变,组件不会重新渲染,页面上显示的还是1state.value.count = 2// 数据会变,组件会重新渲染,页面上显示的会变成2// state.value = { count: 2 }// 强制更新state 组件会重新渲染,页面上显示会变成2triggerRef(state)
}
</script><template><div>{{ state.count }}<button @click='change'>改变</button></div>
</template>
customRef()
customRef():创建一个可以自己指定get和set方法的ref数据
customRef() 传入一个工厂函数,工厂函数中会有track和trigger两个参数,这两个参数都是函数。track是在get方法中触发,trigger是在set方法中触发。
track和trigger两个函数的作用就是将数据变成响应式,触发其他的方法,比如只有触发了track和trigger两个函数组件才会重新渲染,页面数据才会变。不然别的地方是不知道什么时候获取了数据,什么时候改变了数据。
<script setup>
import { customRef } from 'vue'let value = "高启强"
// customRef()中传入一个工厂函数,这个工厂函数接受 track 和 trigger 两个函数作为参数
const myRef = customRef((track, trigger) => {// 返回一个带有 get 和 set 方法的对象return {get() {console.log('获取数据');track()return value},set(newValue) {console.log('改变数据');value = newValuetrigger()}}
})function change() {console.log(myRef.value);// 获取数据// 高启强myRef.value = '高启兰'console.log(myRef.value);// 改变数据// 获取数据// 高启兰
}
</script><template><div>{{ myRef }}<button @click='change'>修改</button></div>
</template>
shallowReactive()、shallowReadonly()
和shallowRef()方法作用一样,shallowReactive()也是监听第一层数据,不一样的是数据是reactive数据,不是ref数据。shallowReadonly()是readonly数据,和前两数据刚好相反,只有第一层是不可修改的。
toRaw()、markRaw()
toRaw()
toRaw()方法的作用就是将数据打回原形,把身上的其他Vue监听方法都去掉,恢复到最原始的js数据。
<script setup>
import { toRaw, reactive } from 'vue'// 原始数据
const obj = {name: '孙悟空'
}// reactive数据
const obj1 = reactive(obj)
console.log(obj1 === obj); // false// 使用toRaw获取到原始数据
const obj2 = toRaw(obj1)
console.log(obj2 === obj); // true
</script>
markRaw()
<script setup>
import { markRaw, reactive, isReactive } from 'vue'// 原始数据
const obj = {name: '孙悟空'
}// 将原始数据保护起来,不能转为其他数据
const markObj = markRaw(obj)// 将保护起来的数据转为reactive数据(这里不会转成功,因为已经被markRaw保护过了)
const obj1 = reactive(markObj)// 不是reactive数据
console.log(isReactive(obj1)); // false
// 和原始数据一样
console.log(obj1 === obj); // true</script>
本文链接:https://my.lmcjl.com/post/18850.html
展开阅读全文
4 评论