Vue 2024 年 4 月 9 日
Vue3-toRefs&toRef,toRaw&unref,expose&emit
Vue3-toRefs&toRef,toRaw&unref,expose&emit
Vue3-toRefs&toRef,toRaw&unref,expose&emit
toRefs&toRef
toRefs用于结构整个reactive和props的属性。因为toRefs是作用于响应式对象(reactive)和props。
为什么props也算呢,因为可以在父组件用reactive或者ref来创建相应式对象。但是props本身就是响应式。因为父组件修改了,子组件会响应。
解构Ref
const personal = ref({
name: "mafeifei",
age: 18,
sex: "man"
});
const { name } = toRefs(personal.value);
console.log("name", name); //ObjectRefImpl {_object: Proxy(Object), _key: 'name', _defaultValue: undefined, __v_isRef: true}
console.log("name.value", name.value); // mafeifei
console.log("name isRef", isRef(name)); // true
toRef用于只需要相应式对象里的一个属性。
const age = toRef(personal.value, "age");
console.log("age", age); // ObjectRefImpl {_object: Proxy(Object), _key: 'age', _defaultValue: undefined, __v_isRef: true}
console.log("age.value", age.value); // 18
console.log("age isRef", isRef(age)); // true
当然也可以这样,创建相应式的
const age = computed(() => personal.value.age)
如果子组件需要一个基于props的可修改的相应式引用,那么可以用computed的
get
和set
来共同实现。toRaw&unref
toRaw并不是深拷贝,而会修改引用数据类型的值。
toRaw会返回数据的原始数据类型。
const raw = toRaw(personal.value);
console.log("personal.value", personal.value); // Proxy(Object) {name: 'mafeifei', age: 18, sex: 'man'}
console.log("raw", raw); // {name: 'mafeifei', age: 18, sex: 'man'}
raw.age = 999;
console.log("raw end", raw); // {name: 'mafeifei', age: 999, sex: 'man'}
console.log("personal.value end", personal.value); // Proxy(Object) {name: 'mafeifei', age: 999, sex: 'man'}
unref
unref用于显示ref原始值。用于迫切想知道ref原始值的情况。
如果参数是ref,则返回内部值,否则返回参数本身。
val = isRef(val) ? val.value : val
const article = ref("v2qun");
console.log("article", article); //RefImpl {__v_isShallow: false, dep: undefined, __v_isRef: true, _rawValue: 'v2qun', _value: 'v2qun'}
console.log("unref(article)", unref(article)); // v2qun
const un = unref(personal.value);
console.log("un", un); //Proxy(Object) {name: 'mafeifei', age: 18, sex: 'man'}
console.log("unref(personal.value)", unref(personal.value));
这里un打印失效,没有打印出预期值。因为unref,是从相应式引用里获取内部值,而personal是一个相应式对象。
如果unref传入的是一个相应式对象,那么就会返回这个相应式对象。
expose&emit
expose暴露给父组件该组件的属性和方法
childRef.value.open() // 方法
childRef.value.list // 属性
emit用于发布订阅事件,子组件处理好某些事件之后,主动给父组件发消息,告诉子组件有新的派发。
而expose是直接调用子组件的方法和属性,并没有订阅关系。
emit可以结合.sync从子组件修改父组件传入进来的props,来达成双向数据绑定
在vue2里有.sync,但是vue3里已经取消了.sync。
子组件通过
update:value
来直接把emit的值更新了,然后父组件通过.sync修饰
符来完成数据双向绑定。
.sync
会自动将子组件更新的值传递给父组件,并更新父组件相应prop的值。
现在这个写法是不能省略v-model:count,因为默认有个props就modelValue,如果是用这个名称的话,在父组件就可以省略。
可以定义是默认的v-model。
如果想绑定多个v-model,那么除了默认的modelValue之外,其他的正常写就行
defineModel()
Vue3.4+
开始,推荐的实现方式是defineModel()
。
defineModel其实是一个语法糖
toValue & unref
toValue可以接受
- 一个普通值
- 一个Ref对象
- 一个有返回值的函数
如果是一个函数,则会执行一次这个函数,并使用其返回值。
unref
- 处理Ref对象
- 如果不是Ref类型,则返回传入值
尽可能用toValue替代unref,这不会有任何的问题。
版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)
作者: 保安 发表日期:2024 年 4 月 9 日