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 相关文章推荐
GreyBox技术总结(转)
Nov 23 Javascript
jQuery中remove()方法用法实例
Dec 25 Javascript
JavaScript设计模式之抽象工厂模式介绍
Dec 28 Javascript
使用npm发布Node.JS程序包教程
Mar 02 Javascript
Windows系统下Node.js的简单入门教程
Jun 23 Javascript
javascript实现手机震动API代码
Aug 05 Javascript
浅谈node.js 命令行工具(cli)
May 10 Javascript
使用vue-router完成简单导航功能【推荐】
Jun 28 Javascript
在小程序中使用腾讯视频插件播放教程视频的方法
Jul 10 Javascript
Vue+Element-UI实现上传图片并压缩
Nov 26 Javascript
详解vue 组件注册
Nov 20 Vue.js
vue 实现基础组件的自动化全局注册
Dec 25 Vue.js
用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
php下的权限算法的实现
2007/04/28 PHP
php 将excel导入mysql
2009/11/09 PHP
PHP判断指定时间段的2个方法
2014/03/14 PHP
php实现获取文件mime类型的方法
2015/02/11 PHP
php实现将上传word文件转为html的方法
2015/06/03 PHP
PHP获取文件扩展名的4种方法
2015/11/24 PHP
PHP创建多级目录的两种方法
2016/10/28 PHP
PHP面相对象中的重载与重写
2017/02/13 PHP
php 算法之实现相对路径的实例
2017/10/17 PHP
ie focus bug 解决方法
2009/09/03 Javascript
基于jQuery的固定表格头部的代码(IE6,7,8测试通过)
2010/05/18 Javascript
Firebug入门指南(Firefox浏览器)
2010/08/21 Javascript
jQuery判断元素是否是隐藏的代码
2011/04/24 Javascript
jquery html动态生成select标签出问题的解决方法
2013/11/20 Javascript
jQuery写fadeTo示例代码
2014/02/21 Javascript
深入理解JavaScript系列(45):代码复用模式(避免篇)详解
2015/03/04 Javascript
js点击按钮实现带遮罩层的弹出视频效果
2015/12/19 Javascript
jquery自定义表单验证插件
2016/10/12 Javascript
JS 实现随机验证码功能
2017/02/15 Javascript
Angularjs 实现移动端在线测评效果(推荐)
2017/04/05 Javascript
js模拟支付宝密码输入框
2017/04/11 Javascript
Linux系统中利用node.js提取Word(doc/docx)及PDF文本的内容
2017/06/17 Javascript
ajax请求data遇到的问题分析
2018/01/18 Javascript
微信小程序实现留言板(Storage)
2018/11/02 Javascript
Python查找函数f(x)=0根的解决方法
2015/05/07 Python
Python中的localtime()方法使用详解
2015/05/22 Python
Python实现统计英文单词个数及字符串分割代码
2015/05/28 Python
python web框架中实现原生分页
2019/09/08 Python
Python批量将图片灰度化的实现代码
2020/04/11 Python
天巡全球:Skyscanner Global
2017/06/20 全球购物
DHC美国官网:日本通信销售第一的化妆品品牌
2017/11/12 全球购物
求职信怎么写
2014/05/23 职场文书
2016年暑假家长对孩子评语
2015/12/01 职场文书
Nginx下配置Https证书详细过程
2021/04/01 Servers
《我的美好婚事》动画化决定纪念插画与先导PV公开
2022/04/06 日漫
Windows Server 2012 修改远程默认端口3389的方法
2022/04/28 Servers