普通网站设计,网站建设结课策划书,工信部备案网站查,最优惠的手机网站建设系列文章目录
TypeScript 从入门到进阶专栏 文章目录 系列文章目录一、shallowRef()二、triggerRef()三、customRef()四、shallowReactive()五、shallowReadonly()六、toRaw()七、markRaw()八、effectScope()九、getCurrentScope() 一、shallowRef() shallowRef()是一个新的响…
系列文章目录
TypeScript 从入门到进阶专栏 文章目录 系列文章目录一、shallowRef()二、triggerRef()三、customRef()四、shallowReactive()五、shallowReadonly()六、toRaw()七、markRaw()八、effectScope()九、getCurrentScope() 一、shallowRef() shallowRef()是一个新的响应式API用于创建一个浅层的响应式引用。它类似于ref()但有一个重要的区别当shallowRef()包装的对象发生变化时它不会递归地对其进行响应式处理。 具体来说shallowRef()内部使用了一个Proxy当访问shallowRef()包装的对象属性时会触发响应式。但如果修改对象的属性只会触发浅层的响应式不会对对象的内部属性进行递归处理。
这样的设计可以提高性能因为对于大型的复杂对象如果每次属性变化都进行递归的响应式处理会带来很大的性能开销。而使用shallowRef()可以选择性地对对象的某些属性进行响应式处理。
使用shallowRef()的示例如下
import { shallowRef } from vue;const obj {name: John,age: 25,address: {city: New York,country: USA}
};const refObj shallowRef(obj);console.log(refObj.value.name); // JohnrefObj.value.age 30;
console.log(obj.age); // 30修改refObj的属性会影响到原始对象refObj.value.address.city Los Angeles;
console.log(obj.address.city); // Los Angeles修改refObj的属性不会递归地对内部对象进行响应式处理需要注意的是shallowRef()只能包装对象或数组如果尝试包装一个基本类型的值如字符串、数字等将会抛出警告。
二、triggerRef() triggerRef() 是 Vue 3 中的一个函数它用于触发一个 ref 重新响应即重新执行计算 。
在 Vue 3 中ref 和 reactive 是用于响应式数据的两个主要 API。ref 用于创建一个包装了基本类型值的响应式对象而 reactive 用于创建一个包装了 JavaScript 对象的响应式对象。
当我们使用 ref 创建一个响应式对象时我们可以通过 .value 属性来访问和修改该对象的值。而 triggerRef() 函数可以用于手动触发一个 ref 的重新响应即重新执行 ref 的计算函数更新 ref 的值。
以下是 triggerRef() 函数的用法示例
import { ref, triggerRef } from vue;const count ref(0);function increaseCount() {count.value;
}// 手动触发 ref 重新响应
triggerRef(count);console.log(count.value); // 输出1在上面的示例中我们通过 triggerRef(count) 手动触发了 ref 的重新响应即使没有实际修改 count 的值它的计算函数仍然会被重新执行并更新 count 的值为 1。
三、customRef() vue3customRef() 是 Vue 3 中的一个可以创建自定义的 Ref 的函数。 在 Vue 3 中Ref是用来包装响应式数据的对象类似于 Vue 2 中的 data 对象。Ref 对象可以通过 .value属性访问和修改其包装的值。 vue3customRef() 函数接受一个包含 get 和 set 方法的对象作为参数返回一个自定义的 Ref 对象。通过自定义 get 和 set 方法可以实现对 Ref 对象中的值进行自定义的操作或处理。
示例使用方式如下
import { customRef } from vue;const myCustomRef customRef((track, trigger) {let value 0;return {get() {track(); // 追踪依赖关系return value;},set(newValue) {value newValue;trigger(); // 触发更新}};
});const count myCustomRef.value;console.log(count); // 0myCustomRef.value 10;console.log(count); // 10在这个示例中myCustomRef 是一个自定义的 Ref 对象其 get 方法用于返回 value 的值并使用 track 函数追踪依赖关系。set 方法用于设置新的值并使用 trigger 函数触发更新。
注意在 Vue 3 中Ref 对象的 .value 属性是只读的不能直接修改。因此需要通过 get 和 set 方法来访问和修改 Ref 对象中的值。
四、shallowReactive() shallowReactive() 用于创建一个浅响应式对象。 在 Vue 3 中响应式 API 发生了一些变化。与 Vue 2 中使用的 Vue.observable() 不同Vue 3 中引入了新的响应式函数如 shallowReactive()、reactive()、shallowReadonly() 等。
shallowReactive() 函数用于创建一个浅响应式对象意味着只有对象的顶层属性会被劫持成响应式的而嵌套的属性不会被劫持成响应式的。这是与 reactive() 函数最大的区别。
使用 shallowReactive() 可以轻松地创建一个简单的响应式对象而无需深度遍历对象的所有属性。
以下是一个使用 shallowReactive() 的示例
import { shallowReactive } from vueconst obj shallowReactive({name: Alice,age: 20,address: {city: New York,country: USA}
})console.log(obj.name) // 输出Alice
console.log(obj.age) // 输出20
console.log(obj.address) // 输出{ city: New York, country: USA }obj.name Bob
console.log(obj.name) // 输出Bobobj.address.city Los Angeles
console.log(obj.address.city) // 输出Los Angeles// 但是嵌套属性的变化不会触发更新
obj.address.country Canada
console.log(obj.address.country) // 输出Canada但不会触发更新五、shallowReadonly() shallowReadonly() 用于将一个对象转换为只读read-only的响应式代理。 这意味着被转换的对象将变成只读状态不能进行修改同时它的属性也会变成只读的响应式属性。 shallowReadonly() 的使用方式如下
import { shallowReadonly } from vue;const original { name: John, age: 25 };
const proxy shallowReadonly(original);console.log(proxy.name); // John
proxy.name David; // 抛出错误不允许修改该函数的特点是只会针对对象的第一层属性进行响应式代理对于嵌套的对象属性只会进行浅层代理。这意味着被代理的对象的嵌套属性仍然可以被修改。
import { shallowReadonly } from vue;const original { name: John, address: { city: New York, country: USA } };
const proxy shallowReadonly(original);console.log(proxy.address.city); // New Yorkproxy.address.city Los Angeles; // 可以进行修改
console.log(proxy.address.city); // Los Angeles需要注意的是shallowReadonly() 只会对对象进行只读代理但是它的属性仍然可以被修改。如果你希望所有层级的属性都是只读的则可以使用 readonly() 函数。
六、toRaw() toRaw() 用于将一个响应式对象转换为普通的 JavaScript 对象。 在 Vue 3 中使用 ref、reactive、computed 等函数创建的响应式对象本身是一个代理对象它会在访问或修改属性时触发依赖追踪实现了数据的自动更新。然而有时我们需要直接操作响应式对象的原始值而不想触发依赖追踪这时就可以使用 toRaw()。
toRaw() 方法接收一个参数即要转换的响应式对象它会返回该对象的原始值。如果传入的对象不是响应式对象toRaw() 会直接返回该对象本身。
下面是一个使用 toRaw() 的示例
import { reactive, toRaw } from vueconst obj reactive({ count: 0 })// 获取原始值
const rawObj toRaw(obj)
console.log(rawObj) // { count: 0 }// 修改原始值不会触发依赖追踪
rawObj.count 1// 原始值的修改不会影响到响应式对象
console.log(obj.count) // 0需要注意的是toRaw() 只能将一层响应式对象转换为普通对象如果转换的对象存在嵌套的响应式对象则嵌套的响应式对象仍然是代理对象。如果需要深度转换整个对象树可以使用 toRefs() 和 isRef() 方法。
七、markRaw() markRaw() 用于阻止响应式系统追踪一个对象从而使该对象变为 “原始”raw数据。 在 Vue 3 中默认情况下所有的对象都会被追踪并成为响应式对象即当对象发生变化时相关的界面会自动更新。然而有时我们希望某些对象不被追踪而作为普通的数据使用这时我们可以使用 markRaw() 函数。
通过调用 markRaw() 函数我们可以明确告诉 Vue 3 不要追踪某个对象即使该对象本身是响应式的。这意味着对该对象的修改不会触发相关界面的更新。
一般情况下我们只需要调用 markRaw() 函数来标记一个对象为原始数据即可而不需要经常使用它。它通常用于避免特定对象被追踪或者在某些场景下提高性能。
以下是一个示例
import { reactive, markRaw } from vueconst obj reactive({name: John,age: 30
})const rawObj markRaw(obj)console.log(rawObj.name) // John// 修改原始对象的属性不会触发响应式更新
rawObj.name Janeconsole.log(rawObj.name) // Jane在上面的示例中obj 是一个 reactive 对象它会被追踪并进行响应式更新。而 rawObj 是通过 markRaw() 函数将 obj 标记为原始对象修改 rawObj 的属性不会触发响应式更新。
八、effectScope() effectScope()是Vue3中新增的一个函数用于创建一个作用域范围在该范围内定义的响应式效果函数effect只会在范围内的响应式数据发生变化时执行。 通常情况下响应式效果函数会在其依赖的任何响应式数据发生变化时都会执行。但有时候我们只希望在特定的作用域范围内执行效果函数以避免不必要的计算和更新。
effectScope()函数创建一个作用域范围并返回一个stop函数。调用该stop函数可以停止该范围内的所有效果函数的执行并清理其依赖项。
以下是effectScope()的示例用法
import { effect, reactive, effectScope } from vueconst foo reactive({ count: 0 })effect(() {console.log(foo.count)
})const stop effectScope()effect(() {console.log(foo.count * 2)
})foo.count // 输出1 和 2stop() // 停止第二个效果函数的执行foo.count // 只输出3在上述代码中第一个效果函数会一直执行因为它会响应foo.count的变化。而第二个效果函数在effectScope()范围内定义只会在foo.count发生变化时才执行。调用stop()函数后第二个效果函数将不再执行即使foo.count再次发生变化。
effectScope()函数在一些特定场景下非常有用比如在处理动态组件时可以将用来清理的stop函数传递给子组件以确保在组件销毁时停止所有相关的效果函数的执行。
九、getCurrentScope() getCurrentScope()是Vue 3中的一个内置方法用于获取当前组件的作用域。 在Vue 3中组件的作用域是通过setup()函数中的props、context和attrs对象来访问的。getCurrentScope()方法可以获取到当前组件的作用域对象包括这些属性和方法。
要使用getCurrentScope()方法首先需要在组件的setup()函数中调用它来获取作用域对象然后可以对这个对象进行操作。
例如
import { getCurrentScope } from vue;export default {setup() {const scope getCurrentScope(); // 获取当前组件的作用域对象// 对作用域对象进行操作console.log(scope.props); // 输出组件的props属性console.log(scope.context); // 输出组件的context属性console.log(scope.attrs); // 输出组件的attrs属性// 返回组件的template、render或jsx}
}需要注意的是getCurrentScope()方法仅在setup()函数内部使用有效不能在其他地方使用。此外getCurrentScope()方法只适用于使用Composition API编写的Vue 3组件。