问个 Vue 的问题,父组件通过 props 传值给子组件,在父组件内更改数据 子组件的 class 属性没有变更,详情见代码

2021-02-02 14:09:06 +08:00
 Aruforce

父组件代码

<template>
  <div class="page_content_container">
    <div class="recommand_communities_container">
      <community_card v-for="(community,index) in communities" v-bind:key="index" v-bind:community="community" v-on:onclick="onChosen" />
    </div>
  </div>
</template>
<script>
import community_card from '../community_card.vue';
export default {
  components: { community_card},
  name: "page_content",
  data: function () {
    return {
      communities:[
		{
			id:'1'
			name:'1-C',
			intro:'1-C Test',
			avatar:'/1-C-avatar.jpg'
			selected:true
		},
		{
			id:'2'
			name:'2-C',
			intro:'2-C Test',
			avatar:'/2-C-avatar.jpg'
			selected:false
		},
		{
			id:'3'
			name:'3-C',
			intro:'3-C Test',
			avatar:'/3-C-avatar.jpg'
			selected:false
		},
	  ]
    }
  },
  methods: {
    onChosen:function(communityId){
      for (let index = 0; index < this.communities.length; index++) {
        const element = this.communities[index];
        if(element.id == communityId ){
           element.selected = true;
		   // element.name = 'DoTest'; 有这一行 子组件的 class 会变更 ,没有则不会变更
        }else{
          element.selected = false
        }
      }
    }
  },
};
</script>
<style scoped>
.page_content_container {
  height: 800px;
  width: 100%;
  display:flex;
}
.recommand_communities_container {
  height: 800px;
  width: 240px;
  margin: 0;
  padding: 0;
  display: inline-block;
}
.recommand_community_post_container {
  border-radius: 15px;
  height: 100%;
  width: 100%;
  margin: 0;
  padding: 0;
  border-left:1px solid rgba(0, 0, 0, 0.22);
  display: inline;
}
</style>

子组件

<template>
  <div class="community_card_container" v-bind:class="{'selected':community.selected}" v-on:click="onclick">
    <div class="community_card_avatar_container">
      <img :src="community.avatar" :title="community.name" />
    </div>
    <div class="community_card_base_info_container">
      <div>{{ community.name }}</div>
      <div>{{ community.intro }}</div>
    </div>
  </div>
</template>
<script>
export default {
  name: "community_card",
  data: function () {
    return {
	
    }
  },
  methods: {
    onclick: function () {
      this.$emit('onclick',this.community.id)
    },
  },
  props:['community']
};
</script>
<style scoped>
.community_card_container {
  height: 76px;
  width: 236px;
  border: lightslategray 2px solid;
  display: flex;
  border-radius: 10px;
}
.selected{
  background-color:lightskyblue ;
}
.community_card_container .community_card_avatar_container {
  height: 76px;
  width: 76px;
  display: inline;
  text-align: center;
}

.community_card_container .community_card_base_info_container {
  width: 136px;
  border-left:rgb(177, 171, 204) 2px solid;
}
.community_card_container .community_card_avatar_container img {
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 100%;
}
.community_card_container .community_card_base_info_container div {
  height: 38px;
  width: 136px;
  line-height: 38px;
  text-align:center;
  overflow:hidden;
}
</style>

请教原因和怎么解决

2290 次点击
所在节点    程序员
28 条回复
jrtzxh020
2021-02-02 15:33:23 +08:00
不考虑性能的话。最简单的方法新建一个变量 a,将 communities 深拷贝赋值给 a,遍历 a 修改 selected 后。最后重新赋值 this.communities = a
wunonglin
2021-02-02 15:34:53 +08:00
@Aruforce 把 key 改成 name 试试,是不是 index 没变化
jrtzxh020
2021-02-02 15:37:56 +08:00
@jrtzxh020 或者在 onChosen 方法最后调用 this.communities = JSON.parse(JSON.stringify(this.communities)) 哈哈 不是很建议
yor1g
2021-02-02 16:22:00 +08:00
更新 element 方法不对 子组件检查不到变更
https://cn.vuejs.org/v2/api/#Vue-set
Doracis
2021-02-02 16:29:10 +08:00
不看代码先凭经验说,加深度监听 deep immediate,要么父组件 this.$set
RoshanWu
2021-02-02 20:39:19 +08:00
用个定时器模拟了下 LZ 说的「从后台通过 axios 抓取的数据 」,也没看出啥异常
```
setTimeout(() => {
this.communities[0].selected = false
}, 3000);
```
rodrick
2021-02-02 22:21:57 +08:00
总得来说 community.id 如果要传回去的话就最好 copy 一下再传,毕竟我总觉得把 prop 去$set 响应式有点怪,专一原则上来说 prop 就作为一个父子传参读取就好了
zqx
2021-02-03 06:40:55 +08:00
总的来说就是不要推测 vue 组件什么时候会重新渲染
forceupdate 写多了会让代码不好维护,导致下一个程序员不容易从代码中追踪数据变化
你明知道 vue 组件不会响应的数据变化(几种常见情况,官网有实例),就用 watch 手动监听它(开启 deep 选项)

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/750598

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX