如何理解Vue的render函数的具体用法


Posted in Javascript onAugust 30, 2017

本文介绍了如何理解Vue的render函数的具体用法,分享给大家,具体如下:

第一个参数(必须) - {String | Object | Function}

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>render</title>
  <script src="https://cdn.bootcss.com/vue/2.3.4/vue.js"></script>
</head>
<body>
  <div id="app">
    <elem></elem>
  </div>
  <script>
    Vue.component('elem', {
      render: function(createElement) {
        return createElement('div');//一个HTML标签字符
        /*return createElement({
          template: '<div></div>'//组件选项对象
        });*/
        /*var func = function() {
          return {template: '<div></div>'}
        };
        return createElement(func());//一个返回HTML标签字符或组件选项对象的函数*/
      }
    });
    new Vue({
      el: '#app'
    });
  </script>
</body>
</html>

第二个参数(可选) - {Object}

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>render</title>
  <script src="https://cdn.bootcss.com/vue/2.3.4/vue.js"></script>
</head>
<body>
  <div id="app">
    <elem></elem>
  </div>
  <script>
    Vue.component('elem', {
      render: function(createElement) {
        var self = this;
        return createElement('div', {//一个包含模板相关属性的数据对象
          'class': {
            foo: true,
            bar: false
          },
          style: {
            color: 'red',
            fontSize: '14px'
          },
          attrs: {
            id: 'foo'
          },
          domProps: {
            innerHTML: 'baz'
          }
        });
      }
    });
    new Vue({
      el: '#app'
    });
  </script>
</body>
</html>

第三个参数(可选) - {String | Array}

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>render</title>
  <script src="https://cdn.bootcss.com/vue/2.3.4/vue.js"></script>
</head>
<body>
  <div id="app">
    <elem></elem>
  </div>
  <script>
    Vue.component('elem', {
      render: function(createElement) {
        var self = this;
        // return createElement('div', '文本');//使用字符串生成文本节点
        return createElement('div', [//由createElement函数构建而成的数组
          createElement('h1', '主标'),//createElement函数返回VNode对象
          createElement('h2', '副标')
        ]);
      }
    });
    new Vue({
      el: '#app'
    });
  </script>
</body>
</html>

两种组件写法对比

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>render</title>
  <script src="https://cdn.bootcss.com/vue/2.3.4/vue.js"></script>
</head>
<body>
  <div id="app">
    <ele></ele>
  </div>
  <script>
    /*Vue.component('ele', {
      template: '<div id="elem" :class="{show: show}" @click="handleClick">文本</div>',
      data: function() {
        return {
          show: true
        }
      },
      methods: {
        handleClick: function() {
          console.log('clicked!');
        }
      }
    });*/
    Vue.component('ele', {
      render: function(createElement) {
        return createElement('div', {
          'class': {
            show: this.show
          },
          attrs: {
            id: 'elem'
          },
          on: {
            click: this.handleClick
          }
        }, '文本');
      },
      data: function() {
        return {
          show: true
        }
      },
      methods: {
        handleClick: function() {
          console.log('clicked!');
        }
      }
    });
    new Vue({
      el: '#app'
    });
  </script>
</body>
</html>

this.$slots用法

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>render</title>
  <script src="https://cdn.bootcss.com/vue/2.3.4/vue.js"></script>
</head>
<body>
  <div id="app">
    <blog-post>
      <h1 slot="header"><span>About Me</span></h1>
      <p>Here's some page content</p>
      <p slot="footer">Copyright 2016 Evan You</p>
      <p>If I have some content down here</p>
    </blog-post>
  </div>
  <script>
    Vue.component('blog-post', {
      render: function(createElement) {
        var header = this.$slots.header,//返回由VNode组成的数组
          body = this.$slots.default,
          footer = this.$slots.footer;
        return createElement('div', [
          createElement('header', header),
          createElement('main', body),
          createElement('footer', footer)
        ])
      }
    });
    new Vue({
      el: '#app'
    });
  </script>
</body>
</html>

使用props传递数据

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>render</title>
  <script src="https://cdn.bootcss.com/vue/2.3.4/vue.js"></script>
</head>
<body>
  <div id="app">
    <ele :show="show"></ele>
    <ele :show="!show"></ele>
  </div>
  <script>
    Vue.component('ele', {
      render: function(createElement) {
        if (this.show) {
          return createElement('p', 'true');
        } else {
          return createElement('p', 'false');
        }
      },
      props: {
        show: {
          type: Boolean,
          default: false
        }
      }
    });
    new Vue({
      el: '#app',
      data: {
        show: false
      }
    });
  </script>
</body>
</html>

