Vue学习笔记进阶篇之函数化组件解析


Posted in Javascript onJuly 21, 2017

这两天学习了Vue.js 感觉函数化组件这个地方知识点挺多的,而且很重要,所以,今天添加一点小笔记

介绍

之前创建的锚点标题组件是比较简单,没有管理或者监听任何传递给他的状态,也没有生命周期方法。它只是一个接收参数的函数。

在这个例子中,我们标记组件为 functional, 这意味它是无状态(没有 data),无实例(没有 this 上下文)。

一个 函数化组件 就像这样:

Vue.component('my-component', {
 functional: true,
 // 为了弥补缺少的实例
 // 提供第二个参数作为上下文
 render: function (createElement, context) {
  // ...
 },
 // Props 可选
 props: {
  // ...
 }
})

组件需要的一切都是通过上下文传递,包括:

  1. props: 提供props 的对象
  2. children: VNode 子节点的数组
  3. slots: slots 对象
  4. data: 传递给组件的 data 对象
  5. parent: 对父组件的引用
  6. listeners: (2.3.0+) 一个包含了组件上所注册的 v-on 侦听器的对象。这只是一个指向 data.on 的别名。
  7. injections: (2.3.0+) 如果使用了 inject 选项, 则该对象包含了应当被注入的属性。

在添加 functional: true 之后,锚点标题组件的 render 函数之间简单更新增加context参数,this.$slots.default 更新为 context.children,之后this.level 更新为 context.props.level。

因为函数化组件只是一个函数,所以渲染开销也低很多。另外,这也意味着函数化组件不会出现在 VueJS Chrome 开发者工具的组件树里。

在作为包装组件时它们也同样非常有用,比如,当你需要做这些时:

程序化地在多个组件中选择一个

在将 children, props, data 传递给子组件之前操作它们。

下面是一个依赖传入 props 的值的smart-list组件例子,它能代表更多具体的组件:

var EmptyList = { /* ... */ }
var TableList = { /* ... */ }
var OrderedList = { /* ... */ }
var UnorderedList = { /* ... */ }
Vue.component('smart-list', {
 functional: true,
 render: function (createElement, context) {
  function appropriateListComponent () {
   var items = context.props.items
   if (items.length === 0)      return EmptyList
   if (typeof items[0] === 'object') return TableList
   if (context.props.isOrdered)   return OrderedList
   return UnorderedList
  }
  return createElement(
   appropriateListComponent(),
   context.data,
   context.children
  )
 },
 props: {
  items: {
   type: Array,
   required: true
  },
  isOrdered: Boolean
 }
})

slots()和children对比

你可能想知道为什么同时需要 slots()childrenslots().default 不是和 children 类似的吗?在一些场景中,是这样,但是如果是函数式组件和下面这样的 children 呢?

<my-functional-component>
 <p slot="foo">
  first
 </p>
 <p>second</p>
</my-functional-component>

对于这个组件,children 会给你两个段落标签,而 slots().default 只会传递第二个匿名段落标签,slots().foo 会传递第一个具名段落标签。同时拥有 children 和 slots() ,因此你可以选择让组件通过 slot() 系统分发或者简单的通过 children 接收,让其他组件去处理。

示例

渐进过渡

之前的Vue学习笔记进阶篇——列表过渡及其他中可复用的过渡提到用函数组件实现合适,下面就用函数化组件来实现那个渐进过渡

<div id="app5">
  <input v-model="query">
  <my-transition :query="query" :list="list">
    <li v-for="(item, index) in computedList"
      :key="item.msg"
      :data-index="index">
      {{item.msg}}
    </li>
  </my-transition>
</div>
  Vue.component('my-transition', {
    functional:true,
    render:function (h, ctx) {
      var data = {
        props:{
          tag:'ul',
          css:false
        },
        on:{
          beforeEnter:function (el) {
            el.style.opacity = 0
            el.style.height = 0
          },
          enter:function (el, done) {
            var delay = el.dataset.index * 150
            setTimeout(function () {
              Velocity(el, {opacity:1, height:'1.6em'},{complete:done})
            }, delay)
          },
          leave:function (el, done) {
            var delay = el.dataset.index * 150
            setTimeout(function () {
              Velocity(el, {opacity:0, height:0}, {complete:done})
            }, delay)
          }
        }
      }
      return h('transition-group', data, ctx.children)
    },
    props:['query', 'list']
  })

  var app5 = new Vue({
    el:'#app5',
    data:{
      query:'',
      list:[
        {msg:'Bruce Lee'},
        {msg:'Jackie Chan'},
        {msg:'Chuck Norris'},
        {msg:'Jet Li'},
        {msg:'Kung Furry'},
        {msg:'Chain Zhang'},
        {msg:'Iris Zhao'},
      ]
    },
    computed:{
      computedList:function () {
        var vm = this
        return this.list.filter(function (item) {
          return item.msg.toLowerCase().indexOf(vm.query.toLowerCase()) !== -1
        })
      }
    },
  })

