当前位置:网站首页 > Vue.js开发 > 正文

vue插槽多级传递(vue插槽怎么传值)



在封装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,做了一些定制化配置:

columns.png

其代码结构如下

调用组件StandardTable,并提供自定义列模板

 

渲染自定义列,因为支持多级表头,故将自定义列的具体逻辑抽离出来即组件RenderTableColumn

 
 

运行结果: slot_1.png

发现我们在TestStandardTable.vue中定义的两个自定义列模板没有生效,为什么呢?

由于在TestStandardTable.vue向子组件StandardTable传入了自定义列模板(提供了两个插槽)以自定义展示列。按需求,这两个插槽是在el-table-columns接收展示的,但是插槽是由父组件流向子组件的,如何实现父组件给子组件的插槽流向孙组件呢即如何实现插槽透传

这里笔者想到的解决方案是:借助父子组件插槽流动特性父组件传递,子组件接收),父传子,子传孙... ,修改上述代码如下。

 

再次运行: slot_2.png

OK,搞定!现在,需求是实现了,但是是通过父子、子孙等的传递,这样有个弊端:如果插槽内容的逻辑复杂,这种击鼓传花方式会带来过多的损耗。

如果你有更好的方式,请留言~

 

掘友提供了一个新思路,只在使用插槽的时候再去往上找以避免层层传递带来的损耗,根据组件实例上的$parent属性,向上找指定名称的插槽,露水晰123也在尝试这种方式,如何访问parent属性呢?哈哈,使用渲染函数。这里涉及一些预备知识,Vue3渲染机制、渲染函数、渲染函数语法和声明渲染函数。

首先做准备工作,了解Vue3的渲染机制:将语法糖template内部代码编译成渲染函数,渲染函数会返回一个生成虚拟dom树的函数,然后根据虚拟dom树渲染成真实的dom树。如果组件的编程性更强,就可直接使用渲染函数。声明渲染方式的方式也有两种:(1)组合式API的setup()返回渲染函数;(2)选项式API的render()返回渲染函数。 image.png

新建文件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插槽怎么传值)的文章就介绍到这了,更多相关内容请继续浏览下面的相关 推荐文章,希望大家都能在编程的领域有一番成就!

版权声明


相关文章:

  • vue的安装步骤(安装vue ui)2025-03-13 18:18:10
  • vue2生命周期的区别(vue生命周期有什么作用)2025-03-13 18:18:10
  • vue钩子函数有几种(vue中钩子函数有哪些)2025-03-13 18:18:10
  • jsjs(jsjsj是什么意思)2025-03-13 18:18:10
  • pcie5(pcie5.0和pcie4.0区别)2025-03-13 18:18:10
  • pcie5.0什么时候出(pci-e 5.0)2025-03-13 18:18:10
  • js深拷贝和浅拷贝的区别(js中深拷贝和浅拷贝的区别)2025-03-13 18:18:10
  • can通讯故障怎么解决(can通讯故障522083.19)2025-03-13 18:18:10
  • map转json字符串 /u0000(map转json字符串 空没有字段)2025-03-13 18:18:10
  • swagger2的作用(swagger 2.0)2025-03-13 18:18:10
  • 全屏图片