• vue render函数初级学习使用


    render函数的基本使用

    render函数可以接受三个参数,其中第一个参数是必填的可以是String | Object | Function
    比如说直接写一个div的字符串

    render(createElement) {
        return createElement("div")
    }
    

    上边的代码你在审查代码的时候你会发现他渲染出来了一个div的标签,或者你输入了一个你不认识的字符串,他也会渲染成一个html标签比如说

    render(createElement) {
        return createElement("xxx")
    }
    

    他会渲染出一个XXX的标签

    所以如果render函数的第一个参数是String的话,表示的是HTML 标签

    另外这个参数可以是一个组件的名字比如说我们需要渲染一个element的input组件

    render(createElement) {
        return createElement("el-input")
    }
    

    上边的代码中你会得到一个el-input的组件,其实本来的初衷就是看到之前项目中用到的大表单千篇一律,想改造一下,感觉用template太累赘所以才学习的render,render函数并不能全部替代template,你需要在合适的场景下选择使用它,比如element源码中tag标签

     render(h) {
       const classes = [ 'el-tag', this.type ? `el-tag--${this.type}` : '',
         this.tagSize ? `el-tag--${this.tagSize}` : '',
         {'is-hit': this.hit},
         {'is-circle': this.circle}
       ];
       const tagEl = (<span class={classes} style={{backgroundColor: this.color}} on-click={this.handleClick}>
         { this.$slots.default }
         {
           this.closable && <i class={{'el-tag__close': !this.circle, 'el-icon-close': !this.circle }}on-click={this.handleClose}></i>
         }
       </span>);
       
       return this.disableTransitions ? tagEl : <transition name="el-zoom-in-center">{ tagEl }</transition>;
     }
    

    这个组件中 他们用的就是render

    在封装组件时,不知道到底需要一个什么样的标签组件。如果去加一堆的判断的话,代码量太大,但用render()函数来实现就很简单。

    待会我们再来说一个不适合用render函数的地方

    上边element的源码中可以看到 render函数中 是允许使用jsx语法的,其实jsx语法说白了,我感觉他就是一个语法糖,它会被编译成一个树状的json树,里边有被渲染出来的标签所需要的属性,是一个对象

    最后你可以选择传入一个方法 把你的json数据return出去比如说

     fun() {
         return {template: '<div></div>'}
     };
     return createElement(fun());
    

    render函数的第二个和第三个参数是可选的,如果你们动手去使用一下上边的代码你们会发现,如果传入的是字符串的话,被渲染的这个标签除了一个标签以外什么都没有,那么第二个参数就是用来定义这个标签上边的属性的

    举例说明比较常见的几个属性classstyle,attrs,domPropson

    • class style 这俩不用解释

    • attrs 这个可以定义标签上的属性 比如说id啊 src啊 placeholder什么什么的

    • domProps 这个是原生的一些属性 比如说value 但是这个是根据你渲染的标签有关的,加入你渲染了一个el-input的话 加value是不起作用的

    • on 标签的原生方法

    举个例子

    
    
    //高级搜索搜索图标按钮样式
     let iconSearchClass = ["search-icon","icon-sousuo", "iconfont"];
    // 等待渲染的原生属性
     let componentProps = {};
    // 高级搜索的input事件
     let selectInputOn={
       input:this.change,
       keyup:this.keyup,
       focus:this.focus,
       blur:this.blur
     }
     
      // 父组件属性存储
     for (const key in this.$attrs) {
       componentProps[key] = this.$attrs[key];
     }
     // 搜索图标
     let searchIcon =createElement('div',{
       class: iconSearchClass
     })
     
     // 渲染input
     let searchInput = createElement("input", {
       props: componentProps,
       on: selectInputOn
     });  
    

    上边是我之前写的一个小demo,还有一些其他的属性比如说

    • props 组件的props

    • directives 自定义指令

    • scopedSlots 作用域插槽

    还有一些不常用的属性,具体的请参考vue官网的vue属性那一篇

    另外 在render函数里边是没有v-for v-if v-model v-show 什么什么的这些指令的
    可以通过自己封装函数达到相应的效果,这篇博客先做一个简单的介绍,下一篇我会把所有的属性做一个demo分享出来

    第三个参数可以给上边那个标签里边添加东西 比如

    <div>
        <div></div>
    </div>
    

    如果你想实现这样的效果 你可以在第三个参数里边再写一个div的字符串,第三个参数正常来讲接收的是一个字符串或者一个数组,一般数组用的是比较多的,我之前的用法是数组里边放的是一个返回一个标签的变量,代码如下

    
    
     // 父组件属性存储
     for (const key in this.$attrs) {
       componentProps[key] = this.$attrs[key];
     }
     // 搜索图标
     let searchIcon =createElement('div',{
       class: iconSearchClass
     })
     
     // 渲染input
     let searchInput = createElement("input", {
       props: componentProps,
       on: selectInputOn
     });
    
     // 高级搜索图标按钮
     let iconBtn = createElement("div", {
       class: iconBtnClass
     });
    
     // 高级搜索图标按钮盒子
     let iconBtnBox = createElement(
       "div",
       {
         class: iconBtnBoxClass
       },
       [iconBtn]
     );
     
     // 高级搜索input栏
     let inputRow = createElement(
       "div",
       {
         class: searchBoxClass
       },
       [searchIcon,searchInput, iconBtnBox]
     );
    
    
    // 渲染高级搜索
     return createElement(
       "div",
       {
         attrs: {
           id: "advancedSearch"
         }
       },
       [inputRow, (this.listShow||this.notDestruc)&&searchSlotBox]
     );
     
    

    大概就是这个意思 代码就不全沾出来了,有充字数的嫌疑,同时也可以看到,这是一个没有必要使用render函数的地方。。。。不灵活 而且我也没有使用jsx,使用jsx可能还好些 被我们组长一顿喷 没有后续了

    我这个demo巴拉巴拉写了100多行 实际生成了大概15行html包括一些事件,并不是说render不好,是要提醒大家不要为了用而去用,要找到适合的地方再去用

    render函数中插槽

    • 插槽用法
    
    
    render(createElement) {
      // 等同于:<div><slot></slot></div>
      return createElement('div', this.$slots.default)
    }
    
    
    
    • 插槽传值
    
    
    props: ['message'],
    render(createElement) {
      // 等同于`<div><slot :text="message"></slot></div>`
      return createElement('div', [
        this.$scopedSlots.default({
          text: this.message
        })
      ])
    }
    
    
    

    放一个双向数据绑定demo

    
    
      render: function(createElement) {
        var self = this;
        return createElement("input", {
          domProps: {
            value: self.name
          },
          on: {
            input: function(event) {
              self.$emit("input", event.target.value);
            }
          }
        });
      },
    
    

    外边组件

    
    
        <template>
            <demo :value='value' @input="demoInput"></demo>
            {{value}}
        </template>
        export default {
        data(){
            return{
             value:null,//demo  
            }
        },
        methods:{
            demoInput(val){
              this.value=val
            },
        }
    

    效果图

    今天说了一下render的基本使用 ,下一篇会分享一个render函数的demo和其他的用法,如有不足之处,希望批评指正

  • 相关阅读:
    Bootstrap-CSS:按钮
    Bootstrap-CSS:表单
    质检总局-版权局
    java实现第二届蓝桥杯地铁换乘(C++)
    java实现第二届蓝桥杯地铁换乘(C++)
    java实现第二届蓝桥杯地铁换乘(C++)
    java实现第二届蓝桥杯地铁换乘(C++)
    java实现第二届蓝桥杯地铁换乘(C++)
    java实现第二届蓝桥杯最小公倍数(c++)
    java实现第二届蓝桥杯最小公倍数(c++)
  • 原文地址:https://www.cnblogs.com/netUserAdd/p/10920138.html
Copyright © 2020-2023  润新知