浅析Vue 中的 render 函数


Posted in Javascript onFebruary 28, 2020

render函数是什么

简单的说,在vue中我们使用模板HTML语法组建页面的,使用render函数我们可以用js语言来构建DOM

因为vue是虚拟DOM,所以在拿到template模板时也要转译成VNode的函数,而用render函数构建DOM,vue就免去了转译的过程。

当使用render函数描述虚拟DOM时,vue提供一个函数,这个函数是就构建虚拟DOM所需要的工具。官网上给他起了个名字叫createElement。还有约定的简写叫h,

vm中有一个方法_c,也是这个函数的别名

先看官网对 createElement的介绍

// @returns {VNode}
createElement(
 // {String | Object | Function}
 // 一个 HTML 标签字符串,组件选项对象,或者
 // 解析上述任何一种的一个 async 异步函数,必要参数。
 'div',

 // {Object}
 // 一个包含模板相关属性的数据对象
 // 这样,您可以在 template 中使用这些属性。可选参数。
 {
  // (详情见下一节)
 },

 // {String | Array}
 // 子节点 (VNodes),由 `createElement()` 构建而成,
 // 或使用字符串来生成“文本节点”。可选参数。
 [
  '先写一些文字',
  createElement('h1', '一则头条'),
  createElement(MyComponent, {
   props: {
    someProp: 'foobar'
   }
  })
 ]
)

就是说createElement(params1,params2,params3)接受三个参数,每个参数的类型官方介绍已经说明

好了,开始今天的正文。

本文 GitHub https://github.com/qq44924588... 上已经收录,更多往期高赞文章的分类,也整理了很多我的文档,和教程资料。欢迎Star和完善,大家面试可以参照考点复习,希望我们一起有点东西。

我们知道 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 :class="{'is-red': isRed}">
  *   <p>这是一个 render 事例</p>
  *  </div>
  * </template>
  */
 // render 中的渲染结果与上面等价
 render(h) {
  return h('div', {
   'class': {
    'is-red': this.isRed
   }
  }, [
   h('p', '这是一个 render 事例')
  ])
 }
}

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

特殊属性

Slots 可以通过 this.$slots 作为 createElement() 节点的数组来访问插槽。

作用域插槽存储在 this.$scopedSlots[scope](props:object) 中,作为返回 createElement() 节点数组的函数。

代码部署后可能存在的BUG没法实时知道,事后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具 Fundebug 。

总结

到此这篇关于浅析Vue 中的 render 函数的文章就介绍到这了,更多相关Vue render 函数内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
改进UCHOME的记录发布,增强可访问性用户体验
Jan 17 Javascript
javascript中的onkeyup和onkeydown区别介绍
Apr 28 Javascript
jQuery插件formValidator自定义函数扩展功能实例详解
Nov 25 Javascript
url传递的参数值中包含&amp;时,url自动截断问题的解决方法
Aug 02 Javascript
js中获取jsp表单中radio类型的值简单实例
Aug 15 Javascript
JS数组返回去重后数据的方法解析
Jan 03 Javascript
BootstrapTable请求数据时设置超时(timeout)的方法
Jan 22 Javascript
JavaScript的继承实现小结
May 07 Javascript
VUE axios上传图片到七牛的实例代码
Jul 28 Javascript
vue中阻止click事件冒泡,防止触发另一个事件的方法
Feb 08 Javascript
angularJs select绑定的model取不到值的解决方法
Oct 08 Javascript
vue+koa2实现session、token登陆状态验证的示例
Aug 30 Javascript
微信小程序实现录制、试听、上传音频功能(带波形图)
Feb 27 #Javascript
基于Element的组件改造的树形选择器(树形下拉框)
Feb 27 #Javascript
js与jquery获取input输入框中的值实例讲解
Feb 27 #jQuery
javascript将扁平的数据转为树形结构的高效率算法
Feb 27 #Javascript
js实现无限层级树形数据结构(创新算法)
Feb 27 #Javascript
js实现树形数据转成扁平数据的方法示例
Feb 27 #Javascript
vue学习笔记之给组件绑定原生事件操作示例
Feb 27 #Javascript
You might like
php access 数据连接与读取保存编辑数据的实现代码
2010/05/12 PHP
php中http与https跨域共享session的解决方法
2014/12/20 PHP
WordPress开发中自定义菜单的相关PHP函数使用简介
2016/01/05 PHP
php异步:在php中使用fsockopen curl实现类似异步处理的功能方法
2016/12/10 PHP
PHP jQuery+Ajax结合写批量删除功能
2017/05/19 PHP
php删除一个路径下的所有文件夹和文件的方法
2018/02/07 PHP
针对thinkPHP5框架存储过程bug重写的存储过程扩展类完整实例
2018/06/16 PHP
PHP如何通过表单直接提交大文件详解
2019/01/08 PHP
浅谈php使用curl模拟多线程发送请求
2019/03/08 PHP
javascript中的几个运算符
2007/06/29 Javascript
Div Select挡住的解决办法
2008/08/07 Javascript
Array, Array Constructor, for in loop, typeof, instanceOf
2011/09/13 Javascript
jquery仿京东导航/仿淘宝商城左侧分类导航下拉菜单效果
2013/04/24 Javascript
js检测浏览器版本、核心、是否移动端示例
2014/04/24 Javascript
手机端转盘抽奖代码分享
2015/09/10 Javascript
jquery获取复选框checkbox的值实现方法
2016/05/30 Javascript
浅析JavaScript中命名空间namespace模式
2016/06/22 Javascript
jQuery实现定位滚动条位置
2016/08/05 Javascript
vue基础之模板和过滤器用法实例分析
2019/03/12 Javascript
node.js中fs文件系统模块的使用方法实例详解
2020/02/13 Javascript
JS常用排序方法实例代码解析
2020/03/03 Javascript
使用原生JS实现滚轮翻页效果的示例代码
2020/05/31 Javascript
vue同个按钮控制展开和折叠同个事件操作
2020/07/29 Javascript
[14:25]教你分分钟做大人:主宰(HEROS)
2014/12/08 DOTA
python基于multiprocessing的多进程创建方法
2015/06/04 Python
python实现判断数组是否包含指定元素的方法
2015/07/15 Python
python栈的基本定义与使用方法示例【初始化、赋值、入栈、出栈等】
2019/10/24 Python
Python lxml模块的基本使用方法分析
2019/12/21 Python
Django 解决开发自定义抛出异常的问题
2020/05/21 Python
html5实现微信打飞机游戏
2014/03/27 HTML / CSS
详解Canvas实用库Fabric.js使用手册
2019/01/07 HTML / CSS
公司企业表扬信
2014/01/11 职场文书
岗位职责的构建方法
2014/02/01 职场文书
社区优秀志愿者材料
2014/02/02 职场文书
写自荐信的注意事项
2014/03/09 职场文书
春风行动实施方案
2014/03/28 职场文书