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 相关文章推荐
ajaxControlToolkit AutoCompleteExtender的用法
Oct 30 Javascript
javascript RadioButtonList获取选中值
Apr 09 Javascript
csdn 论坛技术区平均给分功能
Nov 07 Javascript
javascript面向对象之二 命名空间
Feb 08 Javascript
Egret引擎开发指南之视觉编程
Sep 03 Javascript
jquery中checkbox使用方法简单实例演示
Nov 24 Javascript
JS组件Bootstrap实现下拉菜单效果代码
Apr 26 Javascript
Vue 短信验证码组件开发详解
Feb 14 Javascript
详解bootstrap用dropdown-menu实现上下文菜单
Sep 22 Javascript
vue双花括号的使用方法 附练习题
Nov 07 Javascript
webpack多入口多出口的实现方法
Aug 17 Javascript
vue-cli3 项目从搭建优化到docker部署的方法
Jan 28 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
使用php实现快钱支付功能(涉及到接口)
2013/07/01 PHP
zend framework文件上传功能实例代码
2013/12/25 PHP
php中类和对象:静态属性、静态方法
2017/04/09 PHP
Laravel 5.5 的自定义验证对象/类示例代码详解
2017/08/29 PHP
JQuery 确定css方框模型(盒模型Box Model)
2010/01/22 Javascript
JS获取URL中参数值(QueryString)的4种方法分享
2014/04/12 Javascript
JavaScript使用ActiveXObject访问Access和SQL Server数据库
2015/04/02 Javascript
学习javascript文件加载优化
2016/02/19 Javascript
JavaScript实现设计模式中的单例模式的一些技巧总结
2016/05/17 Javascript
微信小程序 devtool隐藏的秘密
2017/01/21 Javascript
JavaScript解析JSON格式数据的方法示例
2017/01/24 Javascript
js控制一个按钮是否可点击(可使用)disabled的实例
2017/02/14 Javascript
phantomjs导出html到pdf的方法总结
2017/10/19 Javascript
ECharts地图绘制和钻取简易接口详解
2019/07/12 Javascript
微信小程序 如何保持登录状态
2019/08/16 Javascript
vue 实现模糊检索并根据其他字符的首字母顺序排列
2019/09/19 Javascript
小程序开发之模态框组件封装
2020/04/23 Javascript
[03:08]TI9战队档案 - Vici Gaming
2019/08/20 DOTA
学习python (1)
2006/10/31 Python
深入Python解释器理解Python中的字节码
2015/04/01 Python
Python编程中对文件和存储器的读写示例
2016/01/25 Python
Python实现霍夫圆和椭圆变换代码详解
2018/01/12 Python
对django后台admin下拉框进行过滤的实例
2019/07/26 Python
基于python实现百度语音识别和图灵对话
2020/11/02 Python
如何基于Python pygame实现动画跑马灯
2020/11/18 Python
用纯css3和html制作泡沫对话框实现代码
2013/03/21 HTML / CSS
雷曼兄弟的五金店:Lehman’s Hardware Store
2019/04/10 全球购物
与C++相比,Java中的数组有什么不同
2014/03/25 面试题
通信工程毕业生自荐信
2013/11/01 职场文书
婚庆公司的创业计划书
2014/01/22 职场文书
公司新年寄语
2014/04/04 职场文书
球队口号
2014/06/18 职场文书
小学生暑假安全公约
2015/07/14 职场文书
寒假致家长的一封信
2015/10/10 职场文书
windows11怎么查看自己安装的版本号? win11版本号的查看方法
2021/11/21 数码科技
Nginx使用ngx_http_upstream_module实现负载均衡功能示例
2022/08/05 Servers