做搜狗手机网站排,哪里有免费的网站推广软件,建设个人网站多少钱,企业网站建设 骆shallowRef()
shallowRef 是一个特殊的 ref 创建函数#xff0c;它允许你创建一个只追踪顶层属性变化的响应式引用。与 ref 不同的是#xff0c;shallowRef 创建的响应式引用对其内部值的深层嵌套属性是不敏感的#xff0c;也就是说#xff0c;只有当 shallowRef 的 .valu…shallowRef()
shallowRef 是一个特殊的 ref 创建函数它允许你创建一个只追踪顶层属性变化的响应式引用。与 ref 不同的是shallowRef 创建的响应式引用对其内部值的深层嵌套属性是不敏感的也就是说只有当 shallowRef 的 .value 被一个新对象替换时Vue 的响应式系统才会追踪这个变化。shallowRef 的主要作用是创建一个只对其顶层属性敏感的响应式引用。这在某些场景下非常有用比如当你想要引用一个大型对象或数组并且只需要关心该对象或数组的引用变化而不关心其内部属性的变化时。但是请注意不要意外地修改其内部属性因为这可能不会触发视图更新。
import { shallowRef } from vue; // 创建一个 shallowRef
const shallow shallowRef({ nested: { prop: Hello Vue 3! }
});
// 修改 shallowRef 的顶层属性即引用变化这将触发视图更新
shallow.value { newNested: { prop: New value! }
};
// 尝试修改 shallowRef 的嵌套属性内部对象的变化这不会触发视图更新
shallow.value.nested.prop This change will not trigger a view update.;triggerRef()
强制触发依赖于一个浅层 ref 的副作用这通常在对浅引用的内部值进行深度变更后使用。如果你确实在某个地方看到了 triggerRef() 这样的函数那么它可能是某个库或应用程序中定义的自定义函数而不是 Vue 3 官方 API 的一部分。
const shallow shallowRef({greet: Hello, world
})// 触发该副作用第一次应该会打印 Hello, world
watchEffect(() {console.log(shallow.value.greet)
})// 这次变更不应触发副作用因为这个 ref 是浅层的
shallow.value.greet Hello, universe// 打印 Hello, universe
triggerRef(shallow)customRef()
customRef 是一个高阶函数它允许你创建一个自定义的 ref以精细地控制 ref 的 get 和 set 行为。当你需要自定义响应式引用的行为时customRef 是非常有用的。customRef 接收一个工厂函数作为参数该工厂函数返回一个对象该对象必须包含 get 和 set 方法。get 方法返回引用的值而 set 方法接收新的值并更新引用。
import { customRef, ref } from vue; function customRefWithValidation(value, validator) { // 使用内置的 ref 创建一个响应式引用 const innerRef ref(value); // 返回一个自定义的 ref 对象 return customRef((track, trigger) { // get 方法返回内部 ref 的值 return { get() { track(); // 通知 Vue 这个 ref 正在被读取 return innerRef.value; }, set(newValue) { // 可以在这里添加自定义逻辑比如验证 if (validator(newValue)) { innerRef.value newValue; trigger(); // 通知 Vue 这个 ref 的值已经改变 } else { console.warn(Invalid value!); } } }; });
} // 使用自定义的 ref
const validatedRef customRefWithValidation(0, (value) typeof value number value 0); // 设置值
validatedRef.value 5; // 成功
validatedRef.value -1; // 失败并在控制台中打印警告shallowReactive()
创建一个浅层的响应式对象。与 reactive 不同shallowReactive 只会对对象的顶层属性进行响应式追踪而不会递归地追踪其嵌套对象的属性。不要意外修改嵌套属性由于 shallowReactive 不会追踪嵌套对象的属性变化因此如果你尝试修改嵌套对象的属性并期望视图更新你可能会遇到意外的行为。与 reactive 的对比与 reactive 不同shallowReactive 是浅层的只追踪顶层属性的变化。如果你需要追踪嵌套对象的属性变化请使用 reactive。与其他工具函数的结合使用你可以将 shallowReactive 与其他 Vue 3 的响应式工具函数如 watch、computed 等结合使用以实现更复杂的响应式逻辑。
import { shallowReactive } from vue; const state shallowReactive({ nested: { prop: Hello Vue 3! }, shallowProp: Shallow prop
}); // 修改顶层属性将触发视图更新
state.shallowProp New shallow prop value; // 修改嵌套对象的属性不会触发视图更新
state.nested.prop New nested prop value; // 这个变化不会被追踪shallowReadonly()
创建一个浅层的只读响应式对象。与 readonly 函数类似shallowReadonly 会创建一个响应式对象的代理但不同之处在于 shallowReadonly 只会将对象的顶层属性标记为只读而不会递归地将对象的嵌套属性也标记为只读。不要意外修改嵌套属性虽然 shallowReadonly 不会阻止你修改嵌套对象的属性但这样做并不会触发 Vue 的响应式系统因此不会触发相关的依赖更新。与 readonly 的对比与 readonly 不同shallowReadonly 是浅层的只会将对象的顶层属性标记为只读。如果你需要递归地将对象的所有属性包括嵌套属性都标记为只读请使用 readonly。与其他工具函数的结合使用你可以将 shallowReadonly 与其他 Vue 3 的响应式工具函数如 computed、watch 等结合使用以实现更复杂的响应式逻辑。但请记住由于 shallowReadonly 是浅层的它不会追踪嵌套属性的变化。
import { shallowReadonly } from vue; const original { nested: { prop: Hello Vue 3! }, shallowProp: Shallow prop
}; const state shallowReadonly(original); // 读取顶层属性
console.log(state.shallowProp); // Shallow prop // 读取嵌套对象的属性
console.log(state.nested.prop); // Hello Vue 3! // 尝试修改顶层属性会抛出错误
// state.shallowProp New shallow prop value; // TypeError: Cannot assign to read only property shallowProp of object // 尝试修改嵌套对象的属性这将成功但Vue不会追踪这个变化
state.nested.prop New nested prop value; // 不会抛出错误但Vue不会追踪这个变化toRaw()
用于获取一个响应式对象的原始对象。这意味着你可以通过 toRaw 函数绕过 Vue 的响应式系统直接访问原始的非代理对象。这在某些需要直接操作原始对象的场景下可能会很有用。不要意外修改原始对象虽然 toRaw 允许你直接访问和修改原始对象但这可能会导致与 Vue 的响应式系统不一致的情况。请确保你了解这样做的后果并在必要时采取适当的措施来同步状态。与 Vue 的响应式系统分离通过 toRaw 获取的原始对象与 Vue 的响应式系统完全分离。这意味着对原始对象的任何修改都不会触发 Vue 的依赖更新或视图渲染。谨慎使用由于 toRaw 可以绕过 Vue 的响应式系统因此在使用时需要格外小心。请确保你了解你的代码和 Vue 的响应式系统的工作原理并谨慎地决定何时使用 toRaw。
import { reactive, toRaw } from vue; const original { count: 0
}; const state reactive(original); // 通过响应式对象修改值
state.count 1; // 获取原始对象
const raw toRaw(state); // 原始对象和响应式对象不是同一个对象
console.log(state raw); // false // 原始对象和响应式对象的内容是相同的
console.log(state.count raw.count); // true // 直接修改原始对象响应式系统不会追踪这个变化
raw.count 2; // 响应式对象的内容没有被改变
console.log(state.count); // 1markRaw()
用于将一个对象标记为非响应式的从而确保它不会被 Vue 的响应式系统转换为代理对象。这在某些情况下可能是有用的特别是当你有一个不应该被 Vue 追踪其属性变化的对象时。不要意外修改非响应式对象虽然 markRaw 允许你创建一个非响应式的对象但这并不意味着你可以随意修改它而不用担心任何副作用。如果你正在与组件或其他 Vue 的功能交互并且错误地修改了一个非响应式对象可能会导致不一致的行为或难以调试的问题。谨慎使用由于 markRaw 会绕过 Vue 的响应式系统因此在使用时需要格外小心。请确保你了解你的代码和 Vue 的响应式系统的工作原理并谨慎地决定何时使用 markRaw。不与其他响应式功能结合使用一旦一个对象被 markRaw 标记为非响应式你就不应该再使用 Vue 的其他响应式功能如 reactive、ref、computed 等来尝试使其变得响应式。这样做可能会导致不可预测的行为。
import { reactive, markRaw } from vue; // 创建一个普通的对象
const rawObject { value: I am raw!
}; // 使用 markRaw 标记该对象为非响应式
const nonReactiveObject markRaw(rawObject); // 尝试使用 reactive 包裹它但 Vue 会识别到它已经被标记为非响应式
const reactiveWrapper reactive(nonReactiveObject); // reactiveWrapper 实际上与 nonReactiveObject 是同一个对象没有被转换为代理
console.log(reactiveWrapper nonReactiveObject); // true // 修改 rawObject 的属性Vue 不会追踪这个变化
rawObject.value I am still raw!; // 因为 reactiveWrapper 是 rawObject 的引用所以它的值也会变化但 Vue 并没有追踪这个变化
console.log(reactiveWrapper.value); // I am still raw!effectScope()
effectScope 是一个相对高级的工具函数它允许你创建一个独立的作用域scope来管理副作用effects。副作用通常指的是那些依赖于响应式数据变化并执行相应操作的函数例如计算属性、侦听器watchers或渲染函数。谨慎使用effectScope 是一个相对高级的工具通常用于处理复杂的响应式逻辑。在大多数情况下使用 Vue 提供的 reactive、ref、computed 和 watch 等 API 就足够了。资源管理当使用 onScopeDispose 添加清理逻辑时请确保正确管理资源以避免内存泄漏或其他问题。副作用的触发在 effectScope 内的副作用仍然遵循 Vue 的响应式系统规则。只有当它们依赖的响应式数据发生变化时它们才会被触发执行。性能考虑创建过多的作用域或副作用可能会对性能产生影响。因此请确保在使用 effectScope 时考虑性能因素并尽量保持作用域和副作用的数量在可控范围内。
import { reactive, effectScope, effect, onScopeDispose } from vue; // 创建一个响应式对象
const state reactive({ count: 0 }); // 创建一个新的 effectScope
const scope effectScope(); // 在该作用域内创建一个 effect
scope.run(() { effect(() { console.log(count changed:, state.count); }); // 当作用域被销毁时执行一些清理逻辑 onScopeDispose(() { console.log(Scope disposed!); });
}); // 触发 state.count 的变化
state.count; // 输出 count changed: 1 // 你可以稍后手动停止并销毁作用域及其内部的 effects
scope.stop(); // 销毁作用域输出 Scope disposed! // 再次触发 state.count 的变化但不会有任何输出
// 因为作用域已经被销毁了
state.count;getCurrentScope()
getCurrentScope 是一个与 effectScope 相关的工具函数但它并不是 Vue 官方 API 的一部分。在大多数情况下你不需要直接访问当前的作用域。Vue 的响应式系统会自动管理作用域的创建、销毁和其中的副作用。但是如果你确实需要这样的功能可能是为了调试或高级用例你可以考虑使用 Vue 的内部 API 或自己实现类似的逻辑。如果你确实需要类似 getCurrentScope 的功能你可能需要考虑以下替代方案 使用自定义标记在你的代码中你可以为每个 effectScope 创建一个唯一的标识符并在创建作用域时将其存储在某个全局或局部的可访问位置。然后你可以通过该标识符来获取相应的作用域。 使用外部库或插件如果你发现自己经常需要这样的功能你可以考虑使用第三方库或插件来扩展 Vue 的功能。这些库或插件可能已经实现了类似 getCurrentScope 的功能并且经过了广泛的测试和验证。 重新设计你的代码在大多数情况下你可能不需要直接访问当前的作用域。相反你可以重新设计你的代码使其更加模块化和可维护。例如你可以将相关的副作用组织在同一个组件或模块中并使用Vue 的响应式系统来自动管理它们。 onScopeDispose()
onScopeDispose 并不是一个直接暴露给用户的 API但它是一个在内部使用的重要概念特别是在与 effectScope 一起使用时。onScopeDispose 主要用于注册当特定作用域scope被停止或销毁时应当执行的回调函数。当你在 effectScope 的上下文中创建副作用如使用 effect 或 watchEffect时你可以使用 onScopeDispose 来注册一个清理函数这个函数会在该作用域被停止或销毁时执行。
import { reactive, effectScope, effect } from vue; // 创建一个响应式对象
const state reactive({ count: 0 }); // 创建一个新的 effectScope
const scope effectScope(); // 在该作用域内创建一个 effect 并注册一个清理函数
scope.run(() { // 创建一个 effect const cleanupEffect effect(() { console.log(count changed:, state.count); }); // 注册一个当作用域被销毁时执行的清理函数 // 注意这里不是直接使用 onScopeDispose而是模拟其功能 const onDispose () { console.log(Scope disposed! Cleaning up...); // 在这里执行清理逻辑比如取消订阅、移除事件监听器等 // cleanupEffect.stop(); // 如果需要的话可以停止这个特定的 effect }; // 假设我们有一个机制来在作用域停止时调用 onDispose // ...在 Vue 内部这是自动处理的 // 模拟作用域停止的事件在 Vue 中你不需要手动这样做 // scope.stop(); // 这会触发上面定义的 onDispose 函数
}); // 触发 state.count 的变化
state.count; // 输出 count changed: 1 // 假设在某个时候作用域被停止了在 Vue 中可能是组件卸载时
// scope.stop(); // 如果这行代码被取消注释会输出 Scope disposed! Cleaning up...