VNodes必须唯一

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>render</title>
  <script src="https://cdn.bootcss.com/vue/2.3.4/vue.js"></script>
</head>
<body>
  <!-- VNode必须唯一 -->
  <div id="app">
    <ele></ele>
  </div>
  <script>
    var child = {
      render: function(createElement) {
        return createElement('p', 'text');
      }
    };
    /*Vue.component('ele', {
      render: function(createElement) {
        var childNode = createElement(child);
        return createElement('div', [
          childNode, childNode//VNodes必须唯一,渲染失败
        ]);
      }
    });*/
    Vue.component('ele', {
      render: function(createElement) {
        return createElement('div', 
          Array.apply(null, {
            length: 2
          }).map(function() {
            return createElement(child)//正确写法
          })
        );
      }
    });
    new Vue({
      el: '#app'
    })
  </script>
</body>
</html>

v-model指令

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>render</title>
  <script src="https://cdn.bootcss.com/vue/2.3.4/vue.js"></script>
</head>
<body>
  <div id="app">
    <el-input :name="name" @input="val=>name=val"></el-input>
    <div>你的名字是{{name}}</div>
  </div>
  <script>
    Vue.component('el-input', {
      render: function(createElement) {
        var self = this;
        return createElement('input', {
          domProps: {
            value: self.name
          },
          on: {
            input: function(event) {
              self.$emit('input', event.target.value);
            }
          }
        })
      },
      props: {
        name: String
      }
    });
    new Vue({
      el: '#app',
      data: {
        name: 'hdl'
      }
    });
  </script>
</body>
</html>

作用域插槽

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>render</title>
  <script src="https://cdn.bootcss.com/vue/2.3.4/vue.js"></script>
</head>
<body>
  <div id="app">
    <ele>
      <template scope="props">
        <span>{{props.text}}</span>
      </template>
    </ele>
  </div>
  <script>
    Vue.component('ele', {
      render: function(createElement) {
        // 相当于<div><slot :text="msg"></slot></div>
        return createElement('div', [
          this.$scopedSlots.default({
            text: this.msg
          })
        ]);
      },
      data: function() {
        return {
          msg: '来自子组件'
        }
      }
    });
    new Vue({
      el: '#app'
    });
  </script>
</body>
</html>

向子组件中传递作用域插槽

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>render</title>
  <script src="https://cdn.bootcss.com/vue/2.3.4/vue.js"></script>
</head>
<body>
  <div id="app">
    <ele></ele>
  </div>
  <script>
    Vue.component('ele', {
      render: function(createElement) {
        return createElement('div', [
          createElement('child', {
            scopedSlots: {
              default: function(props) {
                return [
                  createElement('span', '来自父组件'),
                  createElement('span', props.text)
                ];
              }
            }
          })
        ]);
      }
    });
    Vue.component('child', {
      render: function(createElement) {
        return createElement('b', this.$scopedSlots.default({text: '我是组件'}));
      }
    });
    new Vue({
      el: '#app'
    });
  </script>
</body>
</html>

函数化组件

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>render</title>
  <script src="https://cdn.bootcss.com/vue/2.3.4/vue.js"></script>
</head>
<body>
  <div id="app">
    <smart-item :data="data"></smart-item>
    <button @click="change('img')">切换为图片为组件</button>
    <button @click="change('video')">切换为视频为组件</button>
    <button @click="change('text')">切换为文本组件</button>
  </div>
  <script>
    // 图片组件选项
    var ImgItem = {
      props: ['data'],
      render: function(createElement) {
        return createElement('div', [
          createElement('p', '图片组件'),
          createElement('img', {
            attrs: {
              src: this.data.url
            }
          })
        ]);
      }
    }
    // 视频组件
    var VideoItem = {
      props: ['data'],
      render: function(createElement) {
        return createElement('div', [
          createElement('p', '视频组件'),
          createElement('video', {
            attrs: {
              src: this.data.url,
              controls: 'controls',
              autoplay: 'autoplay'
            }
          })
        ]);
      }
    };
    /*纯文本组件*/
    var TextItem = {
      props: ['data'],
      render: function(createElement) {
        return createElement('div', [
          createElement('p', '纯文本组件'),
          createElement('p', this.data.text)
        ]);
      }
    };

    Vue.component('smart-item', {
      functional: true,
      render: function(createElement, context) {
        function getComponent() {
          var data = context.props.data;
          if (data.type === 'img') return ImgItem;
          if (data.type === 'video') return VideoItem;
          return TextItem;
        }
        return createElement(
          getComponent(),
          {
            props: {
              data: context.props.data
            }
          },
          context.children
        )
      },
      props: {
        data: {
          type: Object,
          required: true
        }
      }
    });
    new Vue({
      el: '#app',
      data() {
        return {
          data: {}
        }
      },
      methods: {
        change: function(type) {
           if (type === 'img') {
            this.data = {
              type: 'img',
              url: 'https://raw.githubusercontent.com/iview/iview/master/assets/logo.png'
            }
          } else if (type === 'video') {
            this.data = {
              type: 'video',
              url: 'http://vjs.zencdn.net/v/oceans.mp4'
            }
          } else if (type === 'text') {
            this.data = {
              type: 'text',
              content: '这是一段纯文本'
            }
          }
        }
      },
      created: function() {
        this.change('img');
      }
    });
  </script>
