Vue循环中根据对象type更新title变量失效问题求助
问题描述
我有一个包含6个对象的数组,可通过循环获取每个对象的name和type值。我定义了title变量,希望根据JSON中对象的type值动态更新它:当type为post时,title设为'SinglePost';type为page时,title设为'SinglePage';type为movies时,title设为'SingleMovie'。我需要按「Name值 - Type值 - title值」的格式输出6行内容,例如第一个对象应输出「Item 1 - page - SinglePage」。目前我能正常获取name和type值,但title变量无法随每个对象的type更新,始终显示最后一个值'SingleMovie'。
相关JSON数据
[ { "name": "Item 1", "href": "http://localhost/Wordpress/", "id": "23", "type": "page" }, { "name": "Item 2", "href": "http://localhost/Wordpress/item-2", "id": "2", "type": "page" }, { "name": "Item 3", "href": "http://localhost/Wordpress/item-3", "id": "10", "type": "page" }, { "name": "Item 4", "href": "http://localhost/Wordpress/item-4", "id": "12", "type": "page" }, { "name": "Item 5", "href": "http://localhost/Wordpress/item-5", "id": "1", "type": "post" }, { "name": "Item 6", "href": "http://localhost/Wordpress/item-6", "id": "54", "type": "movies" } ]
当前Vue代码
模板部分
<p v-for="item in newComp" :key="item.id">{{ item.name + " - " + item.type + " - " + this.title }}</p>
组件逻辑部分
export default { data() { let title = ''; return { posts: [], title:'', } }, mounted() { fetch('http://localhost/Wordpress/wp-json/wp/v2/test') .then(res => res.json()) .then(data => this.posts = data) .then(err => console.log(err)) }, computed: { newComp() { const posts = this.posts; if(posts.filter(item => item.type === 'post')) { this.title = 'SinglePost'; } if(posts.filter(item => item.type === 'page')) { this.title = 'SinglePage'; } if(posts.filter(item => item.type === 'movies')) { this.title = 'SingleMovie'; } return posts } }, }
解决方案
问题根源在于两点:
- 单个全局
title变量无法对应多个item的不同类型,计算属性里的判断会依次覆盖title值,最后执行的movies判断会把title固定为SingleMovie。 - 计算属性中修改
data变量(this.title = ...)属于副作用,违反了计算属性纯函数的设计原则。
方案一:用方法实时计算每个item的标题
不需要全局title变量,直接通过方法根据item的type返回对应标题:
组件逻辑修改
export default { data() { return { posts: [], } }, mounted() { fetch('http://localhost/Wordpress/wp-json/wp/v2/test') .then(res => res.json()) .then(data => this.posts = data) .catch(err => console.log(err)) // 修正错误捕获方式 }, methods: { getTitle(type) { switch(type) { case 'post': return 'SinglePost'; case 'page': return 'SinglePage'; case 'movies': return 'SingleMovie'; default: return ''; } } } }
模板修改
<p v-for="item in posts" :key="item.id"> {{ `${item.name} - ${item.type} - ${getTitle(item.type)}` }} </p>
方案二:在计算属性中为每个item添加title字段
如果希望在数据层面预处理,可通过计算属性给每个item新增title字段:
组件逻辑修改
export default { data() { return { posts: [], } }, mounted() { fetch('http://localhost/Wordpress/wp-json/wp/v2/test') .then(res => res.json()) .then(data => this.posts = data) .catch(err => console.log(err)) }, computed: { postsWithTitle() { return this.posts.map(item => { let title = ''; switch(item.type) { case 'post': title = 'SinglePost'; break; case 'page': title = 'SinglePage'; break; case 'movies': title = 'SingleMovie'; break; } return { ...item, title }; }) } } }
模板修改
<p v-for="item in postsWithTitle" :key="item.id"> {{ `${item.name} - ${item.type} - ${item.title}` }} </p>
内容的提问来源于stack exchange,提问作者user28112684
相关产品推荐
相关产品推荐

