vue render 3种写法
一,嵌套元素
<script>
export default {
render: function (h) {
let self = this
return h(
//第一个参数:写一个 HTML 标签名、组件选项对象
//或者resolve 了上述任何一种的一个 async 函数。必填项。
'div',
//第二个参数:一个与模板中 attribute 对应的数据对象。
//可选
{
// // 与 `v-bind:class` 的 API 相同,
// 接受一个字符串、对象或字符串和对象组成的数组 可直接在style中使用
class: {
child: true,
more: false
},
//html属性
attrs: {
id: 'foo',
name: 'child',
// class: 'child'
},
// 事件1直接运行
// on: {
// click:
// () => {
// console.log('执行');
// }
// },
//2
on: {
click:
this.nativeClickHandler //指定methods中方法
},
// 仅用于组件,用于监听原生事件,而不是组件内部使用
// `vm.$emit` 触发的事件。
nativeOn: {
// click: this.nativeClickHandler
},
// 组件 prop
props: {
teext: 'bar'
},
style: {
color: 'red'
}
,
// domProps: {
// innerHTML: '我是render渲染的子组件'
// },
// 自定义指令。注意,你无法对 `binding` 中的 `oldValue`
// 赋值,因为 Vue 已经自动为你进行了同步。
// directives: [
// {
// name: 'my-custom-directive',
// value: '2',
// expression: '1 + 1',
// arg: 'foo',
// modifiers: {
// bar: true
// }
// }
// ],
// 如果组件是其它组件的子组件,需为插槽指定名称
slot: 'name-of-slot',
// 其它特殊顶层属性
key: 'myKey',
ref: 'myRef',
// 如果你在渲染函数中给多个元素都应用了相同的 ref 名,
// 那么 `$refs.myRef` 会变成一个数组。
refInFor: true
}
//第三个参数:子级虚拟节点 (VNodes),由 `createElement()` 构建而成,
//也可以使用字符串来生成“文本虚拟节点”。可选。
//可省略不写 domProps: { innerHTML:} // domProps: { innerHTML: '我是render渲染的子组件' }
,
'我是render渲染的子组件'
[
//作用域插槽
self.$scopedSlots.default({
text: this.teext
}),
// 添加子标签
h('h2', '标题'),
h('div', {
class: 'content',
attrs: {
id: 'content',
},
on: {
click:
() => {
console.log('执行');
}
},
style: {
width: '800px',
height: '100px'
},
domProps: {
innerHTML: '我是内容'
}
})
]
)
// )
},
props: {
teext: {
type: String,
}
},
data() {
return {
a: '1'
}
},
methods: {
nativeClickHandler() {
console.log('我是方法');
}
},
created() {
// console.log(this.teext);
}
}
</script>
<style lang="scss" scoped>
.child {
background-color: #5cd727;
width: 300px;
height: 200px;
}
</style>
二,返回的是平级(同一层)元素, 用slot插槽;
render(h, context) {
const { icon, title } = context.props
const vnodes = []
if (icon) {
vnodes.push(<svg-icon icon-class={icon}/>)
}
if (title) {
vnodes.push(<span slot='title'>{(title)}</span>)
}
return vnodes
}
三,创建vue组件 ,返回 html模板 - 里面的元素可直接访问 vue组件里的事件、属性
render: function (h,record) {
return (
<div class="renderClass" style='background:#409EFF' onClick={() =>
this.DisStatus(record) class={this.isActive ? 'active sidebar-item' : 'sidebar-item'}}
>
{text}
</div >
)
},
oncLick={()=>this.xxx()} 方法后的()不能省略
需要注意最好用函数不是箭头函数,箭头函数this指向问题会使on不能直接使用methods方法,作用域插槽也会报错,具体可查看this的绑定模式
也可直接render(h){}
组件中自定义reader函数组件
我们将组件记为 functional,它无状态(没有 data),无实例(没有 this 上下文)。
在添加 functional: true 之后,组件的 render 函数之间将增加 ctx 参数
组件需要的一切都是通过 ctx 传递,包括:
- props: 提供 props 的对象
- children: VNode 子节点的数组
- slots: slots 对象
- data: 传递给组件的 data 对象
- parent: 对父组件的引用
render组件
<script>
export default {
name: 'RenderCol',
functional: true,
props: {
row: Object,
render: Function,
index: Number,
column: {
type: Object,
default: null
}
},
render (h, ctx) {
console.log( ctx.props.render(ctx.props.row[ctx.props.column.prop], ctx.props.row, ctx.props.index));
const params = {
row: ctx.props.row,
index: ctx.props.index
}
if (ctx.props.column) params.column = ctx.props.column
return ctx.props.render(ctx.props.row[ctx.props.column.prop], ctx.props.row, ctx.props.index)
}
}
</script>
<template>
//根据上下文定义render位置
<el-table:data="listDate" >
<template slot-scope="scope" >
<renderTest v-if="rscope.row.render" :index="scope.$index" :render="scope.row.render" :row="scope.row" ></renderTest>
</template>
</el-dable>
</template>
<script>
import renderTest from './renderTest.vue'
export default {
name: 'lists',
components: { renderTest },
props: {
listDate: {
type: Array
},
}
}
</script>
使用组件
<template>
<div class="text">
<ttable :table="lable"></ttable>
</div>
</template>
<script>
import ttablefrom './ttable.vue'
export default {
name: 'text',
components: { ttable},
data() {
return {
topicColumns: [{
label: "排名", prop: "xmdmc",
render: (text) => {
if (text <= 3) {
return (
<div class="renderClass" style='background:#409EFF'
>
{text}
</div >
)
} else {
return (
<div class="renderClass" style='background:#C0C4CC'
>
{text}
</div >)
}
}
},
{ label: "#话题名称", prop: "yskze", },
{ label: "话题下文章数", prop: "srze", },
],
}
}
}
</script>