运行结果:

Vue学习笔记进阶篇之函数化组件解析

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
基于Jquery的回车成tab焦点切换效果代码(Enter To Tab )
Nov 14 Javascript
IE8下String的Trim()方法失效的解决方法
Nov 08 Javascript
判断文档离浏览器顶部的距离的方法
Jan 08 Javascript
JS实现无限级网页折叠菜单(类似树形菜单)效果代码
Sep 17 Javascript
jQuery Easyui实现左右布局
Jan 26 Javascript
浅谈javascript中的 “ &amp;&amp; ” 和 “ || ”
Feb 02 Javascript
JavaScript校验Number(4,1)格式的数字实例代码
Mar 13 Javascript
IE9 elementUI文件上传的问题解决
Oct 17 Javascript
小程序外卖订单界面的示例代码
Dec 30 Javascript
echarts实现获取datazoom的起始值(包括x轴和y轴)
Jul 20 Javascript
Ajax获取node服务器数据的完整步骤
Sep 20 Javascript
element多个表单校验的实现
May 27 Javascript
用javascript获取任意颜色的更亮或更暗颜色值示例代码
Jul 21 #Javascript
基于JavaScript实现数码时钟效果
Mar 30 #Javascript
bootstrap多层模态框滚动条消失的问题
Jul 21 #Javascript
基于JavaScript实现无缝滚动效果
Jul 21 #Javascript
基于JavaScript实现选项卡效果
Jul 21 #Javascript
基于JavaScript实现弹幕特效
Aug 27 #Javascript
js实现水平滚动菜单导航
Jul 21 #Javascript
You might like
基于mysql的bbs设计(一)
2006/10/09 PHP
漂亮的thinkphp 跳转页封装示例
2019/10/16 PHP
从javascript语言本身谈项目实战
2006/12/27 Javascript
jquery和ajax的关系详细介绍
2013/11/29 Javascript
初识Node.js
2014/09/03 Javascript
jQuery构造函数init参数分析续
2015/05/13 Javascript
JavaScript实现点击按钮就复制当前网址
2015/12/14 Javascript
node.js文件上传处理示例
2016/10/27 Javascript
js学习笔记之事件处理模型
2016/10/31 Javascript
ionic中列表项增加和删除的实现方法
2017/01/22 Javascript
web前端vue之CSS过渡效果示例
2018/01/10 Javascript
vue 全选与反选的实现方法(无Bug 新手看过来)
2018/02/09 Javascript
vue引用js文件的多种方式(推荐)
2018/05/17 Javascript
C#程序员入门学习微信小程序的笔记
2019/03/05 Javascript
[55:47]DOTA2上海特级锦标赛C组小组赛#2 LGD VS Newbee第三局
2016/02/27 DOTA
Python学习笔记(二)基础语法
2014/06/06 Python
在Python中操作字符串之startswith()方法的使用
2015/05/20 Python
python简单文本处理的方法
2015/07/10 Python
python3+PyQt5 实现Rich文本的行编辑方法
2019/06/17 Python
Python爬虫学习之翻译小程序
2019/07/30 Python
在OpenCV里使用Camshift算法的实现
2019/11/22 Python
使用Python 自动生成 Word 文档的教程
2020/02/13 Python
PyInstaller将Python文件打包为exe后如何反编译(破解源码)以及防止反编译
2020/04/15 Python
在ipython notebook中使用argparse方式
2020/04/20 Python
浅谈matplotlib中FigureCanvasXAgg的用法
2020/06/16 Python
如何清空python的变量
2020/07/05 Python
彼得罗夫美国官网:Peter Thomas Roth美国(青瓜面膜)
2017/11/05 全球购物
Java中实现多态的机制
2015/08/09 面试题
房展策划方案
2014/06/07 职场文书
师德承诺书
2015/01/20 职场文书
2015少先队大队辅导员工作总结
2015/07/24 职场文书
医务人员岗前培训心得体会
2016/01/08 职场文书
创业计划之特色精品店
2019/08/12 职场文书
python实现局部图像放大
2021/11/17 Python
《王国之心》迎来了发售的20周年, 野村哲发布贺图
2022/04/11 其他游戏
Windows Server 2012 R2服务器安装与配置的完整步骤
2022/07/15 Servers