uni-app h5中动态设置class 在父组件传递的参数变了之后子组件不会生效

uni-app h5中动态设置class 在父组件传递的参数变了之后子组件不会生效

开发环境 版本号 项目创建方式
Windows Windows 10 家庭中文版 版本号22H2 HBuilderX
产品分类:uniapp/H5

浏览器平台:Chrome
浏览器版本:5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1

### 示例代码:

```html
子组件  
<template>  
    <view class="button-list">  
        <button v-for="(item,index) in data" :key="index" :class="['button-item', item.disabled&&'is-disabled']"  
            :style="[item.style]" @click="buttonClick(item)">  
            <text class="button-item-text">{{item.label}}</text>  
        </button>  
    </view>  
</template>  

<script setup>  
    const props = defineProps({  
        data: {  
            type: Array,  
            default: () => ([])  
        }  
    })  
    const emits = defineEmits(['customClick'])  

    function buttonClick(item) {  
        if (item.disabled) return // 这里可以生效  
        emits('customClick', item)  
    }  
</script>  

父组件  
<template>  
     <buttonListVue :data="data" @customClick="buttonClick" />  
</template>  
<script setup>    
    const data = [{label: '点我'},{label:'点他'}]  
    const emits = defineEmits(['customClick'])  

    function buttonClick(item) {  
        data[0].disabled = !data[0].disabled  
        emits('customClick', item)  
    }  
</script>

操作步骤:

复制上面

预期结果:

可以改变class

实际结果:

不可以改变class

bug描述:

如题, 在父组件设置item为disabled后子组件里面的class没有加上is-disabled,方法里面点击是可以禁止的,是我写法的问题还是啥啊,求解决办法


更多关于uni-app h5中动态设置class 在父组件传递的参数变了之后子组件不会生效的实战教程也可以访问 https://www.itying.com/category-93-b0.html

3 回复

setup 中需要加上 ref 才会变成响应式变量,下面这样写就可以啦

<script setup> import { ref } from 'vue' import subComponentVue from './subComponent.vue'; const data = ref([{label: '点我'},{label:'点他'}] ) const emits = defineEmits(['customClick']) function buttonClick(item) { data.value[0].disabled = !data.value[0].disabled emits('customClick', item) } </script>

更多关于uni-app h5中动态设置class 在父组件传递的参数变了之后子组件不会生效的实战教程也可以访问 https://www.itying.com/category-93-b0.html


忘记加了,感谢…我之前是直接写到父组件用的props传递的…没有写到ref里面导致的

在 uni-app 中,如果你在父组件中传递了参数给子组件,并且希望在子组件中根据这些参数动态设置 class,但发现父组件传递的参数变化时子组件的 class 没有更新,可能是由于以下几个原因:

1. 确保父组件传递的 props 是响应式的

父组件传递给子组件的 props 需要是响应式的,这样当父组件中的 props 变化时,子组件才能感知到并更新。

<!-- 父组件 -->
<template>
  <Child :isActive="isActive" />
</template>

<script>
export default {
  data() {
    return {
      isActive: false
    };
  },
  methods: {
    toggleActive() {
      this.isActive = !this.isActive;
    }
  }
};
</script>

2. 子组件中正确使用 props

子组件中需要正确接收并使用父组件传递的 props。

<!-- 子组件 -->
<template>
  <div :class="{ active: isActive }">子组件内容</div>
</template>

<script>
export default {
  props: {
    isActive: {
      type: Boolean,
      required: true
    }
  }
};
</script>

<style>
.active {
  background-color: yellow;
}
</style>

3. 确保父组件的 props 更新触发了子组件的重新渲染

如果父组件的 props 更新了,但子组件没有重新渲染,可能是因为子组件的 props 没有正确监听变化,或者子组件的 shouldComponentUpdate 逻辑阻止了更新。

在 Vue 中,props 默认是响应式的,因此通常不需要手动处理。但如果你在子组件中使用了 watch 来监听 props 的变化,确保 watch 生效。

<!-- 子组件 -->
<template>
  <div :class="{ active: isActive }">子组件内容</div>
</template>

<script>
export default {
  props: {
    isActive: {
      type: Boolean,
      required: true
    }
  },
  watch: {
    isActive(newVal) {
      console.log('isActive changed:', newVal);
    }
  }
};
</script>

4. 检查是否使用了 v-ifv-show

如果你在子组件中使用了 v-ifv-show,确保它们的条件逻辑不会阻止子组件的更新。

<!-- 父组件 -->
<template>
  <Child v-if="showChild" :isActive="isActive" />
</template>

<script>
export default {
  data() {
    return {
      showChild: true,
      isActive: false
    };
  },
  methods: {
    toggleActive() {
      this.isActive = !this.isActive;
    }
  }
};
</script>

5. 检查是否使用了 key 强制更新子组件

如果你使用了 key 来强制更新子组件,确保 key 的值在父组件的 props 变化时也更新了。

<!-- 父组件 -->
<template>
  <Child :key="isActive" :isActive="isActive" />
</template>

<script>
export default {
  data() {
    return {
      isActive: false
    };
  },
  methods: {
    toggleActive() {
      this.isActive = !this.isActive;
    }
  }
};
</script>
回到顶部