vue之render基本书写方法
Vue 推荐在绝大多数情况下使用 template 来创建你的 HTML。然而在一些场景中,你真的需要 JavaScript 的完全编程的能力,这就是 render 函数,它比 template 更接近编译器。
render 基本写法
export default {
name: 'renderTest',
data() {},
render: (createElement) => {
return createElement(tag, data, context)
},
props: {},
methods: {},
created () {}
...
}
Vue 通过建立一个虚拟 DOM 对真实 DOM 发生的变化保持追踪。
render函数提供了一个参数createElement
(可以简写为h
), 用来生成DOM, 其有三个参数:
- 第一个参数: {String | Object | Function}, 必要参数,一个 HTML 标签字符串,组件选项对象,或者一个返回值类型为 String/Object 的函数
- 第二个参数: {Object},可选参数,一个包含模板相关属性的数据对象,这样,您可以在 template 中使用这些属性。
- 第三个参数: {String | Array},可选参数, 子节点 (VNodes),由
createElement()
构建而成, 或使用字符串来生成“文本节点”。
数据对象详解
{
// 和`v-bind:class`一样的 API
'class': {
foo: true,
bar: false
},
// 和`v-bind:style`一样的 API
style: {
color: 'red',
fontSize: '14px'
},
// 正常的 HTML 特性
attrs: {
id: 'foo'
},
// 组件 props
props: {
myProp: 'bar'
},
// DOM 属性
domProps: {
innerHTML: 'baz'
},
// 事件监听器基于 `on`
// 所以不再支持如 `v-on:keyup.enter` 修饰器
// 需要手动匹配 keyCode。
on: {
click: this.clickHandler
},
// 仅对于组件,用于监听原生事件,而不是组件内部使用 `vm.$emit` 触发的事件。
nativeOn: {
click: this.nativeClickHandler
},
// 自定义指令。注意,您无法对绑定中的 `oldValue` 赋值
// Vue 会为您持续追踪
directives: [
{
name: 'my-custom-directive',
value: '2',
expression: '1 + 1',
arg: 'foo',
modifiers: {
bar: true
}
}
],
// Scoped slots in the form of
// { name: props => VNode | Array<VNode> }
scopedSlots: {
default: props => createElement('span', props.text)
},
// 如果组件是其他组件的子组件,需为插槽指定名称
slot: 'name-of-slot',
// 其他特殊顶层属性
key: 'myKey',
ref: 'myRef'
}
v-if 、 v-for 与 v-model
render 函数中没有与v-if 、 v-for 、v-model 相应的 api, 必须自己来实现相应的逻辑
render: function (createElement) {
if (this.items.length) {
return createElement('ul', this.items.map(function (item) {
return createElement('li', item)
}))
} else {
return createElement('p', 'No items found.')
}
}
完整示例
renderTest组件
export default {
name: 'renderTest',
data() {
return {
}
},
render: function (createElement) {
return createElement(
'h' + this.level,
{
on: {
click: this.clickHandler
}
},
[
createElement('a', {
attrs: {
href: '##'
}
}, this.$slots.default)
]
)
},
props: {
level: {
type: Number,
required: true
}
},
methods: {
clickHandler () {}
}
}
使用组件
<renderTest :level="1">
<button> Hello world!</button>
</renderTest>
组件中自定义render(函数式组件)
render组件
export default {
name: 'renderTest',
functional: true,
props: {
render: Function,
item: String,
index: Number
},
render: (h, ctx) => {
const params = {
item: ctx.props.item,
index: ctx.props.index
}
return ctx.props.render(h, params)
}
}
我们将组件记为 functional,这意味它无状态(没有 data),无实例(没有 this 上下文)。
在添加 functional: true 之后,组件的 render 函数之间将增加 ctx 参数
组件需要的一切都是通过 ctx 传递,包括:
- props: 提供 props 的对象
- children: VNode 子节点的数组
- slots: slots 对象
- data: 传递给组件的 data 对象
- parent: 对父组件的引用
list组件
<template>
<ul class="bs-list left" style="width:200px;">
<li v-for="(item, i) in listDate" class="list-item" :key="i">
<span>{{item}}</span>
<renderTest v-if="renderfun" :item="item" :index="i" :render="renderfun"></renderTest>
</li>
</ul>
</template>
<script>
import renderTest from './renderTest.js'
export default {
name: 'lists',
components: { renderTest },
props: {
listDate: {
type: Array
},
renderfun: {
type: Function,
default() {
return () => false
}
}
}
}
</script>
使用组件
<template>
<div class="text">
<lists :listDate="listDate" :renderfun="renderfun"></lists>
</div>
</template>
<script>
import lists from './lists.vue'
export default {
name: 'text',
components: { lists },
data() {
return {
listDate: [ 'list item 1', 'list item 2', 'list item 3', 'list item 4', 'list item 5' ],
renderfun: (h, ctx) => {
return h('div', {
style: {display: 'inline-block', float: 'right'}
}, [
h('button', {
class: ['btn-primary'],
on: {
click: () => {
this.listDate.splice(ctx.index, 1)
}
}
}, '删除')
])
}
}
}
}
</script>
JSX使用
安装babel依赖
npm install babel-plugin-syntax-jsx babel-plugin-transform-vue-jsx babel-helper-vue-jsx-merge-props babel-preset-env --save-dev
.babelrc 文件配置
{
"presets": ["env"],
"plugins": ["transform-vue-jsx"]
}
书写格式
render (h) {
return (
<div
// 普通的属性
id="foo"
// DOM 属性,添加前缀`domProps`
domPropsInnerHTML="bar"
// 事件监听,添加前缀 `on` or `nativeOn`
onClick={this.clickHandler}
nativeOnClick={this.nativeClickHandler}
// 其他属性
class={{ foo: true, bar: false }}
style={{ color: 'red', fontSize: '14px' }}
key="key"
ref="ref"
slot="slot">
</div>
)
}
实例
export default {
name: 'renderJSX',
data() {
return {
num: 1
}
},
render() {
const data = {
class: ['b', 'c']
}
return (<div class = 'div'>
<span>123</span>
<button onClick={this.clickHandler} class='btn-primary'>btn</button>
<span class='a' {...data}>{this.num}</span>
</div>)
},
props: {
level: {
type: Number
}
},
methods: {
clickHandler() {
this.num++
console.log('clickHandler')
}
},
created() {}
}
https://vuefe.cn/v2/guide/render-function.html
https://github.com/vuejs/babel-plugin-transform-vue-jsx
vue之render基本书写方法的更多相关文章
- Vue2.x源码学习笔记-Vue实例的属性和方法整理
还是先从浏览器直观的感受下实例属性和方法. 实例属性: 对应解释如下: vm._uid // 自增的id vm._isVue // 标示是vue对象,避免被observe vm._renderProx ...
- 关于Vue的Render的讲解
首先我们传统的对于DOM的操作基本上都是通过js直接的获取一个节点,然后对DOM进行增加或者是删除.而Vue的Render这个函数是通过js虚拟的添加dom节点,然后虚拟的添加到html节点上去. 算 ...
- vue插件开发的两种方法:以通知插件toastr为例
方法一: 1.写插件: 在 src 文件夹下面建 lib 文件夹用于存放插件,lib 文件夹下再建toastr文件夹,在toastr文件夹下新建 toastr.js 和 toastr.vue两个文件. ...
- Vue(十二)vue实例的属性和方法
vue实例的属性和方法 1. 属性 vm.$el vm.$data vm.$options vm.$refs <!DOCTYPE html> <html lang="en& ...
- 在Vue中关闭Eslint 的方法
在vue项目中关闭ESLint方法:找到 webpack.base.conf.js 将这些代码注释掉, { test: /\.(js|vue)$/, loader: 'eslint-loader', ...
- vue解决遮罩层滚动方法
vue 遮罩层阻止默认滚动事件 在写移动端页面的时候,弹出遮罩层后,我们仍然可以滚动页面. vue中提供 @touchmove.prevent 方法可以完美解决这个问题 <div class=& ...
- vue实例的属性和方法
vue实例的属性和方法 1. 属性 vm.$el #指定要绑定的元素 vm.$data #Vue 实例的数据对象 vm.$options #获取自定义属性的值 new Vue({ customOpti ...
- Vue把父组件的方法传递给子组件调用(评论列表例子)
Vue把父组件的方法传递给子组件调用(评论列表例子) 效果展示: 相关Html: <!DOCTYPE html> <html lang="en"> < ...
- html select options & vue h render
html select options & vue h render https://developer.mozilla.org/en-US/docs/Web/HTML/Element/opt ...
随机推荐
- matlab文件读写处理实例(一)——不规则文件读取
数据: A) Title: Income Data B) Relevant Information: Marketing Database. Source: Impact Resources, Inc ...
- jenkins安装配置[二]
标签(linux): jenkins 笔者Q:972581034 交流群:605799367.有任何疑问可与笔者或加群交流 安装依赖,如果本机已有java环境可跳过 yum install java- ...
- 开发JQuery插件(转)
教你开发jQuery插件(转) 阅读目录 基本方法 支持链式调用 让插件接收参数 面向对象的插件开发 关于命名空间 关于变量定义及命名 压缩的好处 工具 GitHub Service Hook 原 ...
- typedef如何显示变量类型名
dsa typedef unsigned long int NUM; typedef unsigned short int Data; //为已经存在的类型起一个别名 //1.定义一个变量 unsig ...
- [JavaScript]自执行函数
最近在接触mui的时候,遇到了一段代码: (function($, doc) { $.init({ statusBarBackground: '#f7f7f7' }); $.plusReady(fun ...
- Python随笔,day1
#python中不存在单个字符的运算,只有字符串函数 >>> s="www.google.com" >>> s 'www.google.com' ...
- Spring 当 @PathVariable 遇上 【. # /】等特殊字符
@PathVariable注解应该不是新鲜东西了Spring3.0就开始有了 URL中通过加占位符把参数传向后台 举个栗子,如下比较要说的内容比较简单就大概齐的写一下 画面侧 $.ajax({ typ ...
- jupyter扩展插件Nbextensions使用
本节主要解释jupyter中各种插件 原创文章,转载请务必注明原作者出处:http://www.cnblogs.com/cloud-ken/p/7401534.html Exercise Exerci ...
- python中的线程之semaphore信号量
semaphore是一个内置的计数器 每当调用acquire()时,内置计数器-1 每当调用release()时,内置计数器+1 计数器不能小于0,当计数器为0时,acquire()将阻塞线程直到其他 ...
- CentOS(Linux)下安装dmidecode包
安装代码: yum install dmidecode 安装完成后,查看总体信息: dmidecode 查看服务器类型,测试环境为DELL R610: dmidecode -s system-prod ...