跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • 问个 Vue 的问题,父组件通过 props 传值给子组件,在父组件内更改数据 子组件的 class 属性没有变更,详情见代码
未分類
4 2 月 2021

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

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

資深大佬 : Aruforce 2

父组件代码

<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> 

请教原因和怎么解决

大佬有話說 (28)

  • 資深大佬 : bootvue

    props:[‘community’] 这种写法 子组件 仅仅会把 props 数据 copy 一份为本地变量使用

    如果希望观察到 props 的变化 子组件应该用 computed 官方文档说的很清楚

    https://cn.vuejs.org/v2/guide/components-props.html#%E5%8D%95%E5%90%91%E6%95%B0%E6%8D%AE%E6%B5%81

  • 資深大佬 : shintendo

    一个建议:提问时为了方便他人阅读,尽可能先整理代码,至少不要有缺少逗号这种问题,最重要的是删除所有与问题无关的干扰代码,当你最后得到一个能复现问题的最短代码时,大概率你自己就发现问题的所在了。

  • 資深大佬 : ZZ222ZZ

    好像这个需要用到深度监听,如果只是 community 属性的值发生变化,props 是不会更新的

  • 資深大佬 : Lemeng

    代码有点多,把不要的去掉,尽量精简,一眼就知道问题所在

  • 資深大佬 : chenluo0429

    凭感觉口胡一下。
    子组件响应式的监听只到 community 这一层,对于其属性的变更不会响应。解决方案是将 community 的属性分别在 props 里面传给子组件,或者子组件添加若干 computed 计算属性来监听具体属性的变化。

  • 資深大佬 : jadeborner

    用 this.$set

  • 資深大佬 : hengshenyu

    我本地运行了下,没有问题。className 可以响应变化。建议看看缓存?或者 vue 版本升级?

  • 資深大佬 : hengshenyu

    就是少了些逗号

  • 資深大佬 : ragnaroks

    复制你的代码,使用 vue-cli 运行,没有任何问题,点击后就切换为蓝色底色了

  • 資深大佬 : wunonglin

    同意#5 的说话。

    其次我是建议你更改子组件的状态的话就用一个 bind: selected 即可,不要包装在对象里面,不然检测不到对象变化,除非你重新赋值 community 。

    可以试一下 watch,watch 有一个 deep 选项,或者试一下 computed 。

  • 主 資深大佬 : Aruforce

    @bootvue 不是,’拷贝‘这句事实错误,
    @ZZ222ZZ @chenluo0429 @jadeborner @bootvue 如当前代码这种写死数据的情况,是能够根据 selected 的变更 class value 的
    @shintendo @Lemeng 抱歉。。。

  • 主 資深大佬 : Aruforce

    @ragnaroks 是的 但是 我的数据是从后台通过 axios 抓取的数据 这种情况下 不行 颜色无法改变

  • 資深大佬 : wunonglin

    父组件改成
    “`
    <community_card
    v-for=”(community,index) in communities”
    :selected=”community.selected”
    :avatar=”community.avatar”
    :name=”community.name”
    :intro=”community.intro”
    />
    “`

    子组件改成
    “`
    export default {
    name: “community_card”,
    props:[‘selected’, ‘avatar’, ‘name’, ‘intro’]
    };
    “`

    这样试试?

  • 資深大佬 : JXS

    data 接收 prop,然后监听一下 prop,在监听里面去把数值改变一下看可以不

  • 主 資深大佬 : Aruforce

    @wunonglin 并不行

  • 資深大佬 : hengshenyu

    @Aruforce 因为你是从 axios 获取的数据,所以我猜测你可能没有在 data 对它进行声明。Vue 实例生成时也就没有进行代理。
    Vue 需要使用的数据都需要预先声明,否则就需要使用 this.$set(),手动处理。

  • 資深大佬 : Curtion

    既然写死数据那就说明不是组件传值问题引起的,你应该从其他地方入手。 我说一个可能的原因:你的 communities 变量在实际业务上可能是异步获取的,并且其中并没有 selected 属性? 考虑使用 Vue.set

  • 主 資深大佬 : Aruforce

    @hengshenyu 应该不是吧。。子组件的数据是我从父组件传递进去的。。所有的属性都有值。。peopertySetter 应该被代理了才对了

  • 資深大佬 : ugu

    通过索引直接修改数据,vue 无法监听到,建议使用 splice 或者 set

  • 主 資深大佬 : Aruforce

    @Curtion 在 axios complete 的返回里面 element.selected = true 做了这个操作了

  • 資深大佬 : jrtzxh020

    不考虑性能的话。最简单的方法新建一个变量 a,将 communities 深拷贝赋值给 a,遍历 a 修改 selected 后。最后重新赋值 this.communities = a

  • 資深大佬 : wunonglin

    @Aruforce 把 key 改成 name 试试,是不是 index 没变化

  • 資深大佬 : jrtzxh020

    @jrtzxh020 或者在 onChosen 方法最后调用 this.communities = JSON.parse(JSON.stringify(this.communities)) 哈哈 不是很建议

  • 資深大佬 : yor1g

    更新 element 方法不对 子组件检查不到变更
    https://cn.vuejs.org/v2/api/#Vue-set

  • 資深大佬 : Doracis

    不看代码先凭经验说,加深度监听 deep immediate,要么父组件 this.$set

  • 資深大佬 : RoshanWu

    用个定时器模拟了下 LZ 说的「从后台通过 axios 抓取的数据 」,也没看出啥异常
    “`
    setTimeout(() => {
    this.communities[0].selected = false
    }, 3000);
    “`

  • 資深大佬 : rodrick

    总得来说 community.id 如果要传回去的话就最好 copy 一下再传,毕竟我总觉得把 prop 去$set 响应式有点怪,专一原则上来说 prop 就作为一个父子传参读取就好了

  • 資深大佬 : zqx

    总的来说就是不要推测 vue 组件什么时候会重新渲染
    forceupdate 写多了会让代码不好维护,导致下一个程序员不容易从代码中追踪数据变化
    你明知道 vue 组件不会响应的数据变化(几种常见情况,官网有实例),就用 watch 手动监听它(开启 deep 选项)

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具