如何理解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 相关文章推荐
Mootools 1.2教程 Tooltips
Sep 15 Javascript
JQuery入门——用one()方法绑定事件处理函数(仅触发一次)
Feb 05 Javascript
js window对象属性和方法相关资料整理
Nov 11 Javascript
学习Javascript闭包(Closure)知识
Aug 07 Javascript
JavaScript实现窗口抖动效果
Oct 19 Javascript
正则 js分转元带千分符号详解
Mar 08 Javascript
uploader秒传图片到服务器完整代码
Apr 22 Javascript
js实现图片轮播效果学习笔记
Jul 26 Javascript
vue缓存的keepalive页面刷新数据的方法
Apr 23 Javascript
vue实现多组关键词对应高亮显示功能
Jul 25 Javascript
layui实现数据表格点击搜索功能
Mar 26 Javascript
如何用JS实现简单的数据监听
May 06 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
PHP 开发环境配置(Zend Server安装)
2010/04/28 PHP
PHP 查找字符串常用函数介绍
2012/06/07 PHP
php面向对象之反射功能与用法分析
2017/03/29 PHP
php无限级评论嵌套实现代码
2018/04/18 PHP
PHP钩子实现方法解析
2019/05/21 PHP
php中的钩子理解及应用实例分析
2019/08/30 PHP
JavaScript中的继承方式详解
2015/02/11 Javascript
在线所见即所得HTML编辑器的实现原理浅析
2015/04/25 Javascript
js中常用的Tab切换效果(推荐)
2016/08/30 Javascript
Js判断H5上下滑动方向及滑动到顶部和底部判断的示例代码
2017/11/15 Javascript
vue-cli扩展多模块打包的示例代码
2018/04/09 Javascript
Vue项目webpack打包部署到Tomcat刷新报404错误问题的解决方案
2018/05/15 Javascript
解决echarts的多个折现数据出现坐标和值对不上的问题
2018/12/28 Javascript
JS中注入eval, Function等系统函数截获动态代码
2019/04/03 Javascript
详解基于原生JS验证表单组件xy-form
2019/08/20 Javascript
解决微信小程序中的滚动穿透问题
2019/09/16 Javascript
vue.js中ref及$refs的使用方法解析
2019/10/08 Javascript
python结合shell查询google关键词排名的实现代码
2016/02/27 Python
利用aardio给python编写图形界面
2017/08/21 Python
python放大图片和画方格实现算法
2018/03/30 Python
CentOS 7 安装python3.7.1的方法及注意事项
2018/11/01 Python
FFrpc python客户端lib使用解析
2019/08/24 Python
Python2 与Python3的版本区别实例分析
2020/03/30 Python
CSS3中border-radius属性设定圆角的使用技巧
2016/05/10 HTML / CSS
一款利用纯css3实现的超炫3D表单的实例教程
2014/12/01 HTML / CSS
美国高品质个性化珠宝销售网站:Jewlr
2018/05/03 全球购物
理肤泉加拿大官网:La Roche-Posay加拿大
2018/07/06 全球购物
英国卫浴商店:Ergonomic Design
2019/09/22 全球购物
荣耀俄罗斯官网:HONOR俄罗斯
2020/10/31 全球购物
园长自我鉴定
2013/10/06 职场文书
财务专业大学生职业生涯规划范文
2013/12/30 职场文书
餐厅经理岗位职责范本
2014/02/17 职场文书
工会换届选举方案
2014/05/21 职场文书
质量负责人岗位职责
2015/02/15 职场文书
小学班主任工作总结2015
2015/04/07 职场文书
初中英语教师个人工作总结2015
2015/07/21 职场文书