Render渲染函数和JSX

2019-12-19  本文已影响0人  幻影翔

render函数

h( 元素,属性,值 ) 中 h 不能少

// render 包含下main相关属性
 render: h => {
        return h(CountTo, {
            'class':[],
            attrs: {},
            style: {},
            props: {
                endVal: 200
            },
            // domProps: {
            //  innerHTML: '123'
            // },
            on: {
                'on-animation-end': (val) => {
                    console.log('end')
                }
            },
            nativeOn: {
                'click': () => {
                    console.log('click !')
                }
            },
            directives: [],
            scopedSlots: {},
            slot: '',
            key: '',
            ref: ''
        })
    }

使用

<div>
    <ul @click="handleClick">
        <li v-for="(item, index) in list" :key="`list_item_${index}`">{{ item.name }}</li>
    </ul>
</div>

// 将它转成render函数
    render: h => h('div', [
        h('ul', {
            on: {
                'click': event => {
                    console.log(event)
                }
            }
        }, getEleArr(h))
    ])

let list = [{name: 'jack1'},{name: 'jack3'}]
const getEleArr = (h) => {
    return list.map((item,index) => h('li',{
        on: {
            'click': event => {
                console.log(event)
                event.stopPropagation()
            }
        },
        key: `list_item_${index}`
    },item.name))
}

list组件中调用

<template>
    <ul>
        <li v-for="(item, index) in list" :key="`item_${index}`">
            <span v-if="!render">{{ item.name }}</span>
            <render-dom v-else :render-func="render" :name="item.name"></render-dom>
        </li>
    </ul>
</template>
<script>
import RenderDom from '_c/render-dom'
export default {
    name: 'List',
    components: {
        RenderDom
    },
    props: {
        list: {
            type: Array,
            default: () => []
        },
        render: {
            type: Function,
            default: () => {}
        }
    }
}
</script>

函数式组件

定义函数式组件

export default  {
    functional: true,  // true时没有状态
    props: {
        name: String,
        renderFunc: Function // 用户自定义的函数
    },
    render: (h, ctx) => {
        return ctx.props.renderFunc(h, ctx.props.name)
    }
}

页面使用

<template>
    <div>
        <list :list="list" :render="renderFunc"></list>
    </div>
</template>
<script>
import List from '_c/list'
export default {
    data () {
        return {
            list: [
                { name: 'jack1'},
                { name: 'jack2'}
            ]
        }
    },
    components: {
        List
    },
    methods: {
        renderFunc (h, name) {
            return h('i', {
                style: {
                    color: 'pink'
                }
            }, name)
        }
    }
}
</script>

JSX

    <div>
        <list :list="list"  :render="renderFunc"></list>
    </div>
</template>
<script>
import List from '_c/list'
import CountTo from '_c/count-to'
export default {
    data () {
        return {
            list: [
                { number: 100},
                { number: 200}
            ]
        }
    },
    components: {
        List
    },
    methods: {
        renderFunc (h, number) {
            return (
                // 直接写标签,注意用 { } 包裹
                // 事件使用on-actionName
                <CountTo nativeOn-click={this.handleClick} on-on-animation-end={this.handleEnd} endVal={number} style={{color:'pink'}}></CountTo>
            )
        },
        handleClick (event) {
            console.log(event)
        },
        handleEnd () {
            console.log("end")
        }
    }
}
</script>

常用指令变化

.stop => event.stopPropagation()  // 阻止冒泡事件
.prevent  => event.preventDefault()  // 阻止鼠标默认行为

作用域插槽

// 给 slot 绑定一个属性
<slot :number="item.number"></slot>

// 使用,定义一个属性count ,然后可以直接使用count属性对象中的值
<count-to slot-scope="count" :end-val="count.number"></count-to>
上一篇 下一篇

猜你喜欢

热点阅读