template----html的方式做渲染

render----js的方式做渲染

render(提供)是一种编译方式

render里有一个函数h,这个h的作用是将单文件组件进行虚拟DOM的创建,然后再通过render进行解析。

h就是createElement()方法:createElement(标签名称,属性配置,children)

template也是一种编译方式,但是template最终还是要通过render的方式再次进行编译。

区别:

1、render渲染方式可以让我们将js发挥到极致,因为render的方式其实是通过createElement()进行虚拟DOM的创建。逻辑性比较强,适合复杂的组件封装。

2、template是类似于html一样的模板来进行组件的封装。

3、render的性能比template的性能好很多

4、render函数优先级大于template

  • App.vue(主入口文件)
<template>
    <ParentCmp />
</template>

<script>
import ParentCmp from './ParentCmp';

export default {
    components: {
        ParentCmp
    },
}
</script>
  • ParentCmp.vue (template写法)
  • <template>
        <div>
            <h1>我是parent组件</h1>
            <hr />
            <User style="background: #ccc" text="我是传入的文本">
                <template v-slot:header>
                    <p>这是名字为header的slot</p>
                </template>
                <p>这是填充默认slot数据</p>
                <template v-slot:footer>
                    <p>这是名字为footer的slot</p>
                </template>
                <template v-slot:item="props">
                    <p>名字为item的作用域插槽。显示数据{{props}}</p>
                </template>
                <template v-slot:list="props">
                    <p>名字为list的作用域插槽。显示数据{{props}}</p>
                </template>
            </User>
        </div>
    </template>
    
    <script>
    import User from './User'
    export default {
        components: {
            User
        },
    
        props: {},
    
        data() {
            return {}
        },
    
        methods: {}
    }
    </script>

  • User.vue (template写法)
    <template>
        <div>
            <h4>{{text}}</h4>
            <slot name="header"></slot>
            <slot>默认的user slot</slot>
            <slot name="footer"></slot>
            <slot name="item" v-bind="item">item作用域插槽,展示姓名 {{item.name}}</slot>
            <slot name="list" v-bind="{list}">list作用域插槽</slot>
        </div>
    </template>
    
    <script>
    export default {
        props: {
            text: String
        },
        data() {
            return {
                item: {
                    name: '张三',
                    age: 28,
                    works: '前端、后端、设计、产品'
                },
                list: ['a','b','c']
            }
        }
    }
    </script>

  • ParentCmp.js (render写法)
  • import User from './User'
    
    export default {
        props: {},
        data() {
            return {}
        },
        methods: {},
        render(h) {
            return h('div',[
                h('h1', '我是parent组件'),
                h('hr'),
                h(User, {
                    props: {
                        text: '我是传入的文本'
                    },
                    style: {
                        background: '#ccc'
                    },
                    // 作用域插槽写在scopedSlots里
                    scopedSlots: {
                        item: props => h('p', `名字为item的作用域插槽。显示数据${JSON.stringify(props)}`),
                        list: props => h('p', `名字为list的作用域插槽。显示数据${JSON.stringify(props)}`)
                    }
                }, 
                // 非作用域插槽写数组里
                [
                    h('p', {slot: 'header'}, '这是名字为header的slot'),
                    h('p', '这是填充默认slot数据'),
                    h('p', {slot: 'footer'}, '这是名字为footer的slot'),
                ])
            ]);
            // jxs写法
            /* return (
                <div>
                    <h1>我是parent组件</h1>
                    <hr />
                    <User 
                        style="background: #ccc" 
                        text="我是传入的文本" 
                        scopedSlots={
                            {
                                item: props => (<p>名字为item的作用域插槽。显示数据{JSON.stringify(props)}</p>),
                                list: props => (<p>名字为list的作用域插槽。显示数据{JSON.stringify(props)}</p>),
                            }
                        }
                    >
                        <p slot="header">这是名字为header的slot</p>
                        <p>这是填充默认slot数据</p>
                        <p slot="footer">这是名字为footer的slot</p>
                    </User>
                </div>
            ); */
        }
    }

  • User.js (render写法)
  • export default {
        props: {
            text: String
        },
        data () {
            return {
                item: {
                    name: '张三',
                    age: 28,
                    works: '前端、后端、设计、产品'
                },
                list: ['a', 'b', 'c']
            }
        },
        methods: {
            getSlot (name, data) {
                if (this.$scopedSlots[name]) {
                    return this.$scopedSlots[name](data);
                } else if (this.$slots[name]) {
                    return this.$slots[name];
                }
        
                return undefined;
            },
        },
        render (h) {
            return h('div', [
                h('h4', this.text),
                this.getSlot('header'),
                this.$slots.default,
                this.getSlot('footer'),
                this.getSlot('item', this.item),
                this.getSlot('list', {list: this.list}),
            ])
            // jxs写法
            /* return (
                <div>
                    <h4>{this.text}</h4>
                    {this.getSlot('header')}
                    {this.$slots.default}
                    {this.getSlot('footer')}
                    {this.getSlot('item', this.item)}
                    {this.getSlot('list', {list: this.list})}
                </div>
            ); */
        }
    }

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