vue插槽用法,vue插槽有什么作用

  vue插槽用法,vue插槽有什么作用

  vue.js的灵魂是组件,组件的灵魂是槽。在插槽的帮助下,我们可以最大限度地重用组件。本文主要详细总结了slot的实现机制,在某些场景下是有用的。

  

目录

   I .样本代码II。透过现象看本质。执行原则四。父组件编译阶段五、父组件生成和渲染方法六。父组件生成VNode VII。子组件状态初始化。子组件编译阶段IX。子组件生成和渲染方法十、使用技巧10.1。命名为插槽10.2。范围插槽

  

一、样例代码

  !-子组件昏迷-

  模板

  div class=demo

  插槽插槽

  插槽名称=测试/插槽

  slot name= scopedSlots test= demo /slot

  /div

  /模板

  !-父组件-

  昏迷

  Span这是默认插槽/span

  Template slot=test 这是一个命名的插槽/模板。

  template slot= scoped slots slot-scope= scope 这是作用域插槽(旧版本){{scope.test}}/template

  template v-slot:scoped slots= scope props slot-scope= scope 这是作用域插槽(新版本){{scopeProps.test}}/template

  /昏迷

  

二、透过现象看本质

  slot的作用是实现内容分发,这需要两个条件:

  占位符

  内容分发

  组件内部定义的槽标签可以理解为一个占位符,父组件中的槽内容就是要分发的内容。槽处理的本质是把指定的内容放在指定的位置。不用说,从这篇文章中,我们可以了解到:

  插槽的实现原理

  如何在render方法中使用插槽

  

三、实现原理

  vue组件的实例化顺序为:父组件状态初始化(数据、计算、观察.)-模板编译-生成render方法-实例化render watcher -调用render方法生成VNode -修补VNode,转换为真实DOM -实例化子组件-重复同样的过程-将子组件生成的真实DOM挂载到父组件生成的真实DOM上,挂载到页面上-移除旧节点。

  从上述过程中,可以推断出:

  1.父组件模板在子组件之前被解析,因此父组件将首先获得插槽模板内容。

  2.子组件模板是后面解析的,所以当子组件调用render方法生成VNode时,可以通过某种手段获取槽的VNode节点。

  3.作用域槽可以获得子组件中的变量,因此作用域槽的VNode生成是动态的,也就是说,需要实时地将其引入到子组件的作用域中。

  整个槽加工阶段大致分为三个步骤:

  编辑和翻译

  生成渲染模板

  生成VNode

  以下面的代码为例简单概述一下槽操作的过程。

  div id=应用程序

  试验

  模板槽=你好

  123

  /模板

  /测试

  /div

  脚本

  新Vue({

  埃尔: #app ,

  组件:{

  测试:{

  模板:“h1”

  插槽名称=hello/slot

  /h1

  }

  }

  })

  /脚本

  

四、父组件编译阶段

  编译是将模板文件解析成AST语法树,AST语法树将插槽模板解析成如下数据结构:

  {

  标签:“测试”,

  ScopedSlots: {//范围插槽

  //slotName: ASTNode,

  //.

  }

  儿童:[

  {

  标签:“模板”,

  //.

  parent: parentASTNode,

  Children: [childASTNode ],//槽内容的子节点,即文本节点123。

  SlotScope:未定义,//作用域插槽绑定值

  SlotTarget: \hello\ ,//命名的插槽名称

  SlotTargetDynamic: false //是动态绑定槽吗?

  //.

  }

  ]

  }

  

五、父组件生成渲染方法

  根据AST语法树,解析生成渲染方法字符串,父组件生成的最终结果如下所示。这个结构和我们直接写render方法是一致的,本质都是生成VNode,只不过_c或者h是这个的缩写。$createElement。

  用(这个){

  return _c(div ,{attrs:{id:app}},

  [_c(测试,

  [

  _c(template ,{slot:hello},[_v(\n 123\n )])],2)

  ],

  1)

  }

  

