IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> vue插槽原理 -> 正文阅读

[JavaScript知识库]vue插槽原理

vue插槽原理之前一直理解的不好,因为之前一直理解错了,首先插槽和作用域插槽是完全不同的东西,要区别对待

对于插槽称之为slot

let AppLayout = {
  template: '<div class="container">' +
  '<header><slot name="header"></slot></header>' +
  '<main><slot>默认内容</slot></main>' +
  '<footer><slot name="footer"></slot></footer>' +
  '</div>'
}

let vm = new Vue({
  el: '#app',
  template: '<div>' +
  '<app-layout>' +
  '<h1 slot="header">{{title}}</h1>' +
  '<p>{{msg}}</p>' +
  '<p slot="footer">{{desc}}</p>' +
  '</app-layout>' +
  '</div>',
  data() {
    return {
      title: '我是标题',
      msg: '我是内容',
      desc: '其它信息'
    }
  },
  components: {
    AppLayout
  }
})

之前对vnode的创建顺序理解有误,以为父组件创建vnode的时候,创建到app-layout这里的时候,子组件会进行初始化操作,其实是错误的,父组件执行render函数创建vnode的时候,render函数是这样的

with(this){
  return _c('div',
    [_c('app-layout',
      [_c('h1',{attrs:{"slot":"header"},slot:"header"},
         [_v(_s(title))]),
       _c('p',[_v(_s(msg))]),
       _c('p',{attrs:{"slot":"footer"},slot:"footer"},
         [_v(_s(desc))]
         )
       ])
     ],
   1)}

有slot属性的节点vnode已经在app-layout组件的vnode创建之前创建了,先创建h1节点对应的vnode,再创建p节点对应的vnode,然后是app-layout对应的vnode,最后才是div对应的vnode,

也就是说在子组件app-layou初始化之前,先创建了子组件子节点对应的slot真实vnode,再创建了子组件的vnode,创建了子组件vnode不代表子组件已经初始化了,仅仅是类似于元素节点的vnode

父组件执行render函数生成vnode之后,会通过patch方法将vnode转化为真是dom,在这个过程里,会将vnode创建为真实dom,然后插入到父vnode对应的真实dom里,创建组件的真实dom的时候,会执行子组件的初始化操作,就是parse,render,patch,即解析模版生成抽象语法树,遍历抽象语法树生成render函数,通过render函数和组件中的数据生成vnode,最后通过patch方法将vnode转化成真实dom

这个时候子组件的render函数是这样的

with(this) {
  return _c('div',{
    staticClass:"container"
    },[
      _c('header',[_t("header")],2),
      _c('main',[_t("default",[_v("默认内容")])],2),
      _c('footer',[_t("footer")],2)
      ]
   )
}

_t是renderSlot方法,就是将slot标签转化成vnode的方法,slot标签相当于一个虚拟的节点,不是真实存在的,相当于一个占位符,slot标签的name属性和父组件里节点的slot属性是一一对应关系,也就是说可以拿slot标签的name属性当作key,去父组件里查找相同的slot属性,然后拿到对应的vnode,然后在renderSlot返回即可,父组件里查找slot属性的范围是子组件的子节点,

export function renderSlot (
  name: string,
  fallback: ?Array<VNode>,
  props: ?Object,
  bindObject: ?Object
): ?Array<VNode> {
  ......
  let nodes = this.$slots[name]
  return nodes;
}

this.$slots是在子组件初始化的时候,将子组件在父组件里生成的子节点vnode按照slot属性的值进行的处理,this.$slots是一个对象,对象的key是vnode对应的slot属性值,就是先存储起来,等到子组件执行render函数生成自己的vnode的时候,通过slot标签的name属性,在this.$slots里查找到对应的vnode然后返回即可

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-10 13:19:49  更:2021-08-10 13:20:10 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/17 16:11:44-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码