6.4案例:使用渲染函数渲染列表

本节将使用render()函数实现列表的渲染功能。为了渲染特定样式的列表,需要先实现单个列表项的组件ListItem,假设场景为帖子列表,则每个列表项将展示帖子的简介内容。

代码如下

app.component('listitem', {

props: {

content: {

type: Object,

required: true

}

},

render() {

return Vue.h('li', [

Vue.h('p', [

Vue.h('span', `标题: ${this.content.title}`),

Vue.h('span', ` | 发贴人: ${this.content.author}`),

Vue.h('span', ` | 发贴时间: ${this.content.date}`),

Vue.h('span', ` | 点赞数: ${this.content.vote}`),

Vue.h('button', {

onclick: () => this.$emit('vote')

}, '赞')

])

]);

}

});

Vue.h()函数的两个参数都是可选的,区分第二个参数和第三个参数呢的简单方式是看是看对象传参还是数组传参,对象传参是第二个参数(设置元素的属性信息),数组传参是第三个参数(设置字节的信息)

j接下来是列表组件ContentList的代码,其中粗体显示的部分是针对子组件的处理方式代码如下:

//父组件

app.component('contentlist', {

data() {

return {

contents: [

{ id: 1, title: '如何学好前端开发', author: '张三', date: '3个月前', vote: 0 },

{ id: 2, title: 'Vue3.0与Vue2.0的差异', author: '李四', date: '1个月前', vote: 0 },

{ id: 3, title: 'Web3.0初探', author: '王五', date: '2天前', vote: 0 }

]

};

},

methods: {

handleVote(id) {

this.contents = this.contents.map(item => {

return item.id === id? {...item, vote: item.vote + 1 } : item;

});

}

},

render() {

let contentNodes = [];

this.contents.map(item => {

let node = Vue.h(Vue.resolveComponent('listitem'), {

content: item,

onVote: () => this.handleVote(item.id)

});

contentNodes.push(node);

});

return Vue.h('div', [

Vue.h('ul', contentNodes)

]);

}

});

完整代码如下:

html 复制代码
<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>Vue 3 App</title>
</head>

<body>
    <div id="app">
        <contentlist></contentlist>
    </div>
    <script src="http://unpkg.com/vue@3"></script>
    <script>
        const app = Vue.createApp({});

        // 列表项组件
        app.component('listitem', {
            props: {
                content: {
                    type: Object,
                    required: true
                }
            },
            render() {
                return Vue.h('li', [
                    Vue.h('p', [
                        Vue.h('span', `标题: ${this.content.title}`),
                        Vue.h('span', ` | 发贴人: ${this.content.author}`),
                        Vue.h('span', ` | 发贴时间: ${this.content.date}`),
                        Vue.h('span', ` | 点赞数: ${this.content.vote}`),
                        Vue.h('button', {
                            onclick: () => this.$emit('vote')
                        }, '赞')
                    ])
                ]);
            }
        });

        // 内容列表组件
        app.component('contentlist', {
            data() {
                return {
                    contents: [
                        { id: 1, title: '如何学好前端开发', author: '张三', date: '3个月前', vote: 0 },
                        { id: 2, title: 'Vue3.0与Vue2.0的差异', author: '李四', date: '1个月前', vote: 0 },
                        { id: 3, title: 'Web3.0初探', author: '王五', date: '2天前', vote: 0 }
                    ]
                };
            },
            methods: {
                handleVote(id) {
                    this.contents = this.contents.map(item => {
                        return item.id === id? {...item, vote: item.vote + 1 } : item;
                    });
                }
            },
            render() {
                let contentNodes = [];
                this.contents.map(item => {
                    let node = Vue.h(Vue.resolveComponent('listitem'), {
                        content: item,
                        onVote: () => this.handleVote(item.id)
                    });
                    contentNodes.push(node);
                });
                return Vue.h('div', [
                    Vue.h('ul', contentNodes)
                ]);
            }
        });

        // 挂载应用
        app.mount('#app');
    </script>
</body>

</html>

代码运行结果:

相关推荐
挽淚几秒前
JavaScript 数组详解:从入门到精通
javascript
言兴1 分钟前
教你如何理解useContext加上useReducer
前端·javascript·面试
sunbyte5 分钟前
50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | GoodCheapFast(Good - Cheap - Fast三选二开关)
前端·javascript·css·vue.js·tailwindcss
前端的日常6 分钟前
网页视频录制新技巧,代码实现超简单!
前端
前端的日常8 分钟前
什么是 TypeScript 中的泛型?请给出一个使用泛型的示例。
前端
ccc101812 分钟前
老师问我localhost和127.0.0.1,有什么区别?
前端
南篱13 分钟前
JavaScript 中的 this 关键字:从迷惑到精通
javascript
Struggler28119 分钟前
Chrome插件开发
前端
前端 贾公子31 分钟前
Monorepo + vite 怎么热更新
前端
coding随想40 分钟前
掌控网页的魔法之书:JavaScript DOM的奇幻之旅
开发语言·javascript·ecmascript