凉山住房和城乡建设局网站长春微信做网站

当前位置: 首页 > news >正文

凉山住房和城乡建设局网站,长春微信做网站,应用软件开发过程,wordpress修改布局Vue2 中的ref 首先我们回顾一下 Vue2 中的 ref。 ref 被用来给元素或子组件注册引用信息。引用信息将会注册在父组件的 \(refs 对象上。如果在普通的 DOM 元素上使用#xff0c;引用指向的就是 DOM 元素#xff1b;如果用在子组件上#xff0c;引用就指向组件实例#xff1… Vue2 中的ref 首先我们回顾一下 Vue2 中的 ref。 ref 被用来给元素或子组件注册引用信息。引用信息将会注册在父组件的 \)refs 对象上。如果在普通的 DOM 元素上使用引用指向的就是 DOM 元素如果用在子组件上引用就指向组件实例 !– vm.\(refs.p will be the DOM node -- p refphello/p!-- vm.\)refs.child will be the child component instance – child-component refchild/child-component 其实也就是给元素或者是子组件打上标记然后通过在父组件中 通过 this.refs.xxx拿到这个 DOM元素或者是组件实例进而操作 DOM 或者访问组件实例。 在官方文档上声明ref是一个特殊的属性$refs是一个对象持有注册过 ref attribute 的所有 DOM 元素和组件实例。 Vue3 setup 中直接定义的数据为什么改变之后视图不同步 如果我按照上一节 setup 中的模式 直接创建变量且赋基础值然后试图改变变量的值我们看看会发生什么 templatep{{ name }}/pbutton clickchangeName改变名称/button /templatescript export default {name: App,setup() {let name al;function changeName() {name 汤圆仔}return {changeName,name,};}, }; /script但是在我点击按钮之后我发现页面上的名称并没有发生改变。造成的原因可能有两个 第一个可能是数据改变了但是视图没更新。第二种则是数据本身就没改变所以不更新视图。 验证改变数据之后直接打印修改后的变量 从这里可以看到我们修改的数据其实时发生了改变的但是页面上却没有更新这在 Vue2 中是不会存在的因为 Vue2 中定义在 data 中的数据时响应式的所以我们可以得出下面这个结论那就是 直接在 setup 中声明的变量不是响应式的。 为了解决这一个问题Vue3 推出了 ref 函数 用来将 setup 中定义的变量转化为响应式。 Vue3 中的 ref 函数 首先Vue3 中的 ref 是一个函数区别于Vue2 中的ref是一个特殊属性。作用是将数据转化为响应式。在使用时需要引入然后将要转化的数据传入到 ref() 函数中。 templatep{{ name }}/pbutton clickchangeName改变名称/button /templatescript import { ref } from vue export default {name: App,setup() {let name ref(al);function changeName() {name 汤圆仔console.log(name,name);}return {changeName,name,};}, }; /script到了这一步我们再次点击按钮 发现还是同样的结果数据改变了但是视图没刷新。不是说好的 通过 ref() 函数就能将数据转化为响应式的么我这都转化了为啥还是这样 ref() 函数处理基本数据类型 对于上面的 基本数据类型 name我们可以在改变值之前先看看这个 name 变量被 ref() 函数处理成了什么样子。 可以看到 ref()函数将基本类型数据转化为了一个 ref引用对象(RefImpl对象)同时我们展开对象查看内部属性可以发现存在以下属性。 dep对象暂时猜测和Vue2一致用来收集分发依赖的。四个带有_前缀的属性一般也是用来给 Vue底层源码使用的所以这个value一看就是给我们开发者的。 而且我们还可以发现鼠标放到value属性值的省略号上之后提示是通过gettrt 方法获得的值这和Vue2获取响应式数据一致。 然后打开 Prototype 属性可以看到针对于这个基础类型的值的 getter 和 setter方法以及真正的value值。将方法以及初始值放在原型上是利用原型的作用避免外层数据繁杂。然后将真正的value暴露给外层是为了方便开发者使用。 到这里我们就可以大胆的推论得出ref() 函数在处理基础类型的值时通过将其转化为了 RefImpl 引用实例对象后还是通过 getter 和 setter 来实现响应式的。 得到结论之后还不够我们要知道怎么去修改或访问通过ref()函数转化的基础数据啊。 在上面通过  name 汤圆仔 直接修改属性值被证明是已经行不通了的。因为这样修改之后相当于是把这个响应式属性直接变成了一个基础类型的值从而失去了响应式功能。 而看着 RefImpl 引用实例对象中的属性我们能理解并使用的也就只有 value 属性了。所以当我们修改数据的时候通过 name.value 汤圆仔就能在保证响应式的前提下修改数据了。 function changeName() {name.value 汤圆仔console.log(name,name); } 同理在模板中使用数据的时候我们好像也应该通过 插值语法的形式 {{ name.value }} 去使用但是在你真这么做之后你会发现页面渲染其实错误了。 p姓名{{ name.value }}/p这其实是因为Vue3底层设计考虑到了这一问题在模板中使用变量Vue3判断当前为插值语法且使用的是通过 ref() 函数进行转化过后的响应式数据后会自动解包自动读取value值而不需要开发者手动 xxx.value 去获取属性值。所以我们还是像以前一样通过插值语法直接使用该属性即可。 ref() 函数处理引用类型值 上面说的是ref()函数对于基本数据类型的值的处理。但是如果我的数据比较多那我分别调用ref比较麻烦所以 ref() 函数也支持传入对象形式的数据 templatep姓名{{ userInfo.name }}/pp姓名{{ userInfo.age }}/pp姓名{{ userInfo.work }}/pbutton clickchangeName改变名称/button /templatescript import { ref } from vue export default {name: App,setup() {let userInfo ref({name: al,age: 29,work:前端});function changeName() {console.log(userInfo,userInfo);}return {changeName,userInfo,};}, }; /script点击按钮控制台打印出当前通过ref()函数转化后的 userInfo 属性我们能发现返回的还是一个RefImpl引用实例对象而且 value还是通过 getter转化为响应式的。此时我们不点开 value的值按照基本类型的处理方式推测一下此时的value应该是一个对象。 于此同时我们也应该想到一个问题那就是在Vue2 中实现了对象的深层响应那么在Vue3中不可能丢掉这个功能所以我们可以推断此时 ref()函数对于引用类型的值也做了深层响应式也应该是针对于引用类型中每个属性都应该返回一个refImpl引用对象实例以此来保障数据完全深层响应。 那么我们可以推断出当我们在改变unseInfo内部 name 属性的时候我们也应该通过  name.value  去修改也就是说当我们需要修改对象内部属性时我们需要这样做先通过 userInfo.value 拿到转化为响应式的 userInfo 对象然后修改name时也需要拿到 name 的value去修改 function changeName() {console.log(userInfo);userInfo.value.name.value 汤圆仔 } 但是这时候我们发现页面报错了且提示信息为不能在一个字符串 al 中读取 value 属性。也就是说 userInfo.value.name 之后是取不到 value属性的。这么搞就有点混乱了啊那我到底是加还是不加呢 为了解决这个问题我们看看 userInfo.value 到底返回的是个啥玩意。点开 value属性之后我们发现 value 属性并不是一个 refImpl引用实例对象而是一个 Proxy 代理对象。而且这个代理对象上的每个属性只有键值对对应并没有所谓的 value 属性所以这个时候我们就需要明白一个问题Vue3 对于基础类型和引用类型转化为响应式用的是不同的底层逻辑。 针对于基本类型的数据Vue3走的还是和Vue2一样的 defineProperty 的getter、setter的数据劫持的方式实现的响应式。 而针对于引用类型的数据Vue3 走的则是通过Proxy代理的方式实现的响应式( 下一节仔细讲讲怎么通过Proxy实现引用类型的响应式转化 ) 搞明白了上面这个value属性值的问题当我们需要改变引用类型中的数据时我们就可以这样做 function changeName() {userInfo.value.name 汤圆仔 } 总结 ref的作用定义一个响应式的数据 ref的语法let xxx ref(initvalue) 创建一个 包含响应式数据的引用对象在js中操作数据时需要使用 xxx.value 来修改在模板中使用数据时不需要通过 .value来读取因为 Vue底层会自动解包 ref的参数可以是基本类型也可以是引用类型但是对于这两种数据响应式处理是完全不同的两套逻辑 基本类型数据依然是通过 Object.defineProperty() 中的 get 与 set 进行数据劫持完成响应式引用类型数据Vue3 内部求助了一个新函数 – reactive 函数通过ES6自带的 Proxy 方法完成了响应式( 参考下一节 – reactive 函数实现引用类型响应式 )