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 相关文章推荐
JavaScript判断两种格式的输入日期的正确性的代码
Mar 25 Javascript
HTML DOM的nodeType值介绍
Mar 31 Javascript
JS 实现导航栏悬停效果
Sep 23 Javascript
javascript日期格式化示例分享
Mar 05 Javascript
Javascript aop(面向切面编程)之around(环绕)分析
May 01 Javascript
Google 地图API Map()构造器详解
Aug 06 Javascript
完美解决js传递参数中加号和&amp;号自动改变的方法
Oct 11 Javascript
JS实现倒计时(天数、时、分、秒)
Nov 16 Javascript
为Jquery EasyUI 组件加上清除功能的方法(详解)
Apr 13 jQuery
JS实现图片点击后出现模态框效果
May 03 Javascript
Vue 兄弟组件通信的方法(不使用Vuex)
Oct 26 Javascript
Vue使用Ref跨层级获取组件的步骤
Jan 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
十大感人催泪爱情动漫 第一名至今不忍在看第二遍
2020/03/04 日漫
全文搜索和替换
2006/10/09 PHP
Discuz 模板引擎的封装类代码
2008/07/18 PHP
IIS+fastcgi下PHP运行超时问题的解决办法详解
2013/06/20 PHP
php实现cookie加密的方法
2015/03/10 PHP
功能强大的php分页函数
2016/07/20 PHP
laravel执行php artisan migrate报错的解决方法
2019/10/09 PHP
PHP内存溢出优化代码详解
2021/02/26 PHP
js 延迟加载 改变JS的位置加快网页加载速度
2012/12/11 Javascript
JS Date函数整理方便使用
2013/10/23 Javascript
浅谈JS日期(Date)处理函数
2014/12/07 Javascript
javascript实现删除前弹出确认框
2015/06/04 Javascript
javascript多物体运动实现方法分析
2016/01/08 Javascript
Augularjs-起步详解
2016/07/08 Javascript
ionic在开发ios系统微信时键盘挡住输入框的解决方法(键盘弹出问题)
2016/09/06 Javascript
js style.display=block显示布局错乱问题的解决方法
2016/09/21 Javascript
Javascript 事件冒泡机制详细介绍
2016/10/10 Javascript
BootStrap中
2016/12/10 Javascript
Bootstrap table 定制提示语的加载过程
2017/02/20 Javascript
详解node.js搭建代理服务器请求数据
2017/04/08 Javascript
JavaScript运动框架 解决速度正负取整问题(一)
2017/05/17 Javascript
微信小程序使用wxParse解析html的方法教程
2018/07/06 Javascript
详解js中的原型,原型对象,原型链
2020/07/16 Javascript
Python爬虫之pandas基本安装与使用方法示例
2018/08/08 Python
Python音频操作工具PyAudio上手教程详解
2019/06/26 Python
python采集百度搜索结果带有特定URL的链接代码实例
2019/08/30 Python
python调用Matplotlib绘制分布点图
2019/10/18 Python
Python编译成.so文件进行加密后调用的实现
2019/12/23 Python
Python用5行代码实现批量抠图的示例代码
2020/04/14 Python
解决python对齐错误的方法
2020/07/16 Python
Python面向对象特殊属性及方法解析
2020/09/16 Python
python线程优先级队列知识点总结
2021/02/28 Python
Waterford加拿大官方网站:世界著名的水晶杯品牌
2016/11/01 全球购物
学术会议邀请函范文
2014/01/22 职场文书
KTV门卫岗位职责
2014/10/09 职场文书
本科毕业论文导师评语
2014/12/31 职场文书