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

vue渲染方式render和template的区别

程序员文章站 2022-04-09 16:06:30
render函数详解vue中的render函数中有一个参数,这个参数是一个函数通常我们叫做h。其实这个h叫做createelement。render函数将createelement的返回值放到了htm...

render函数详解

vue中的render函数中有一个参数,这个参数是一个函数通常我们叫做h。其实这个h叫做createelement。render函数将createelement的返回值放到了html中

createelement这个函数中有3个参数

第一个参数(必要参数):主要用于提供dom的html内容,类型可以是字符串、对象或函数

第二个参数(类型是对象,可选):用于设置这个dom的一些样式、属性、传的组件的参数、绑定事件之类

第三个参数(类型是数组,数组元素类型是vnode,可选):主要是指该结点下还有其他结点,用于设置分发的内容,包括新增的其他组件。注意,组件树中的所有vnode必须是唯一的

// @return {vnode}
createelement(
 // {string | object | function}
 // 一个html标签字符串,组件选项对象,或者一个返回值类型为string/object的函数。该参数是必须的
 'div',

 // {object}
 // 一个包含模板相关属性的数据对象,这样我们可以在template中使用这些属性,该参数是可选的。
{
   attrs: {
    name: headingid,
    href: '#'+headingid
  },
   style: {
    color: 'red',
    fontsize: '20px'
  },
   'class': {
    foo: true,
    bar: false
   },
   // dom属性
   domprops: {
     innerhtml: 'baz'
   },
   // 组件props
    props: {
     myprop: 'bar'
   },
    // 事件监听基于 'on'
    // 所以不再支持如 'v-on:keyup.enter' 修饰语
    // 需要手动匹配 keycode 
    on: {
      click: function(event) {
        event.preventdefault();
        console.log(111);
     }
    }
 }

 // {string | array}
 // 子节点(vnodes)由 createelement() 构建而成。可选参数
 // 或简单的使用字符串来生成的 "文本节点"。
[
  'xxxx',
  createelement('h1', '一则头条'),
  createelement(mycomponent, {
   props: {
    someprop: 'xxx'
  }
 }),
  this.$slots.default
]
)

什么时候用render函数?

假设我们要封装一套按钮组件,按钮有四个样式(success、error、warning、default)。首先,你可能会想到如下实现

<template>
<divclass="btn btn-success"v-if="type === 'success'">{{ text }}</div>
<divclass="btn btn-danger"v-else-if="type === 'danger'">{{ text }}</div>
<divclass="btn btn-warning"v-else-if="type === 'warning'">{{ text }}</div>
</template>

虽然我们这样实现没有问题,但是如果现在有十几个样式的情况下我们就需要写n多个判断,如果遇到了这种情况我们就可以选择使用render函数。

其实简单的来说就是template适合简单的组件封装,然后render函数适合复杂的组件封装

<script>
vue.component("a-button", {
    props: {
      type: {
        type: string,
        default: 'default'
     },
      text: {
        type: string,
        default: '按钮'
     }
   },
    computed: {
      tag() {
        switch(this.type) {
          case'success':
            return1;
          case'danger':
            return2;
          case'warning':
            return3;
          default:
            return1;
       }
     }
   },
    render(h) {
      returnh('div', {
        class: {
          btn: true,
          'btn-success': this.type==='success',
          'btn-danger': this.type==='danger',
          'btn-warning': this.type==='warning'
       },
        domprops: {
          //innertext: this.text,
       },
        on: {
          click: this.handleclick
       }
     },
      this.$slots.default
     );
   },
    methods: {
      handleclick() {
        console.log('-----------------------');
        console.log('li');
     }
   }
 })

  letvm=newvue({
    el: "#app"
 })
</script>

template与render函数对比

template----html的方式做渲染
render----js的方式做渲染

render(提供)是一种编译方式
render里有一个函数h,这个h的作用是将单文件组件进行虚拟dom的创建,然后再通过render进行解析。
h就是createelement()方法:createelement(标签名称,属性配置,children)

template也是一种编译方式,但是template最终还是要通过render的方式再次进行编译。

区别:
        1、render渲染方式可以让我们将js发挥到极致,因为render的方式其实是通过createelement()进行虚拟dom的创建。逻辑性比较强,适合复杂的组件封装。
        2、template是类似于html一样的模板来进行组件的封装。
        3、render的性能比template的性能好很多
        4、render函数优先级大于template

案例一:template和render的方式渲染标题标签:

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>document</title>
</head>
<body>
  <div id="app">
    <h-title level="1">标题</h-title>
    <h-title level="2">标题</h-title>
    <h-title level="3">标题</h-title>
  </div>
  <script src="https://unpkg.com/vue/dist/vue.js"></script>
  <script>
    vue.component("h-title",{
      /*  template渲染  */
      // template:`
      //   <div>
      //     <h1 v-if="level==1"><slot></slot></h1>  
      //     <h2 v-else-if="level==2"><slot></slot></h2>  
      //     <h3 v-else-if="level==3"><slot></slot></h3>  
      //   </div>
      // `,
      
      /*  render渲染  */
      render:function(h){
        // createelement(标签名称,属性配置,children)
        return h("h"+this.level,
          {
            attrs:{
              "data-id":10
            }
          },
          // 相当于<slot></slot>标签接收
          this.$slots.default
        )
      },
      props:{
        level:{
          type:string
        }
      }
    });
    let vm=new vue({
      el:"#app"
    });
  </script>
</body>
</html>

案例二:render方式模拟button:

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>document</title>
  <style>
    *{margin: 0;padding: 0;}
    .btn{
      width: 80px;
      line-height: 40px;
      text-align: center;
      color:#fff;
      border-radius: 5px;
      background-color: #ccc;
    }
    .success{background-color: green;}
    .error{background-color: red;}
    .info{background-color: pink;}
  </style>
</head>
<body>
  <div id="app">
    <wql-button type="success">成功</wql-button>
    <wql-button type="info">提示</wql-button>
    <wql-button type="error">报错</wql-button>
    <wql-button>默认</wql-button>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <script>
    vue.component("wql-button",{
      render:function(h){
        return h("div",{
          class:{
            btn:true,
            success:this.type=="success",
            error:this.type=="error",
            info:this.type=="info"
          }
        },this.$slots.default);
      },
      props:{
        type:{
          type:string
        }
      }
    });
    let vm=new vue({
      el:"#app"
    });
  </script>
</body>
</html>

到此这篇关于vue渲染方式render和template的区别的文章就介绍到这了,更多相关vue render template区别内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!