您现在的位置是:亿华云 > 域名
Vue.js设计与实现之十-原始类型的响应式代理
亿华云2025-10-09 03:56:05【域名】7人已围观
简介1、写在前面在javascript中原始值包括:Boolean、String、Number、Null、Undefined、Symbol和BigInt等类型,原始值是按值传递而非按引用传递。前面,知道P
在javascript中原始值包括:Boolean、原始应式String、类型Number、响代理Null、计实Undefined、原始应式Symbol和BigInt等类型,类型原始值是响代理按值传递而非按引用传递。前面,计实知道Proxy可以用于实现对象类型的原始应式响应式代理,但是类型却不能实现原始值的代理,要实现原始值变成响应式数据,响代理就需要做些处理。计实
2、原始应式refProxy的类型代理目标必须是对象类型,那么是否可以将原始值类型包装成对象类型,这样不就可以实现代理了吗?
// let name = "pingping"
const data = {
value: "pingping"
}
const state = reactive(data);
name.value = "onechuan";想法是很好,但是你想过没有这样做带来的问题:
用户创建一个原始值的响应式数据,就必须创建一个包裹的对象。而包裹对象又是由用户自定义,那么就存在命名和使用不规范情况。源码库解决方法很简单,你不是担心用户自定义的对象不规范不可控吗,那么就在源码内部定义不就行了。
function ref(val){
const wrapper = {
value: val
}
return reactive(wrapper);
}简单试用下:
const refVal = ref("pingping");
effect(()=>{
console.log(refVal.value);
});
refVal.value = "onechuan";但是,在使用过程中又有个问题:你又是如何保证refVal是原始值的包裹对象,还是一个非原始值的响应式数据呢?
const refVal = ref("pingping");
const refVal2 = reactive({ value:"pingping"});其实,ref和reactive生成的响应式数据实现方式都是一样的,对数据来源区分是不是ref是为了后续脱ref,脱出响应式能力恢复原始数据。
function ref(val){
const wrapper = {
value: val
}
Object.defineProperty(wrapper,"__v_isRef",{
value: true
})
return reactive(wrapper);
}在上面代码中,使用Object.defineProperty给包裹对象wrapper定义一个不可枚举和不可写的属性"__v_isRef",使其值为true用于区分当前对象是ref而非普通对象。
简而言之:ref其实是对一个对象和reactive的二次封装。
3、响应丢失的云服务器提供商问题我们知道,ref可以用于实现原始值的响应式代理,但其实还可以用于解决响应式丢失的问题。所谓响应式丢失,就是在使用reactive生成的响应式对象数据,使用展开运算符(...)会丢失响应式,就成了一个普通对象数据。此时,修改修改对象的属性值,不会触发更新和模板渲染。
const obj = reactive({ name:"pingping"});
const newObj = { ...obj};
effect(()=>{
console.log(newObj.name);
});
obj.nmae = "onechuan";在上面代码中,副作用函数中访问的只是普通对象newObj的属性name的值,它并不具有响应式能力,在对其属性值进行修改时,不会触发副作用函数重新执行。
那么,应该如何解决响应式丢失的问题呢?
其实就是能解决在副作用函数中,通过获取普通对象newObj的属性值,也会触发更新,与副作用函数建立联系。
通过在普通对象newObj中设置与obj对象同名的亿华云计算属性,将每个属性值都设置成对象,通过对象的get取值方法实现obj对象的属性值读取,这样就巧妙地将newObj的属性值与副作用函数建立了联系。
const obj = reactive({ name:"pingping"});
const newObj = { ...obj};
effect(()=>{
console.log(newObj.name);
});
obj.nmae = "onechuan";但是,如果obj对象中有很多属性,那是不是就需要在newObj建立许多同名的对象?那么,就可以进行抽取封装函数:
function toRef(obj, key){
const wrapper = {
get value(){
return obj[key];
},
set value(val){
obj[key] = val
}
}
Object.defineProperty(wrapper,"__v_isRef",{
value: true
})
return wrapper;
}在使用过程中,简简单单:
const obj = reactive({ name:"pingping"});
const name = toRef(obj, "name");
name.value = "onechuan";前面只是对少数对象的属性值转成响应式数据可以这样处理,但是当我们需要批量处理数据,应该如何处理呢?
很简单,对对象属性进行遍历不就得了。
function toRefs(obj){
const res = { };
for(const key in obj){
res[key] = toRef(obj,key);
}
return res;
}这样,响应式丢失问题就被解决了,方法就是将响应式数据转换成类似ref结构的数据,通过toRef或toRefs转换后得到的数据就是真正的ref数据。
4、自动脱ref使用toRefs用于解决响应丢失问题,就是对对象的属性进行遍历转为ref,这样就会带来新问题,就是去访问数据的第一层属性,必须通过.value才能访问。这样无疑会增加使用者的心智负担,用户肯定愿意直接对象.属性,而非通过对象.属性.value来使用属性值。
const obj = reactive({
name:"pingping",
age:18
});
const newObj = {
...toRefs(obj)
};
newObj.name.value//pingping
newObj.age.value//18现在我们就需要让其自动脱ref,这样在进行对象属性的访问时,读取到属性是个ref则放回ref.value,否则直接返回属性值。
function proxyRefs(target){
return new Proxy(target,{
get(target, key, receiver){
const value = Reflect.get(target, key, receiver);
return value.__v_isRef ? value.value : value;
}
})
}
const newObj = proxyRefs(...toRefs(obj));在上面代码中,通过定义一个proxyRefs函数接收一个对象参数,返回该对象的代理对象。而代理对象的作用是通过get操作,在读取到对象的属性是个ref值时,直接返回该ref.value值,否则直接返回属性值,这样就实现了自动脱ref。
其实,在模板中使用ref的属性值时,就是通过将组件setup返回的数据传递到proxyRefs函数中进行处理。这样就可以实现,在模板中直接访问属性值,而非属性.value值。
前面有实现自动脱ref的能力,现在就有实现自动穿ref的能力。实现原理,同样的是通过添加对应的set拦截函数。
function proxyRefs(target){
return new Proxy(target,{
get(target, key, receiver){
const value = Reflect.get(target, key, receiver);
return value.__v_isRef ? value.value : value;
},
set(target, key, newValue, receiver){
const value = target[key];
if(value.__v_isRef){
value.value = newValue;
return true
}
return Reflect.set(target, key, newValue, receiver);
}
})
}5、写在最后在本文中主要介绍了如何将原始值转为响应式数据,如何解决响应式丢失的问题,如何减少用户心智负担实现自动脱ref的能力等。ref本质就是一个包裹对象,通过reactive实现对原始值的响应式代理,但是包裹对象自爱本质上又和普通对象没啥区别,对此需要通过设置一个标识符__v_isRef来实现ref数据的区分。
很赞哦!(2)
上一篇: ICANN 规章禁止转移已经被记录或者在60天前内转移的域名。
下一篇: 4、club娱乐
相关文章
- 一下域名,看有没有显示出你所解析的IP,如果有,就说明解析是生效的;如果没有,就说明解析是不生效的。
- 4、选择一个安全的域名注册商进行域名注册
- 2. 不要花大价钱买域名,新手鉴别能力不足,容易投资失误。
- .net 适用于从事Internet相关的网络服务的机构或公司
- 在更换域名后,并不是就万事大吉了,我们需要将旧域名做301重定向到新域名上,转移旧域名的权重到新域名上。
- 为了避免将来给我们的个人站长带来的麻烦,在选择域名后缀时,我们的站长最好省略不稳定的后缀域名,比如n,因为我们不知道策略什么时候会改变,更不用说我们将来是否还能控制这个域名了。因此,如果站长不是企业,或者有选择的话,如果不能选择域名的cn类,最好不要选择它。
- 2016年1月1日:注册价格将降至每年7欧元。
- 3、考虑出售域名
- 四、配置网站,填充内容
- 域名和网址一样吗?域名和网址有什么区别?
热门文章
站长推荐
二、如何选择合适的域名
顶级域名可以增加企业品牌的价值。随着经济的快速发展,域名已不再是企业在网络中的独立地位。顶级域名的服务范围、企业产品、综合形象体现等,对于企业单位来说,顶级域名的重要性不言而喻。
四、一定要仔细阅读细节
换新域名(重新来过)
4、说起来容易
其次,一般域名注册有一个获取密码的按钮,域名注册商点击后会向您发送密码。在得到域名注册商发送的密码后,将其传输到域名服务提供商网站,然后输入密码,此时域名呈现申请状态。提交申请后,原注册人通常会向您发送一封电子邮件,询问您是否同意转让。此时,您只需点击同意转移按钮,域名注册商就可以成功转移。
个人域名转为公司需要什么条件?个人域名转为公司该怎么做?
3、不明先知,根据相关征兆预测可能发生的事件,以便提前做好准备,赶紧注册相关域名。;不差钱域名;buchaqian抢先注册,就是这种敏感类型。预言是最敏感的状态。其次,你应该有眼力。所谓眼力,就是善于从社会上时不时出现的各种热点事件中获取与事件相关的域名资源。眼力的前提是对域名领域的熟悉和丰富的知识。