首页 > 编程 > JavaScript > 正文

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

2019-11-19 15:36:45
字体:
来源:转载
供稿:网友

本文介绍了如何理解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>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持武林网。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表