欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-05-14 19:29:40
本文介绍了如何理解vue的render函数的具体用法,分享给大家,具体如下: 第一个参数(必须) - {string | object | function}...

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

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