您的位置:首页 > 健康 > 养生 > 重庆装修协会_河南建筑信息一体化平台_seo软文推广工具_推广赚钱的软件

重庆装修协会_河南建筑信息一体化平台_seo软文推广工具_推广赚钱的软件

2025/3/14 22:06:53 来源:https://blog.csdn.net/youyoufenglai/article/details/146225384  浏览:    关键词:重庆装修协会_河南建筑信息一体化平台_seo软文推广工具_推广赚钱的软件
重庆装修协会_河南建筑信息一体化平台_seo软文推广工具_推广赚钱的软件

尚硅谷Vue2.0+Vue3.0全套教程丨vuejs从入门到精通

本篇内容对应课程第147-149节

课程 P147节 《vue3响应式原理_Reflect》笔记

想要读取对象上的属性,只需要obj.a 的形式就可以读取到。还有另外一种方式,是使用 window上的Reflect来实现。

读取对象属性时:

Reflect.get(obj, 'a')

在这里插入图片描述

设置对象属性时:

Reflect.set(obj, 'a', value)

在这里插入图片描述

删除对象属性时:

Reflect.deleteProperty(obj, 'a')

在这里插入图片描述

ECMA正在尝试将Object对象上的许多属性与方法移植到 Reflect 上面:

在这里插入图片描述

例如,使用 Object.defineProperty 给对象obj 追加一个属性c ,不小心写了两遍,对 c 进行了重复追加定义的情况下,这段代码会直接报错,且由于js单线程报错即会阻塞后续代码正常执行:

在这里插入图片描述

在这里插入图片描述

如果改用 Reflect.defineProperty ,同样给对象obj追加一个属性c,同样不小心写了两遍,进行了重复定义,此时,控制台不仅没有报错,后续代码可以继续运行,且属性c已经被成功定义,只是生效的是第一次定义的代码:

在这里插入图片描述

在这里插入图片描述

此时,给人的感觉像是,用 Object.defineProperty 写的代码产生报错时,会直观地在控制台看到错误,但用 Reflect.defineProperty 写的代码产生错误时,不易发现错误。事实上 Reflect.defineProperty 是有返回值的,如果设置成功返回 true,设置失败则返回 false:

在这里插入图片描述

在这里插入图片描述

用 Object.defineProperty ,如果想让代码报错时不影响后续代码继续运行,只能使用 try catch来捕获错误:

在这里插入图片描述

在这里插入图片描述

但使用 Reflect.defineProperty 则不需要 try catch捕获错误,直接判断其返回值就可以知道操作是否成功。

在这里插入图片描述

在这里插入图片描述

Object.defineProperty 和 Reflect.defineProperty 的以上对比发现,在封装框架时,Reflect.defineProperty 在代码健壮性方面具有很大的优势,假如使用 Object.defineProperty,则可能需要使用大量 try catch来进行错误捕获,避免程序出错导致整个代码挂掉。

了解了 Reflect,回到 vue3响应式实现原理,在Proxy代理中对属性的操作,都是通过 Reflect 完成的:

在这里插入图片描述

总结vue3的响应式:

在这里插入图片描述

课程 P148节 《reactive对比ref》笔记

在这里插入图片描述

课程 P149节 《setup的两个注意点》笔记

setup的两个注意点:
在这里插入图片描述

回顾vue2中的两个知识点:$attrs 与 $slots

$attrs:

父组件向子组件传递prop:
在这里插入图片描述

子组件中通过 props 声明接收:

在这里插入图片描述

mounted中打印组件实例this,发现父组件通过props传递过来的值被放到了组件实例上面:

在这里插入图片描述

如果注释掉子组件中的 props 声明接收,也就是父组件通过prop的形式向子组件传递了数据,但子组件中没有通过props声明接收这些数据,再次观察子组件的实例对象this,发现组件实例上没有了父组件传递过来的数据,但组件实例上的 $attrs 上却有了这两个数据:

在这里插入图片描述

在这里插入图片描述

打开注释,让子组件中声明接收父组件props传递的数据,会发现子组件实例上有了这两个数据,同时 $attrs 上不再有这两个数据:

在这里插入图片描述

在这里插入图片描述

在子组件的props声明接收里,只接收 msg 这一个数据,发现声明接收了的 msg 被放在了子组件实例上面,而未被声明接收的 school 则被放到了 $attrs 上。就好像 $attrs 在捡漏一样,被声明接收的props(父组件通过props向子组件传递的数据)会被放到组件实例上,而没被声明接收的props则会被放到 $attrs 上:

