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 ...
随机推荐
- 童攀TP5企业网站实战笔记
$this->assign('data',$data) ---恢复内容开始--- return view(); 载入视图 {include file='public/head'} 包含文件 ...
- Cacti在selinux开启的情况下使用
# chcon -R -t httpd_sys_content_t /var/www/html/cacti
- 2017-12-30-如何彻底清除现存GIT仓库的大量提交历史
layout: post title: 2017-12-30-如何彻底清除现存GIT仓库的大量提交历史 key: 20171230 tags: GIT 版本管理 问答 modify_date: 201 ...
- css变量的用法——(--cssName)
CSS变量,又称——CSS自定义属性,现在很多CSS预处理/后处理程序已作了相关快捷的编译处理, 基本用法有哪些呢,我们先看一个简单的栗子:——要求,创建一个五个块元素居中的分栏样式,奇数和偶数同高不 ...
- WTF小程序之wxs
前言 对于从VUE过来的前端同学来说,见到小程序的第一眼一定是熟悉-感觉就像是把vue的单文件拆成了3个文件.但是,随着慢慢入坑.马上会发现,这样怎么不行?wxs文件又是什么鬼?template和vu ...
- C++——函数重载
C++允许功能相近的函数在相同的作用域内以相同函数名声明,从而形成重载,方便使用,便于记忆. /*形参类型不同*/ int add(int x,int y); float add(float x,fl ...
- html5的video标签自动播放
概念澄清 这里的"自动播放",是指用户的视觉效果,并不一定是元素自身的自动播放. 查看相关文档后,有以下两种最简方案. 配置属性 发现有video标签有一个自动播放的属性autop ...
- ng-show,ng-if区别
在使用bootstrap中,我们会经常用到按钮组,也就是btn-group,如果仔细观察的话,会发现一个按钮组的第一个和最后一个按钮分别是有圆角的,如下图: 但是中间的按钮是没有圆角的,这样显得比较美 ...
- CSS中的字体属性和文本属性
1.CSS字体的属性 font 简写,作用是把所有的针对字体的属性设置在一个声明中 font-family 设置字体系列 font-size 设置字体尺寸 font-style 设置字体风格,ital ...
- javascript:Json 和数组的遍历
首先看代码示例var json={a:1,b:2,c:3}; //json var array={1,2,3}; //数组 alert(json.a); //弹出1 或alert(json['a']) ...