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>

代码运行结果:

相关推荐
前端小棒槌15 小时前
TypeScript 核心知识点
前端
Selicens15 小时前
turbo迁移vite+(vite-plus)实践
前端·javascript·vite
答案answer15 小时前
我的Three.js3D场景编辑器免费开源啦🎉🎉🎉
前端·github·three.js
欧阳天羲15 小时前
AI 时代前端工程师发展路线
前端·人工智能·状态模式
Moment15 小时前
从爆红到被嫌弃,MCP 为什么开始失宠了
前端·后端·面试
code2015 小时前
microapp 通过链接区分主子应用步骤
前端
北寻北爱16 小时前
面试题-git+npm
vue.js·git·webpack·echarts
IT 行者16 小时前
Claude Code Viewer: 打造 Web 端 Claude Code 会话管理利器
前端·人工智能·python·django
张毫洁16 小时前
vue2项目搭建
前端·vue.js·node.js
@逆风微笑代码狗16 小时前
148.《mobx-react-lite + TypeScript 入门实战教程(完整版)》
前端·react.js·typescript