六、父组件生成VNode

  调用render方法生成vnode,vnode的具体格式如下:

  {

  标签:“div”,

  父:未定义,

  数据:{//存储VNode配置项

  属性:{ id: #app }

  },

  context: componentContext,//组件作用域

  榆树:未定义,//真实数字正射影像图元素

  儿童:[

  {

  标签:“vue-组件-1-测试",

  子级:未定义,//组件为页面最小组成单元,插槽内容放放到子组件中解析

  父:未定义,

  组件选项:{ //组件配置项

  Ctor: VueComponentCtor,//组件构造方法

  数据:{

  挂钩:{

  init: fn,//实例化组件调用方法

  插入:fn,

  预修补:fn,

  销毁:fn

  },

  scopedSlots: { //作用域插槽配置项,用于生成作用域插槽虚拟节点

  插槽名称:插槽【数学】函数

  }

  },

  孩子:[ //组件插槽节点

  标签:"模板",

  propsData:未定义,//道具参数

  侦听器:未定义,

  数据:{

  插槽:"你好"

  },

  孩子:[ VNode ],

  父:未定义,

  上下文:componentContext //父组件作用域

  //.

  ]

  }

  }

  ],

  //.

  }

  在某视频剪辑软件中,组件是页面结构的基本单元,从上述的虚拟节点中,我们也可以看出,VNode页面层级结构结束于试验组件,测试组件孩子们处理会在子组件初始化过程中处理。子组件构造方法组装与属性合并在vue-dev \ src \ core \ vdom \ create-component。js创建组件方法中,组件实例化调用入口是在vue-dev \ src \ core \ vdom \ patch。js创建组件方法中。

  

七、子组件状态初始化

  实例化子组件时,会在initRender - resolveSlots方法中,将子组件插槽节点挂载到组件作用域伏特计中,挂载形式为虚拟机.$slots={slotName: [VNode]}形式。

  

八、子组件编译阶段

  子组件在编译阶段,会将狭槽节点,编译成以下大西洋时间结构:

  {

  标签:“h1”,

  父:未定义,

  儿童:[

  {

  标签:"插槽",

  插槽名称:“\”你好\ ,

  //.

  }

  ],

  //.

  }

  

九、子组件生成渲染方法

  生成的渲染方法如下,其中_t为渲染槽方法的简写,从渲染槽方法,我们就可以直观的将插槽内容与插槽点联系在一起。

  //渲染方法

  用(这个){

  return _c(h1 ,[ _t(hello) ],2)

  }

  //源码路径:vue-dev \ src \ core \ instance \ render-helpers \ render-slot。射流研究…

  导出函数渲染槽(

  名称:字符串,

  回退:数组节点,

  道具:对象,

  bindObject:目标

  ):数组节点{

  const scopedSlotFn=this .$scopedSlots[name]

  让节点

  if (scopedSlotFn) { //作用域槽

  道具=道具 {}

  if (bindObject) {

  if (process.env.NODE_ENV!==生产!isObject(bindObject)) {

  警告(

  没有参数的插槽v型装订需要一个对象,

  这

  )

  }

  props=extend(extend({},bindObject),props)

  }

  //作用域插槽,获取插槽虚拟节点

  nodes=scopedSlotFn(props) 回退

  }否则{

  //获取插槽普通插槽虚拟节点

  节点=这个插槽[名称] 回退

  }

  const target=props props.slot

  如果(目标){

  归还这个. createElement(template ,{ slot: target },nodes)

  }否则{

  返回节点

  }

  }

  作用域插槽与具名插槽区别

  !-演示-

  div id=应用程序

  试验

  模板slot=hello slot-scope=scope

  {{scope.hello}}

  /模板

  /测试

  /div

  脚本

  var vm=new Vue({

  埃尔: #app ,

  组件:{

  测试:{

  data () {

  返回{

  你好:"123"

  }

  },

  模板:" h1 "

  slot name= hello :hello= hello /slot

  /h1

  }

  }

  })

  /脚本

  作用域插槽与普通插槽相比,主要区别在于插槽内容可以获取到子组件作用域变量。由于需要注入子组件变量,相比于具名插槽,作用域插槽有以下几点不同:

  组装呈现方法时,作用域插槽生成一个包含注入作用域的方法。与生成VNode的createElement相比,多了一层注入作用域方法包,决定了子组件生成VNode时生成VNode的作用域槽,而父组件创建VNode时生成命名槽。_u是resolveScopedSlots,用于将节点配置项转换为{scopedSlots: {slotName: fn}}形式。

  用(这个){

  return _c(div ,{

  属性:{

  id :应用程序

  }

  },[_c(test ,{

  scopedSlots: _u([{

  按键:“你好”,

  fn:功能(范围){

  return[_ v( \ n _ s(scope . hello) \ n )]

  }

  }])

  })], 1)

  }

  当子组件被初始化时,命名的slot节点将被处理并挂载到组件$slots中,作用域slot将在renderSlot中被直接调用。

  除此之外,其他流程大致相同。slot的机制不难理解,关键在于模板解析和渲染函数生成这两个步骤,过程很长,很难理解。

  

十、使用技巧

  通过以上分析,我们可以大致了解槽加工流程。大部分工作使用模板来编写vue代码,但有时模板有一定的局限性,需要借助render方法放大vue的组件抽象能力。然后在render方法中,我们的槽的用法如下:

  

10.1、具名插槽

  槽加工一般分为两部分:

  父组件:父组件只需要写成模板编译的渲染方法,也就是指定槽名。

  子组件:由于子组件直接取父组件初始化阶段生成的VNode,所以子组件只需要用父组件生成的VNode替换槽标签。当子组件被初始化时,它将在组件的$slots属性上挂载命名的slot。

  div id=应用程序

  !-测试-

  !-模板槽=hello -

  !- 123 -

  !-/模板-

  !-/测试-

  /div

  脚本

  新Vue({

  //El:“# app”,

  渲染(createElement) {

  返回createElement(test ,[

  createElement(h3 ,{

  插槽:“你好”,

  domProps: {

  内部文本:“123”

  }

  })

  ])

  },

  组件:{

  测试:{

  渲染(createElement) {

  返回createElement(h1 ,[ this。$ slots . hello]);

  }

  //模板:“h1”

  //插槽名称=hello/slot

  ///h1

  }

  }

  }).$ mount(“# app”)

  /脚本

  

10.2、作用域插槽

  作用域插槽是灵活的,可以注入子组件状态。Scope slot render方法对于打包次要组件非常有用。以chestnut为例,在封装ElementUI表组件的基于JSON的数据时,作用域槽非常有用。

  div id=应用程序

  !-测试-

  !-span slot= hello slot-scope= scope -

  !- {{scope.hello}} -

  !- /span -

  !-/测试-

  /div

  脚本

  新Vue({

  //El:“# app”,

  渲染(createElement) {

  返回createElement(test ,{

  scopedSlots:{

  Hello: scope={//在父组件生成渲染方法中,最终转换的scope slot方法与此写法一致。

  返回createElement(span ,{

  domProps: {

  innerText: scope.hello

  }

  })

  }

  }

  })

  },

  组件:{

  测试:{

  data () {

  返回{

  你好:“123”

  }

  },

  渲染(createElement) {

  //函数由作用域槽的父组件传递,需要手动调用生成VNode。

  设slotVnode=this。$ scopedslots . hello({ hello:this . hello })

  返回createElement(h1 ,[slot node])

  }

  //模板:“h1”

  // slot name= hello :hello= hello /slot

  ///h1

  }

  }

  }).$ mount(“# app”)

  /脚本

  以上是Vue槽实现原理的详细内容。更多关于Vue slot的信息,请关注我们的其他相关文章!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: