zoukankan      html  css  js  c++  java
  • 解Vue 中 render 函数有点意思

    我们知道 vue 模板是非常强大的,基本可以完成我们日常开发的所有任务。但是,有一些用例,如基于输入或插槽值创建动态组件方式,render 函数会比模板完成的更好也更出色。

    用过 react 开发的人对 render 函数应该非常熟悉,因为react组件通过 jsX和 render 函数来构建的。 尽管vue render 函数也可以用jsX编写,但在这里我们使用原生 JS方式,因为这样,我们可以更轻松地了解Vue组件系统的一些基础。

    值得注意的是,Vue 的模板实际上在编译时也是会先解析成 render 函数表示方式。 模板只是在render 函数之上提供了一个方便且熟悉的语法糖。 尽管 render 函数更强大,但render函数可读性很差,相对用的也比较少了。

    创建组件

    带有 render 函数的组件没有template标记或属性。 相反,该组件定义了一个了名为render的函数,该函数接收一个reateElement(renderElement: String | Component, definition: Object, children: String | Array)参数(由于某种原因,通常别名为h,归咎于JSX)并返回使用该函数创建的元素,其他一切保持不变,来看看事例:

    export default {
      data() {
        return {
          isRed: true
        }
      },
    
      /*
       * <template>
       *   <div :is-red': isRed}">
       *     <p>这是一个 render 事例</p>
       *   </div>
       * </template>
       */
      // render 中的渲染结果与上面等价
      render(h) {
        return h('div', {
          'class': {
            'is-red': this.isRed
          }
        }, [
          h('p', '这是一个 render 事例')
        ])
      }
    }

    电脑刺绣绣花厂 http://www.szhdn.com 广州品牌设计公司https://www.houdianzi.com

    render 函数中如何表示指令

    Vue 模板具有各种便捷功能,以便向模板添加基本逻辑和绑定功能,如 v-if、v-for、v-moel指令等。 在render函数中是无法使用这些指令的。 取而代之的是以纯 JS 来实现,对于大多数指令而言,这也是比较简单的。

    v-if

    v-if 用纯 JS 实现很简单,只需围绕createElement调用使用 if(expr)语句即可。

    v-for

    v-for可以使用for-of,Array.map,Array.filter等的JS方法中的任何一种来实现。我们可以通过非常有趣的方式将它们组合在一起,以实现过滤或状态切片,而无需计算属性。

    例如,有以下 Vue 的模板代码

    <template>
      <ul>
        <li v-for="pea of pod">
          
        </li>
      </ul>
    </template>
    

    可以用下面的 render 函数来实现上面的效果:

    render(h) {
      return h('ul', this.pod.map(pea => h('li', pea.name)));
    }
    

    v-model

    我们知道,v-model只是bind属性与value的语法糖,并在触发input事件时设置数据属性。但是,在render函数没有这样的简写,我们需要自己实现。

    假设,在 Vue 中,我们有如下的结构:

    <template>
      <input v-model='myBoundProperty'/>
    </template>
    

    上面代码等价于:

    <template>
      <input :value="myBoundProperty" @input="myBoundProperty = $event.target.value"/>
    </template>
    

    在 render 函数中可以用下面方式来实现上面的代码:

    render(h) {
      return h('input', {
        domProps: {
          value: this.myBoundProperty
        },
        on: {
          input: e => {
            this.myBoundProperty = e.target.value
          }
        }
      })
    }
    

    v-bind

    attribute和property 这两种类型的绑定被放在元素定义中,如arttrs、props和domProps( value 和innerhtml之类的东西)。

    render(h) {
      return h('div', {
        attrs: {
          // <div :id="myCustomId">
          id: this.myCustomId
        },
    
        props: {
          // <div :someProp="someonePutSomethingHere">
          someProp: this.someonePutSomethingHere
        },
    
        domProps: {
           // <div :value="somethingElse">
          value: this.somethingElse
        }
      });
    }
    

    需要注意的是,对于 class和style的绑定是直接在定义的根进行处理,而不是作为attrs,props或domProps处理。

    render(h) {
      return h('div', {
        // “类”是JS中的保留关键字,因此必须引用它。
        'class': {
          myClass: true,
          theirClass: false
        },
    
        style: {
          backgroundColor: 'green'
        }
      });
    }
    

    v-on

    对事件处理程也是直接添加到元素定义中 on 定义

    render(h) {
      return h('div', {
        on: {
          click(e) {
            console.log('I got clickeded!')
          }
        }
      });
    }
    

    事件的修饰符可以在处理程序内部实现:

    • .stop -> e.stopPropagation()
    • .prevent -> e.preventDefault()
    • .self -> if (e.target !== e.currentTarget) return

    键盘修饰符

    • .[TARGET_KEY_CODE] -> if (event.keyCode !== TARGET_KEY_CODE) return
    • .[MODIFIER] -> if (!event.MODIFIERKey) return
  • 相关阅读:
    react native android9 axios network error
    .NET Core3.1升级.NET5 oracle连接报错
    asp.net mvc api swagger 配置
    ASP.NET Core3.1 中使用MongoDB基本操作
    基于.NET Core3.1的SQLiteHelper增删改帮助类
    linux离线安装gcc 和g++
    简单验证两次密码输入是否相同
    循环结构-回文数
    《暴走大事件》为80、90后正名
    循环结构-判断一个数是否为完全数(C语言)
  • 原文地址:https://www.cnblogs.com/xiaonian8/p/13825938.html
Copyright © 2011-2022 走看看