Vue响应式进阶

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 评论

留下您的评论.