如何理解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 相关文章推荐
基于JQuery的类似新浪微博展示信息效果的代码
Jul 23 Javascript
JS实现下拉框的动态添加(附效果)
Apr 03 Javascript
页面刷新时记住滚动条的位置jquery代码
Jun 17 Javascript
window.location 对象所包含的属性
Oct 10 Javascript
javascript实现拖动元素交换位置
Nov 29 Javascript
浅析Bootstrip的select控件绑定数据的问题
May 10 Javascript
jQuery实现微信长按识别二维码功能
Aug 26 Javascript
AngularJS equal比较对象实例详解
Sep 14 Javascript
js,jq,css多方面实现简易下拉菜单功能
May 13 Javascript
微信小程序 input表单与redio及下拉列表的使用实例
Sep 20 Javascript
实用的Vue开发技巧
May 30 Javascript
JS实现表单中点击小眼睛显示隐藏密码框中的密码
Apr 13 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代码优化技巧小结
2015/09/29 PHP
windows7配置Nginx+php+mysql的详细教程
2016/09/04 PHP
编辑浪子版表单验证类
2007/05/12 Javascript
Add a Formatted Table to a Word Document
2007/06/15 Javascript
多浏览器支持的右下角浮动窗口
2010/04/01 Javascript
Javascript学习笔记一 之 数据类型
2010/12/15 Javascript
完美解决AJAX跨域问题
2013/11/01 Javascript
JS网页图片按比例自适应缩放实现方法
2014/01/15 Javascript
json的定义、标准格式及json字符串检验
2014/05/11 Javascript
Bootstrap轮播插件中图片变形的终极解决方案 使用jqthumb.js
2016/07/10 Javascript
jQuery实现的兼容性浮动层示例
2016/08/02 Javascript
Vue中 v-if 和v-else-if页面加载出现闪现的问题及解决方法
2018/10/12 Javascript
解决node-sass偶尔安装失败的方法小结
2018/12/05 Javascript
JavaScript栈和队列相关操作与实现方法详解
2018/12/07 Javascript
微信小程序云开发修改云数据库中的数据方法
2019/05/18 Javascript
解决VantUI popup 弹窗不弹出或无蒙层的问题
2020/11/03 Javascript
js实现弹幕墙效果
2020/12/10 Javascript
java直接调用python脚本的例子
2014/02/16 Python
pyenv命令管理多个Python版本
2017/03/26 Python
从CentOS安装完成到生成词云python的实例
2017/12/01 Python
numpy自动生成数组详解
2017/12/15 Python
基于Python中numpy数组的合并实例讲解
2018/04/04 Python
pandas实现选取特定索引的行
2018/04/20 Python
python3.4实现邮件发送功能
2018/05/28 Python
python中的tcp示例详解
2018/12/09 Python
Pyqt5自适应布局实例
2019/12/13 Python
聊聊python中的异常嵌套
2020/09/01 Python
英国领先的男士美容护发用品公司:Mankind
2016/08/31 全球购物
HUGO BOSS美国官方网上商店:世界知名奢侈品牌
2017/08/04 全球购物
Armor Lux法国官方网站:水手服装、成衣和内衣
2020/05/26 全球购物
JAVA代码查错题
2014/10/10 面试题
法院实习人员自我鉴定
2013/09/26 职场文书
2014年社区个人工作总结
2014/12/02 职场文书
长城导游词
2015/01/30 职场文书
撤诉状格式范本
2015/05/19 职场文书
行为规范主题班会
2015/08/13 职场文书