</body>
</html>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
My Desktop :) 桌面式代码
Dec 29 Javascript
自己动手制作jquery插件之自动添加删除行的实现
Oct 13 Javascript
jQuery实现ichat在线客服插件
Dec 29 Javascript
vue.js实现仿原生ios时间选择组件实例代码
Dec 21 Javascript
AngularJS使用ng-inlude指令加载页面失败的原因与解决方法
Jan 19 Javascript
JS实现简单抖动效果
Jun 01 Javascript
JS实现搜索关键词的智能提示功能
Jul 07 Javascript
客户端(vue框架)与服务器(koa框架)通信及服务器跨域配置详解
Aug 26 Javascript
关于vue状态过渡transition不起作用的原因解决
Apr 09 Javascript
微信小程序实现弹出菜单动画
Jun 21 Javascript
JavaScript中this函数使用实例解析
Feb 21 Javascript
JavaScript实现缓动动画
Nov 25 Javascript
微信小程序之发送短信倒计时功能
Aug 30 #Javascript
使用node.js对音视频文件加密的实例代码
Aug 30 #Javascript
hammer.js实现图片手势放大效果
Aug 29 #Javascript
js禁止表单重复提交
Aug 29 #Javascript
View.post() 不靠谱的地方你知道多少
Aug 29 #Javascript
jsTree事件和交互以及插件plugins详解
Aug 29 #Javascript
移动端Ionic App 资讯上下循环滚动的实现代码(跑马灯效果)
Aug 29 #Javascript
You might like
php4的彩蛋
2006/10/09 PHP
dede3.1分页文字采集过滤规则详说(图文教程)续二
2007/04/03 PHP
PHP中用接口、抽象类、普通基类实现“面向接口编程”与“耦合方法”简述
2011/03/23 PHP
PHP 9 大缓存技术总结
2015/09/17 PHP
PHP中常用的魔术方法
2017/04/28 PHP
php获取ajax的headers方法与内容实例
2017/12/27 PHP
php使用gearman进行任务分发操作实例详解
2020/02/26 PHP
Javascript对象属性方法汇总
2013/11/21 Javascript
js 采用delete实现继承示例代码
2014/05/20 Javascript
setTimeout内不支持jquery的选择器的解决方案
2015/04/28 Javascript
javascript获取文档坐标和视口坐标
2015/05/26 Javascript
基于jQuery实现的菜单切换效果
2015/10/16 Javascript
老生常谈遮罩层 滚动条的问题
2016/04/29 Javascript
js中获取时间new Date()的全面介绍
2016/06/20 Javascript
JS获取一个未知DIV高度的方法
2016/08/09 Javascript
jsonp跨域请求实现示例
2017/03/13 Javascript
javascript基本数据类型和转换
2017/03/17 Javascript
vue.js,ajax渲染页面的实例
2018/02/11 Javascript
jquery实现动态添加附件功能
2018/10/23 jQuery
js时间转换毫秒的实例代码
2019/08/21 Javascript
Vue+ElementUI table实现表格分页
2019/12/14 Javascript
跟老齐学Python之坑爹的字符编码
2014/09/28 Python
wxPython实现带颜色的进度条
2019/11/19 Python
python单例设计模式实现解析
2020/01/07 Python
django rest framework serializers序列化实例
2020/05/13 Python
详解Pandas 处理缺失值指令大全
2020/07/30 Python
COACH德国官方网站:纽约现代奢侈品牌,1941年
2018/06/09 全球购物
关于环保的建议书400字
2014/03/12 职场文书
小学教师寄语大全
2014/04/03 职场文书
工程负责人任命书
2014/06/06 职场文书
八荣八耻的活动方案
2014/08/16 职场文书
2015年实习生工作总结报告
2015/04/28 职场文书
公司借条范本
2015/05/25 职场文书
红楼梦读书笔记
2015/06/25 职场文书
酒店工程部的岗位职责汇总大全
2019/10/23 职场文书
如何用python识别滑块验证码中的缺口
2021/04/01 Python