在祖父组件render-page.vue中,renderFunc函数由 vue 中的函数式组件 —> JSX实现
函数式组件
methods: {
renderFunc(h, name) {
return h('i', {
style: {
color: 'red'
}
}, name)
}
}
jsx
methods: {
renderFunc(h, name) {
return (
<i on-click={this.handleClick} style={{color: 'pink'}}>{name}</i>
)
},
// 给i标签加点击事件
handleClick(event) {
console.log(event)
}
}
在组件中引用子组件,给jsx和函数式组件使用功能时,不用驼峰命令的形式,组件是什么名字,引入时就是什么形式,比如
引入 import CountTo from '_c/count-to'
使用时 <CountTo endVal={number} on-click={this.handleClick} style={{color: 'pink', fontSize: '40px'}}>{number}</CountTo>
自定义事件和js本身的事件,在事件名前面加 on-
<CountTo
on-on-animation-end={this.handleEnd}
endVal={number}
on-click={this.handleClick}
style={{color: 'pink', fontSize: '40px'}}>{number}</CountTo>
下面是全部代码
父组件render-page.vue
<template>
<div>
<list :list="list" :render="renderFunc"></list>
</div>
</template>
<script>
import List from '_c/ulList'
import CountTo from '_c/count-to'
export default {
data() {
return {
list: [
{number: 100 },
{number: 33 }
]
}
},
components: {
List
},
methods: {
renderFunc(h, number) {
return (
<CountTo
on-on-animation-end={this.handleEnd}
endVal={number}
nativeOn-click={this.handleClick}
style={{color: 'pink', fontSize: '40px'}}>{number}</CountTo>
)
},
handleClick(event) {
console.log(event)
},
handleEnd () {
console.log('end!')
}
}
}
</script>
子组件 ulList.vue
<template>
<div>
<ul>
<li @mousemove="handleMove" v-for="(item, index) in list" :key="`item_${index}`">
<span v-if="!render">
{{item.number}}
</span>
<render-dom v-else :render-func="render" :number="item.number"></render-dom>
</li>
</ul>
</div>
</template>
<script>
import RenderDom from '_c/render-dom'
export default {
name: 'list',
components: {
RenderDom
},
props: {
list: {
type: Array,
default: () => []
},
render: {
type: Function,
default: () => {}
}
},
methods: {
handleMove(event) {
// 去除鼠标默认事件,例如双击默认选中
event.preventDefault()
}
}
}
</script>
函数式组件 render-dom.js
export default {
functional: true,
props: {
number: Number,
renderFunc: Function
},
render: (h, ctx) => {
return ctx.props.renderFunc(h, ctx.props.number)
}
}