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 相关文章推荐
获取HTML DOM节点元素的方法的总结
Aug 21 Javascript
两个select之间option的互相添加操作(jquery实现)
Nov 12 Javascript
一个JavaScript函数把URL参数解析成Json对象
Sep 24 Javascript
情人节单身的我是如何在敲完代码之后收到12束玫瑰的(javascript)
Aug 21 Javascript
Jquery 垂直多级手风琴菜单附源码下载
Nov 17 Javascript
JS实现单击输入框弹出选择框效果完整实例
Dec 14 Javascript
Node.js Streams文件读写操作详解
Jul 04 Javascript
Bootstrap中的fileinput 多图片上传及编辑功能
Sep 05 Javascript
Vue2组件tree实现无限级树形菜单
Mar 29 Javascript
关于redux-saga中take使用方法详解
Feb 27 Javascript
Vue中使用create-keyframe-animation与动画钩子完成复杂动画
Apr 09 Javascript
uniapp实现横向滚动选择日期
Oct 21 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之第一天
2006/10/09 PHP
如何在WIN2K下安装PHP4.04
2006/10/09 PHP
在PHP中利用wsdl创建标准webservice的实现代码
2011/12/07 PHP
使用PHP similar text计算两个字符串相似度
2015/11/06 PHP
php创建图像具体步骤
2017/03/13 PHP
实例讲解php将字符串输出到HTML
2019/01/27 PHP
laravel异步监控定时调度器实例详解
2019/06/21 PHP
javascript数组组合成字符串的脚本
2021/01/06 Javascript
当jQuery遭遇CoffeeScript的时候 使用分享
2011/09/17 Javascript
js弹出层之1:JQuery.Boxy (二)
2011/10/06 Javascript
jQuery获取样式中的背景颜色属性值/颜色值
2012/12/17 Javascript
10个基于浏览器的JavaScript调试工具分享
2013/02/07 Javascript
自定义百度分享的分享按钮
2015/03/18 Javascript
javascript移动开发中touch触摸事件详解
2016/03/18 Javascript
Vue2递归组件实现树形菜单
2017/04/10 Javascript
nodejs批量下载图片的实现方法
2017/05/19 NodeJs
JS如何设置元素样式的方法示例
2017/08/28 Javascript
微信小程序实现漂亮的弹窗效果
2020/05/26 Javascript
websocket4.0+typescript 实现热更新的方法
2019/08/14 Javascript
H5 js点击按钮复制文本到粘贴板
2020/11/19 Javascript
[03:39]这就是刀塔,我们是冠军!燃情短片讲述我们的DOTA故事
2019/07/02 DOTA
python写的ARP攻击代码实例
2014/06/04 Python
Python中用memcached来减少数据库查询次数的教程
2015/04/07 Python
Python实现EXCEL表格的排序功能示例
2019/06/25 Python
Python操作Sqlite正确实现方法解析
2020/02/05 Python
Python爬虫:Request Payload和Form Data的简单区别说明
2020/04/30 Python
如何用Anaconda搭建虚拟环境并创建Django项目
2020/08/02 Python
详解canvas绘制多张图的排列顺序问题
2019/01/21 HTML / CSS
美国当红的名品折扣网:Gilt Groupe
2016/08/15 全球购物
孕妇内衣和胸罩:Cake Maternity
2018/07/16 全球购物
幼师自荐信
2013/10/26 职场文书
python中pandas.read_csv()函数的深入讲解
2021/03/29 Python
vue使用v-model进行跨组件绑定的基本实现方法
2021/04/28 Vue.js
SQL优化老出错,那是你没弄明白MySQL解释计划用法
2021/11/27 MySQL
oracle删除超过N天数据脚本的方法
2022/02/28 Oracle
Vue.js中v-bind指令的用法介绍
2022/03/13 Vue.js