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 篱式条件判断
Aug 22 Javascript
JQury slideToggle闪烁问题及解决办法
Jul 05 Javascript
js jquery验证银行卡号信息正则学习
Jan 21 Javascript
简单对比分析JavaScript中的apply,call与this的使用
Dec 04 Javascript
AngularJS辅助库browserTrigger用法示例
Nov 03 Javascript
理解javascript中的闭包
Jan 11 Javascript
Three.js开发实现3D地图的实践过程总结
Nov 20 Javascript
js实现HTML中Select二级联动的实例
Jan 05 Javascript
微信小程序开发之路由切换页面重定向问题
Sep 18 Javascript
基于React Native 0.52实现轮播图效果
Aug 25 Javascript
搭建基于express框架运行环境的方法步骤
Nov 15 Javascript
微信小程序实现富文本图片宽度自适应的方法
Jan 20 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 split()函数的用法详解
2013/06/05 PHP
PHP中strtr字符串替换用法详解
2014/11/26 PHP
优化javascript的执行速度
2010/01/23 Javascript
基于jquery循环map功能的代码
2011/02/26 Javascript
jquery.combobox中文api和例子,修复了上面的小bug
2011/03/28 Javascript
JavaScript 高级篇之闭包、模拟类,继承(五)
2012/04/07 Javascript
javascript游戏开发之《三国志曹操传》零部件开发(二)人物行走的实现
2013/01/23 Javascript
js实现收缩菜单效果实例代码
2013/10/30 Javascript
PHP+MySQL+jQuery随意拖动层并即时保存拖动位置实例讲解
2015/10/09 Javascript
JavaScript中的闭包
2016/02/24 Javascript
JavaScript的MVVM库Vue.js入门学习笔记
2016/05/03 Javascript
js中获取 table节点各tr及td的内容简单实例
2016/10/14 Javascript
浅谈JS读取DOM对象(标签)的自定义属性
2016/11/21 Javascript
用vue构建多页面应用的示例代码
2017/09/20 Javascript
Vue CLI2升级至Vue CLI3的方法步骤
2019/05/20 Javascript
layui prompt 设置允许空白提交的方法
2019/09/24 Javascript
vue-drag-chart 拖动/缩放图表组件的实例代码
2020/04/10 Javascript
vue实现移动端拖动排序
2020/08/21 Javascript
如何在VUE中使用vue-awesome-swiper
2021/01/04 Vue.js
[00:35]DOTA2上海特级锦标赛 VP战队宣传片
2016/03/04 DOTA
pandas多级分组实现排序的方法
2018/04/20 Python
Python定时发送消息的脚本:每天跟你女朋友说晚安
2018/10/21 Python
python3 http提交json参数并获取返回值的方法
2018/12/19 Python
浅谈python 读excel数值为浮点型的问题
2018/12/25 Python
对python For 循环的三种遍历方式解析
2019/02/01 Python
Python里字典的基本用法(包括嵌套字典)
2019/02/27 Python
python实现动态创建类的方法分析
2019/06/25 Python
html5 Canvas画图教程(3)—canvas出现1像素线条模糊不清的原因
2013/01/09 HTML / CSS
初中数学教学反思
2014/01/16 职场文书
优秀毕业生自我鉴定
2014/01/19 职场文书
小学英语教学反思
2014/01/30 职场文书
董事长秘书职责
2014/01/31 职场文书
幼儿教师寄语集锦
2014/04/03 职场文书
2015大学生入党个人自传
2015/06/26 职场文书
详解使用 CSS prefers-* 规范提升网站的可访问性与健壮性
2021/05/25 HTML / CSS
nginx七层负载均衡配置详解
2022/07/15 Servers