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判断单选框或复选框是否选中方法集锦
Apr 04 Javascript
Javascript 面向对象 重载
May 13 Javascript
JavaScript 对任意元素,自定义右键菜单的实现方法
May 08 Javascript
jQuery模拟原生态App上拉刷新下拉加载更多页面及原理
Aug 10 Javascript
javascript设计简单的秒表计时器
Sep 05 Javascript
vue2.0移除或更改的一些东西(移除index key)
Aug 28 Javascript
javascript将json格式数组下载为excel表格的方法
Dec 22 Javascript
Webpack实战加载SVG的方法
Dec 26 Javascript
深入浅析Vue全局组件与局部组件的区别
Jun 15 Javascript
vue.js表单验证插件(vee-validate)的使用教程详解
May 23 Javascript
VSCode launch.json配置详细教程
Jun 18 Javascript
微信小程序实现搜索框功能及踩过的坑
Jun 19 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
珊瑚虫IP库浅析
2007/02/15 PHP
php中get_cfg_var()和ini_get()的用法及区别
2015/03/04 PHP
php通过array_push()函数添加多个变量到数组末尾的方法
2015/03/18 PHP
PHP isset()及empty()用法区别详解
2020/08/29 PHP
JS 对象介绍
2010/01/20 Javascript
jQuery焦点图切换特效插件封装实例
2013/08/18 Javascript
仿百度的关键词匹配搜索示例
2013/09/25 Javascript
点击标签切换和自动切换DIV选项卡
2014/08/10 Javascript
javascript实现起伏的水波背景效果
2016/05/16 Javascript
js实现的简练高效拖拽功能示例
2016/12/21 Javascript
100多个基础常用JS函数和语法集合大全
2017/02/16 Javascript
详解vue-router和vue-cli以及组件之间的传值
2017/07/04 Javascript
简单实现js拖拽效果
2017/07/25 Javascript
SVG实现时钟效果
2018/07/17 Javascript
bootstrap+spring boot实现面包屑导航功能(前端代码)
2019/10/09 Javascript
VUE 组件转换为微信小程序组件的方法
2019/11/06 Javascript
Vue使用富文本编辑器Vue-Quill-Editor(含图片自定义上传服务、清除复制粘贴样式等)
2020/05/15 Javascript
Vue页面跳转传递参数及接收方式
2020/09/09 Javascript
[01:32]2016国际邀请赛中国区预选赛IG战队首日赛后采访
2016/06/27 DOTA
Python去掉字符串中空格的方法
2014/03/11 Python
Python通过Pygame绘制移动的矩形实例代码
2018/01/03 Python
Python 3.8正式发布,来尝鲜这些新特性吧
2019/10/15 Python
Python集合基本概念与相关操作实例分析
2019/10/30 Python
python GUI库图形界面开发之PyQt5简单绘图板实例与代码分析
2020/03/08 Python
Python如何把字典写入到CSV文件的方法示例
2020/08/23 Python
Django配置跨域并开发测试接口
2020/11/04 Python
html5中如何将图片的绝对路径转换成文件对象
2018/01/11 HTML / CSS
Java里面如何创建一个内部类的实例
2015/01/19 面试题
TCP/IP中的TCP和IP分别承担什么责任
2012/04/21 面试题
办公室人员先进事迹
2014/01/27 职场文书
安全生产先进个人材料
2014/02/06 职场文书
护士岗前培训自我评鉴
2014/02/28 职场文书
巴黎圣母院读书笔记
2015/06/26 职场文书
趣味运动会赞词
2015/07/22 职场文书
5个pandas调用函数的方法让数据处理更加灵活自如
2022/04/24 Python