在这里插入图片描述

在这里插入图片描述

$slots 插槽:

vue2中的插槽,简单说就是:子组件中留个“坑位”,等父组件来填充。

子组件中没有留“坑位”,观察子组件实例对象,上面有一个$slots属性:
在这里插入图片描述

在这里插入图片描述

父组件中,在引用子组件时向其内部传递一些内容,再次观察子组件实例对象上的 s l o t s ,会发现这个 slots ,会发现这个 slots,会发现这个slots对象上多了 default 属性,里面就是父组件传递的标签内容,被处理成了对应的 vnode,即虚拟dom:

在这里插入图片描述

在这里插入图片描述

在子组件中放入“坑位”,发现页面上渲染出了父组件传递的插槽内容,同时 $slots 上仍然有这个default :

在这里插入图片描述

在这里插入图片描述

父组件中传递两个标签内容时,子组件实例对象上的 $slots 的 default 下也会有两个:

在这里插入图片描述

在这里插入图片描述

父组件中传递两个具名插槽内容时,子组件实例对象上也能观察到这两个属性,属性名正是插槽名:

在这里插入图片描述

在这里插入图片描述

vue3 中的setup

补充完vue2中的 $attrs 与 $slots 知识点,回过头来继续看 vue3 中的setup:

setup执行的时机:在 beforeCreate 之前执行一次,this是undefined:

在这里插入图片描述

在这里插入图片描述

vue3的项目中,父组件给子组件传递两个props属性:msg和school

在这里插入图片描述

打印setup的第一个参数props,发现这个对象上并没有数据,同时控制台出现警告:

在这里插入图片描述

在这里插入图片描述

这是因为在子组件中没有声明接收这两个props参数,增加红框一行代码:

在这里插入图片描述

再次查看控制台,发现打印的setup的第一个参数props对象上有了 msg 与school 两个属性,且它是一个Proxy对象,是响应式的:

在这里插入图片描述

如果子组件中用 props 声明接收时,多声明一个未传递的数据 a ,会发现 a 是undefined:

在这里插入图片描述

在这里插入图片描述

打印setup的第二个参数 context,发现它是一个普通对象,上面主要有 attrs、slots、emit、expose 四个属性:

在这里插入图片描述

在这里插入图片描述

打印 context.attrs,发现这个Proxy对象上没有有用属性:

在这里插入图片描述

在这里插入图片描述

这是因为父组件通过props传递给子组件的数据,都通过 props 声明接收了。将声明接收的代码注释掉,再次观察 context.attrs,发现此时这里面有了 msg 与 school 这两个数据,同时由于没有声明接收,控制台出现了警告:

在这里插入图片描述

在这里插入图片描述

如果只声明接收一个 msg ,会发现:声明接收了的这个msg被放在了 setup 的第一个参数 props 中,未被声明接收的 school 被放在了 setup 的第二个参数 context.attrs 上。由此可见:context.attrs 就相当于vue2中的 $attrs :

在这里插入图片描述

在这里插入图片描述

测试自定义事件:父组件中给子组件绑定一个自定义的 hello 事件(如果给子组件绑定原生事件,如click,则需要 .native修饰符。即 @click.native=“someEvent” ):

在这里插入图片描述

子组件中通过context.emit触发这个事件:

在这里插入图片描述

会发现控制台出现警告,提示需要使用 emits 选项:

在这里插入图片描述

但此时事件已经奏效了:

在这里插入图片描述

增加 emits 选项,用一个数组的形式注册这个 hello 事件:

在这里插入图片描述

父组件中向子组件内部传递一些内容:

在这里插入图片描述

打印 setup 的第二个参数context中的slots :

在这里插入图片描述

发现其是一个Proxy对象,且里面有一个default属性:

在这里插入图片描述

父组件中用 slot=“slotName” 的形式给子组件传递具名插槽内容:

在这里插入图片描述

观察 context.slots ,仍然是传递匿名插槽时的default :

在这里插入图片描述

父组件中改用 v-slot:slotName 的形式给子组件传递具名插槽内容:

在这里插入图片描述

再次观察 context.slots ,这次就变成了传递的插槽的名字 :

在这里插入图片描述

父组件中用 v-slot:slotName 的形式给子组件传递两个具名插槽内容:qwe 和 asd

在这里插入图片描述

context.slots 中就可以打印出 qwe 和 asd :

在这里插入图片描述

在vue3里,使用具名插槽时尽量使用 v-slot:slotName 的形式。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com