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>

代码运行结果:

相关推荐
刘一说19 分钟前
Vue 导航守卫未生效问题解析:为什么路由守卫不执行或逻辑失效?
前端·javascript·vue.js
一周七喜h1 小时前
在Vue3和TypeScripts中使用pinia
前端·javascript·vue.js
weixin_395448911 小时前
main.c_cursor_0202
前端·网络·算法
摘星编程1 小时前
用React Native开发OpenHarmony应用:Calendar日期范围选择
javascript·react native·react.js
东东5162 小时前
基于vue的电商购物网站vue +ssm
java·前端·javascript·vue.js·毕业设计·毕设
MediaTea2 小时前
<span class=“js_title_inner“>Python:实例对象</span>
开发语言·前端·javascript·python·ecmascript
雨季6662 小时前
Flutter 三端应用实战:OpenHarmony “微光笔记”——在灵感消逝前,为思想点一盏灯
开发语言·javascript·flutter·ui·dart
编码者卢布2 小时前
【Azure Stream Analytic】用 JavaScript UDF 解决 JSON 字段被转成 Record 的关键点
javascript·json·azure
梦梦代码精2 小时前
开源、免费、可商用:BuildingAI一站式体验报告
开发语言·前端·数据结构·人工智能·后端·开源·知识图谱
松树戈2 小时前
滥用AI生图引起的JavaScript heap out of memory排查记录
vue.js·ai编程