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开发包大全整理
Dec 22 Javascript
jquery 模拟类搜索框自动完成搜索提示功能(改进)
May 24 Javascript
通过下拉框的值来确定输入框是否可以为空的代码
Oct 18 Javascript
高性能JavaScript循环语句和条件语句
Jan 20 Javascript
深入浅析knockout源码分析之订阅
Jul 12 Javascript
Bootstrap模态框(modal)垂直居中的实例代码
Aug 18 Javascript
bootstrap fileinput实现文件上传功能
Aug 23 Javascript
深入理解Vue 组件之间传值
Aug 16 Javascript
vue图片上传本地预览组件使用详解
Feb 20 Javascript
JS实现电话号码的字母组合算法示例
Feb 26 Javascript
如何使用JavaScript检测空闲的浏览器选项卡
May 28 Javascript
Vue父子组件传值的一些坑
Sep 16 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
PHP4实际应用经验篇(7)
2006/10/09 PHP
phpmyadmin里面导入sql语句格式的大量数据的方法
2010/06/05 PHP
php 去除html标记--strip_tags与htmlspecialchars的区别详解
2013/06/26 PHP
微信公众平台开发-微信服务器IP接口实例(含源码)
2017/03/05 PHP
比较全的JS checkbox全选、取消全选、删除功能代码
2008/12/19 Javascript
Javascript在IE或Firefox下获取鼠标位置的代码
2009/12/18 Javascript
jQuery图片预加载 等比缩放实现代码
2011/10/04 Javascript
解析jquery中的ajax缓存问题
2013/12/19 Javascript
用模版生成HTML的的框架jquery.tmpl使用详解
2015/01/07 Javascript
JavaScript动态提示输入框输入字数的方法
2015/07/27 Javascript
JavaScript实现设计模式中的单例模式的一些技巧总结
2016/05/17 Javascript
echarts鼠标覆盖高亮显示节点及关系名称详解
2018/03/17 Javascript
jQuery中的$是什么意思及 $. 和 $().的区别
2018/04/20 jQuery
原生JS进行前后端同构
2018/04/22 Javascript
基于vue展开收起动画的示例代码
2018/07/05 Javascript
nodejs文件夹深层复制功能
2019/09/03 NodeJs
如何通过javaScript去除字符串两端的空白字符
2020/02/06 Javascript
[01:11:28]DOTA2-DPC中国联赛定级赛 RNG vs Phoenix BO3第一场 1月8日
2021/03/11 DOTA
python实现360皮肤按钮控件示例
2014/02/21 Python
Python 调用Java实例详解
2017/06/02 Python
Python 结巴分词实现关键词抽取分析
2017/10/21 Python
详解将Pandas中的DataFrame类型转换成Numpy中array类型的三种方法
2019/07/06 Python
解决Pycharm的项目目录突然消失的问题
2020/01/20 Python
Python模块zipfile原理及使用方法详解
2020/08/04 Python
HTML5中的网络存储实现方式
2020/04/28 HTML / CSS
阿联酋电子产品购物网站:Menakart
2017/09/15 全球购物
Fenty Beauty官网:蕾哈娜创立的美妆品牌
2021/01/07 全球购物
应聘文员自荐信范文
2014/03/11 职场文书
大学生旷课检讨书1000字
2015/02/19 职场文书
焦裕禄观后感
2015/06/03 职场文书
2016年12月份红领巾广播稿
2015/12/21 职场文书
合作合同协议书
2016/03/21 职场文书
会计工作自我鉴定范文
2019/06/21 职场文书
PostgreSQL解析URL的方法
2021/08/02 PostgreSQL
实例详解Python的进程,线程和协程
2022/03/13 Python
经典《舰娘》游改全新动画预告 预定11月开播
2022/04/01 日漫