做者:Joshua Bemenderfer
译者:前端小智
来源:vuejsbook.com
点赞再看,养成习惯本文
GitHub
https://github.com/qq44924588... 上已经收录,更多往期高赞文章的分类,也整理了不少个人文档,和教程资料。欢迎Star和完善,你们面试能够参照考点复习,但愿咱们一块儿有点东西。前端
咱们知道 Vue 模板是很是强大的,基本能够完成咱们平常开发的全部任务。可是,有一些用例,如基于输入或插槽值建立动态组件方式,render
函数会比模板完成的更好也更出色。vue
用过 React 开发的人对 render
函数应该很是熟悉,由于React组件经过 JSX和 render 函数来构建的。 尽管Vue render
函数也能够用JSX编写,但在这里咱们使用原生 JS方式,由于这样,咱们能够更轻松地了解Vue组件系统的一些基础。git
值得注意的是,Vue 的模板实际上在编译时也是会先解析成 render
函数表示方式。 模板只是在render
函数之上提供了一个方便且熟悉的语法糖。 尽管 render
函数更强大,但render
函数可读性不好,相对用的也比较少了。github
带有 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 事例') ]) } }
Vue 模板具备各类便捷功能,以便向模板添加基本逻辑和绑定功能,如 v-if
、v-for
、v-moel
指令等。 在render
函数中是没法使用这些指令的。 取而代之的是以纯 JS 来实现,对于大多数指令而言,这也是比较简单的。数组
v-if
用纯 JS 实现很简单,只需围绕createElement
调用使用 if(expr)
语句便可。微信
v-for
可使用for-of
,Array.map
,Array.filter
等的JS方法中的任何一种来实现。咱们能够经过很是有趣的方式将它们组合在一块儿,以实现过滤或状态切片,而无需计算属性。dom
例如,有如下 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
只是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 } } }) }
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' } }); }
对事件处理程也是直接添加到元素定义中 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。
原文:https://vuejsbook.com/introdu...
文章每周持续更新,能够微信搜索「 大迁世界 」第一时间阅读和催更(比博客早一到两篇哟),本文 GitHub https://github.com/qq449245884/xiaozhi 已经收录,整理了不少个人文档,欢迎Star和完善,你们面试能够参照考点复习,另外关注公众号,后台回复福利,便可看到福利,你懂的。