文章目录
toRaw与markRaw
toRaw
- 作用:将一个由
reactive生成的响应式对象
转为普通对象。
(不适用于ref) - 使用场景∶用于读取响应式对象对应的普通对象,对这个普通对象的所有操作,不会引起页面更新。
markRaw
- 作用:标记一个对象,使其永远不会再成为
响应式对象
。
即数据可以改变,但是会在渲染到页面了。 - 应用场景:
(1)有些值不应被设置为响应式的,例如复杂的第三方类库等。
(2)当渲染具有不可变数据源的大列表时,跳过响应式转换可以提高性能。
例子
<template>
<h2>姓名:{
{name }}</h2>
<h2>年龄:{
{age }}</h2>
<h2>薪资:{
{job.j1.salary }}</h2>
<h2 v-show="person.student">同学:{
{ person.student }}</h2>
<br />
<button @click="showRawPerson">输出最原始的person</button>
<button @click="addStudent">添加同学</button>
<button @click="person.student.name += '~'">修改同学姓名</button>
<button @click="person.student.age += 1">增长同学年龄</button>
</template>
<script>
import {
reactive, toRefs, ref, toRaw, markRaw } from 'vue'
export default {
name: 'DemoVue',
setup() {
// let person = shallowReactive({
let person = reactive({
name: 'yang',
age: 18,
job: {
j1: {
salary: 20
}
}
})
function showRawPerson() {
const p = toRaw(person)
console.log(p)
}
function addStudent() {
const student = {
name: 'cheng',
age:20
}
person.student = markRaw(student)
}
return {
...toRefs(person),
showRawPerson,
addStudent,
person
}
}
}
</script>
输出效果:
customRef(自定义Ref)
- 作用:
customRef
用于创建一个自定义的ref,并对其依赖项跟踪和更新触发进行显式控制。
eg:
<template>
<input type="text" v-model="keyWord"/>
<h3>{
{keyWord}}</h3>
</template>
<script>
import {
ref,customRef} from 'vue'
export default {
name: 'DemoVue',
setup() {
// 自定义Ref——myRef
function myRef(value) {
console.log('---myRef---', value)
return customRef((track,trigger) => {
return {
// 有人读取该属性时调用
get() {
track()//追踪set修改value的变化
return value
},
// 有人修改该属性时调用
set(newValue) {
value = newValue
trigger()//通知Vue去重新解析模板(重新调用get)
}
}
})
}
// let keyWord = ref("hello")//vue提供的ref
let keyWord = myRef("hello")//自己定义的ref
return {
keyWord}
}
}
</script>
效果:
实现防抖效果
需求:修改数据后1s中再触发页面重新解析模板
实现:
<template>
<input type="text" v-model="keyWord"/>
<h3>{
{keyWord}}</h3>
</template>
<script>
import {
ref,customRef} from 'vue'
export default {
name: 'DemoVue',
setup() {
// 自定义Ref——myRef
function myRef(value,delay) {
let timer
console.log('---myRef---', value)
return customRef((track,trigger) => {
return {
// 有人读取该属性时调用
get() {
track()//追踪set修改value的变化
return value
},
// 有人修改该属性时调用
set(newValue) {
clearTimeout(timer)
timer = setTimeout(() => {
value = newValue
trigger()//通知Vue去重新解析模板(重新调用get)
}, delay)
}
}
})
}
// let keyWord = ref("hello")//vue提供的ref
let keyWord = myRef("hello",1000)//自己定义的ref
return {
keyWord}
}
}
</script>
效果:
一个要注意的问题是,在开启定时器之前先关闭所有的其他定时器,以实现”防抖“
效果。
”防抖“
效果:即连续输入的时候等待输入完成最终才将结果显示在页面上。
如果不关闭定时器会出现如下抖动效果:(连续输入的时候会出现抖动效果)
provide 与inject
-
作用:实现父组件与后代组件间的通信
-
方法:父组件有一个
provide
选项来提供数据,后代组件有一个inject
选项来开始使用这些数据
语法格式:provide('给传递的变量命名',变量名)
语法格式:inject('给传递的变量命名')
provide 与inject案例
父组件:
<template>
<div class="app">
<h2>我是app组件(父组件)</h2>
<h3>{
{name}}--{
{age}}</h3>
<Child/>
</div>
</template>
<script>
import Child from './components/Child.vue'
import {
provide, reactive, toRefs} from 'vue'
export default {
name: 'AppVue',
components: {
Child },
setup() {
const student = reactive({
name: 'yang',
age:18
})
provide('student',student)//给自己的后代组件传递数据
return {
...toRefs(student)
}
}
}
</script>
<style>
.app {
background: #333;
padding: 10px;
}
</style>
孙组件:
<template>
<div class="son">
<h2>我是son组件(孙组件)</h2>
<h3>{
{student.name}}--{
{ student.age}}</h3>
</div>
</template>
<script>
import {
inject } from '@vue/runtime-core'
export default {
name: 'SonVue',
setup() {
let student = inject('student')
return {
student
}
}
}
</script>
<style>
.son {
background: rgb(95, 24, 24);
padding: 10px;
}
</style>
效果:
扫描二维码关注公众号,回复:
14522300 查看本文章
![](/qrcode.jpg)
响应式数据的判断
isRef
:检查一个值是否为一个ref 对象isReactive
:检查一个对象是否是由reactive创建的响应式代理isReadonly
:检查一个对象是否是由readonly创建的只读代理isProxy
:检查一个对象是否是由reactive或者readonly方法创建的代理
eg:
<template>
<div class="app">
<h2>我是app组件</h2>
</div>
</template>
<script>
import {
ref, reactive, readonly, toRefs,isRef,isReactive,isReadonly,isProxy} from 'vue'
export default {
name: 'AppVue',
setup() {
const student = reactive({
name: 'yang',
age:18
})
let sum = ref(0)
let student2 = readonly(student)
console.log(isRef(sum))
console.log(isReactive(student))
console.log(isReadonly(student2))
console.log(isProxy(student))
console.log(isProxy(student2))
return {
...toRefs(student)
}
}
}
</script>
<style>
.app {
background: #333;
padding: 10px;
}
</style>
输出: