Vue函数式组件的应用实例详解


Posted in Javascript onAugust 30, 2019

一、函数式组件和普通组件的区别

  • 渲染快
  • 没有实例,意味着没有(this)
  • 没有生命周期(没有响应式数据)

二、组件函数的使用

1.以局部组件为例,将组件标记为functional=ture;

因为函数式没有实例,因此组件需要的一切都是通过context参数传递,它是一个包括如下字段的对象:

  • props:提供所有 prop 的对象children: VNode 子节点的数组slots: 一个函数,返回了包含所有插槽的对象scopedSlots: (2.6.0+) 一个暴露传入的作用域插槽的对象。也以函数形式暴露普通插槽。data:传递给组件的整个数据对象,作为createElement的第二个参数传入组件parent:对父组件的引用listeners: (2.3.0+) 一个包含了所有父组件为当前组件注册的事件监听器的对象。这是data.on的一个别名。injections: (2.3.0+) 如果使用了inject选项,则该对象包含了应当被注入的属性。

在添加 functional: true 之后,需要更新我们的锚点标题组件的渲染函数,为其增加 context参数,并将 this.$slots.default 更新为 context.children,然后将 this.level 更新为 context.props.level。

因为函数式组件只是函数,所以渲染开销也低很多。

在作为包装组件时它们也同样非常有用。比如,当你需要做这些时:

  • 程序化地在多个组件中选择一个来代为渲染;
  • 在将 children、props、data 传递给子组件之前操作它们。
data() {
    return {
      changer:1
    }
  },
components: {
    MyCmp:{
      functional:true,  //必要的设置
      render: function (createElement, context) {
        function getcomp(cmp){
          console.info(this); //输出为undefined,证明没有实例
          if(cmp==1){
            return comp1; 
          }else{
            return comp2
          }
        }
        return createElement(getcomp(context.props.changer),
        {
          props:{
            cmpData:context.props.data //为子组件传递数据
          }
        }
        );
      },

 2. 定义要渲染的组件

var comp1={
  props:['cmpData'],
  render:function(createElement,context){
    return createElement('el-input',{
      props:{
        type:this.cmpData
      }
    });
  },
  mounted() {
    console.log(this) //这个组件为正常组件
  },
}
var comp2={
  props:['cmpData'],
  render:function(createElement,context){
    return createElement('el-button',{
      props:{
        type:this.cmpData
      }
    });
  },
  mounted() {
    console.log(this) //正常组件
  },
}

三、在父组件中使用

<template>
  <div>
    <el-input v-model="changer" placeholder="子组件"></el-input>
    <my-cmp :changer="changer"></my-cmp>
  </div>
</template>
<script>

四、理解渲染函数的参数

接下来说一下createElement 接受的参数:

第一个参数:可以是  {String | Object | Function}

不管是那种类型,最终返回到都是需要渲染的普通DOM标签,

第二个参数:是一个对象,这个参数是可选的,定义了需要渲染组件的参数,相对于普通HTML标签的属性是一样的。

还可以自定义指令的,Vue特有的东西,只是抽象一些,没有直接用Vue.directive()用起来直观。

第三个参数:子级虚拟节点,如果你这个节点只是单节点,没有嵌套节点,这个参数可以忽略。如果有的你就要使用一个数据数组的值位cerateElement()返回的虚拟节点。套路都是一样的。

// @returns {VNode}
createElement(
 // {String | Object | Function}
 // 一个 HTML 标签名、组件选项对象,或者
 // resolve 了上述任何一种的一个 async 函数。必填项。
 'div',
 // {Object}
 // 一个与模板中属性对应的数据对象。可选。
 {
  // 与 `v-bind:class` 的 API 相同,
  // 接受一个字符串、对象或字符串和对象组成的数组
  'class': {
    foo: true,
    bar: false
  },
  // 与 `v-bind:style` 的 API 相同,
  // 接受一个字符串、对象,或对象组成的数组
  style: {
    color: 'red',
    fontSize: '14px'
  },
  // 普通的 HTML 特性
  attrs: {
    id: 'foo'
  },
  // 组件 prop
  props: {
    myProp: 'bar'
  },
  // DOM 属性
  domProps: {
    innerHTML: 'baz'
  },
  // 事件监听器在 `on` 属性内,
  // 但不再支持如 `v-on:keyup.enter` 这样的修饰器。
  // 需要在处理函数中手动检查 keyCode。
  on: {
    click: this.clickHandler
  },
  // 仅用于组件,用于监听原生事件,而不是组件内部使用
  // `vm.$emit` 触发的事件。
  nativeOn: {
    click: this.nativeClickHandler
 },
 // 自定义指令。注意,你无法对 `binding` 中的 `oldValue`
 // 赋值,因为 Vue 已经自动为你进行了同步。
 directives: [
  {
   name: 'my-custom-directive',
   value: '2',
   expression: '1 + 1',
   arg: 'foo',
   modifiers: {
    bar: true
   }
  }
 ],
 // 作用域插槽的格式为
 // { name: props => VNode | Array<VNode> }
 scopedSlots: {
  default: props => createElement('span', props.text)
 },
 // 如果组件是其它组件的子组件,需为插槽指定名称
 slot: 'name-of-slot',
 // 其它特殊顶层属性
 key: 'myKey',
 ref: 'myRef',
 // 如果你在渲染函数中给多个元素都应用了相同的 ref 名,
 // 那么 `$refs.myRef` 会变成一个数组。
 refInFor: true  
 },
 // {String | Array}
 // 子级虚拟节点 (VNodes),由 `createElement()` 构建而成,
 // 也可以使用字符串来生成“文本虚拟节点”。可选。
 [
  '先写一些文字',
  createElement('h1', '一则头条'),
  createElement(MyComponent, {
   props: {
    someProp: 'foobar'
   }
  })
 ]
)

总结

以上所述是小编给大家介绍的Vue函数式组件的应用实例详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Javascript 相关文章推荐
jquery 取子节点及当前节点属性值的方法
Aug 24 Javascript
JS应用正则表达式转换大小写示例
Sep 18 Javascript
jQuery操作Table技巧大汇总
Jan 23 Javascript
js显示动态时间的方法详解
Aug 20 Javascript
JavaScript实现url参数转成json形式
Sep 25 Javascript
JavaScript构建自己的对象示例
Nov 29 Javascript
JS中检测数据类型的几种方式及优缺点小结
Dec 12 Javascript
关于AngularJs数据的本地存储详解
Jan 20 Javascript
原生js调用json方法总结
Feb 22 Javascript
Webpack中publicPath路径问题详解
May 03 Javascript
浅谈vue项目可以从哪些方面进行优化
May 05 Javascript
Vue项目history模式下微信分享爬坑总结
Mar 29 Javascript
详解elementui之el-image-viewer(图片查看器)
Aug 30 #Javascript
vue+koa2实现session、token登陆状态验证的示例
Aug 30 #Javascript
js利用递归与promise 按顺序请求数据的方法
Aug 30 #Javascript
Vue-CLI 项目在pycharm中配置方法
Aug 30 #Javascript
JS实现页面跳转与刷新的方法汇总
Aug 30 #Javascript
Vue 动态组件components和v-once指令的实现
Aug 30 #Javascript
java实现单链表增删改查的实例代码详解
Aug 30 #Javascript
You might like
用 PHP5 轻松解析 XML
2006/12/04 PHP
php比较相似字符串的方法
2015/06/05 PHP
thinkphp框架实现数据添加和显示功能
2016/06/29 PHP
php+jquery+html实现点击不刷新加载更多的实例代码
2016/08/12 PHP
php遍历替换目录下文件指定内容的方法
2016/11/10 PHP
使用composer命令加载vendor中的第三方类库 的方法
2019/07/09 PHP
关于使用 jBox 对话框的提交不能弹出问题解决方法
2012/11/07 Javascript
jQuery获取浏览器中的分辨率实现代码
2013/04/23 Javascript
js实现头像图片切割缩放及无刷新上传图片的方法
2015/07/17 Javascript
jQuery实现的调整表格行tr上下顺序
2016/01/10 Javascript
有关JavaScript中call()和apply() 的一些理解
2016/05/20 Javascript
Nodejs之http的表单提交
2017/07/07 NodeJs
基于three.js编写的一个项目类示例代码
2018/01/05 Javascript
解决layui table表单提示数据接口请求异常的问题
2019/09/24 Javascript
微信小程序如何获取地址
2019/12/24 Javascript
Vue+scss白天和夜间模式切换功能的实现方法
2021/01/05 Vue.js
[05:00]第二届DOTA2亚洲邀请赛主赛事第三天比赛集锦.mp4
2017/04/04 DOTA
[01:44]Ti10举办地公布
2019/08/25 DOTA
python操作摄像头截图实现远程监控的例子
2014/03/25 Python
在python的WEB框架Flask中使用多个配置文件的解决方法
2014/04/18 Python
PyQt5实现类似别踩白块游戏
2019/01/24 Python
python+opencv像素的加减和加权操作的实现
2019/07/14 Python
python中将两组数据放在一起按照某一固定顺序shuffle的实例
2019/07/15 Python
python爬虫 正则表达式解析
2019/09/28 Python
python2 对excel表格操作完整示例
2020/02/23 Python
Python使用Matlab命令过程解析
2020/06/04 Python
解决Keras 自定义层时遇到版本的问题
2020/06/16 Python
opencv 图像轮廓的实现示例
2020/07/08 Python
python爬虫筛选工作实例讲解
2020/11/23 Python
孝老爱亲模范事迹
2014/01/24 职场文书
校长先进事迹材料
2014/02/01 职场文书
人力资源部经理岗位职责规定
2014/02/23 职场文书
教堂婚礼主持词
2014/03/14 职场文书
老人节标语大全
2014/10/08 职场文书
银行员工考核评语
2014/12/31 职场文书
Canvas如何做个雪花屏版404的实现
2021/09/25 HTML / CSS