在封装el-table组件时遇到这样一个场景,关于插槽透传。props透传可以通过provide/inject,插槽透传如何实现?孙组件如何使用父组件传递给子组件的插槽?曾孙组件又如何使用父组件传递给子组件的插槽?
针对场景分析,有这样的一个组件链:父组件TestStandardTable引用了子组件StandardTable且传递了多个具名插槽(这些插槽用于自定义列的渲染),而子组件StandardTable又引用了组件RenderTableColumn(渲染列),即组件链:。据此,组件RenderTableColumn如何使用组件StandardTable接收的插槽呢?
父子组件之间的通信,父组件可通过props向子组件传递数据,也支持通过插槽内容向子组件传入自定义模板内容。
关于插槽的官方文档。
插槽包含两部分内容:(1)插槽内容,由父组件定义;(2)插槽出口,由子组件通过 实现。
- 插槽内容:由包含v-slot指令的template标签包裹;
- v-slot指定格式:,例如或解构形式;
- v-slot指令简写形式为# :即可简写为;
- 插槽出口:通过slot标签输出
- 具名插槽的输出需要指定name(默认为default,默认插槽可省略name);
- 传递数据:可使用v-bind指令或其简写形式;
- 获取父组件传入的插槽对象:
- 组合式 API:
- 钩子:
二次封装el-table组件为standard-table,接收tableData,其类型tableDataProps如下:
针对列el-table-columns,做了一些定制化配置:
其代码结构如下
调用组件StandardTable,并提供自定义列模板
渲染自定义列,因为支持多级表头,故将自定义列的具体逻辑抽离出来即组件RenderTableColumn。
运行结果:
发现我们在TestStandardTable.vue中定义的两个自定义列模板没有生效,为什么呢?
由于在TestStandardTable.vue向子组件StandardTable传入了自定义列模板(提供了两个插槽)以自定义展示列。按需求,这两个插槽是在el-table-columns接收展示的,但是插槽是由父组件流向子组件的,如何实现父组件给子组件的插槽流向孙组件呢即如何实现插槽透传?
这里笔者想到的解决方案是:借助父子组件插槽流动特性(父组件传递,子组件接收),父传子,子传孙... ,修改上述代码如下。
再次运行:
OK,搞定!现在,需求是实现了,但是是通过父子、子孙等的传递,这样有个弊端:如果插槽内容的逻辑复杂,这种击鼓传花的方式会带来过多的损耗。
如果你有更好的方式,请留言~
掘友提供了一个新思路,只在使用插槽的时候再去往上找以避免层层传递带来的损耗,根据组件实例上的$parent属性,向上找指定名称的插槽,露水晰123也在尝试这种方式,如何访问parent属性呢?哈哈,使用渲染函数。这里涉及一些预备知识,Vue3渲染机制、渲染函数、渲染函数语法和声明渲染函数。
首先做准备工作,了解Vue3的渲染机制:将语法糖template内部代码编译成渲染函数,渲染函数会返回一个生成虚拟dom树的函数,然后根据虚拟dom树渲染成真实的dom树。如果组件的编程性更强,就可直接使用渲染函数。声明渲染方式的方式也有两种:(1)组合式API的setup()返回渲染函数;(2)选项式API的render()返回渲染函数。
新建文件RenderColumnList.ts,关键代码如下:
在render函数中,使用方法renderColumnList来生成列,为什么不直接在render里生成呢? 因为要支持多级表头的设置,多级表头就意味着递归调用自身,如果我们在render里直接渲染列,递归调用自身会报错:。因function的声明会被提升到全局,故可将渲染列这块代码拉出去,做函数调用。
call、apply和bind的异同之处
相同点:
- 强制更改function的this的指向;
- 不能更改ES6箭头函数的this,因为箭头函数的this是上级父作用域的,其本身没有this;
不同点:
- call与apply的传参方式不同,call是单个单个传参(例如:call(this, parms1, parms2, parms3)),apply是以数组的形式传参(apply(this, [parms1, parms2, parms3]));
- call与bind的传参方式相同,但是fn.call和fn.apply中的fn都是立即执行,而fn.bind会返回接受了传参的fn,这一点可以用在柯里化;
若有异议,请留言议之~
到此这篇vue插槽多级传递(vue插槽怎么传值)的文章就介绍到这了,更多相关内容请继续浏览下面的相关 推荐文章,希望大家都能在编程的领域有一番成就!版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/qdvuejs/44311.html