本节将使用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>
代码运行结果:
