单选框组件接收传值更新失败——强制组件刷新

发布于:2025-07-06 ⋅ 阅读:(14) ⋅ 点赞:(0)

单选框组件接收传值更新失败————强制组件刷新
摘要:
单选框组件CustomImageRadio在接收v-model传值时可能出现更新失败问题。原因在于组件可能未正确监听绑定值的变化。解决方法是通过添加:key="componentKey"绑定,并在数据更新时强制更改key值触发组件重新渲染。文中展示了表单中的使用示例,以及完整的单选框组件封装代码,包含动态图片切换和样式处理。关键点包括:1) 使用watch监听选中值变化;2) 通过key值强制刷新;3) 原生单选框隐藏并用图片替代的样式实现。

问题所在

组件监听机制可能缺失。性别单选框CustomImageRadio 组件也许没有监听 v-model 绑定值的变化,进而无法更新自身的选中状态。

封装的组件样式

在这里插入图片描述

在这里插入图片描述

解决方式

:key=“componentKey”

        <el-form-item label="性        别" prop="gender" class="theme-line">
          <CustomImageRadio
              name="gender"
              v-model="selectedGender"
              :key="componentKey"  <!-- 添加 key 绑定 -->
              :options="[
                  {
                    label: '男',
                    value: 0,
                    uncheckedImg: require('@/assets/image/patient/no.png'), // 替换实际图片路径
                    checkedImg: require('@/assets/image/patient/yes.png')
                  },
                  {
                    label: '女',
                    value: 1,
                    uncheckedImg: require('@/assets/image/patient/no.png'), // 替换实际图片路径
                    checkedImg: require('@/assets/image/patient/yes.png')
                  }
                ]"
          />
        </el-form-item>

// 通过更改 key 强制组件重新渲染
componentKey.value += 1;

const componentKey = ref(0);

// 查看
const LookInfo = (item) => {
  form.value = { ...item };
  selectedGender.value = item.gender;
  
  // 通过更改 key 强制组件重新渲染
  componentKey.value += 1;
};

单选框样式封装代码

<template>
  <div class="custom-image-radio-group">
    <label
        v-for="(option, index) in options"
        :key="index"
        class="custom-image-radio-label"
    >
      <input
          type="radio"
          :name="name"
          :value="option.value"
          v-model="selectedValue"
          class="custom-image-radio-input"
      >
      <!-- 未选中状态的图片 -->
      <img
          :src="option.uncheckedImg"
          alt="unchecked"
          class="custom-image-radio-img"
      >
      <span class="custom-image-radio-text">{{ option.label }}</span>
    </label>
  </div>
</template>

<script setup>
import {ref, defineProps, watch} from 'vue';

const props = defineProps({
  name: {
    type: String,
    required: true
  },
  options: {
    type: Array,
    required: true,
    default: () => [
      {
        label: '男',
        value: '0',
        uncheckedImg: require('@/assets/image/patient/no.png'), // 替换实际图片路径
        checkedImg: require('@/assets/image/patient/yes.png')
      },
      {
        label: '女',
        value: '1',
        uncheckedImg: require('@/assets/image/patient/no.png'),
        checkedImg: require('@/assets/image/patient/yes.png')
      }
    ]
  },
  modelValue: {
    type: String,
    default: ''
  }
});

// eslint-disable-next-line no-undef
const emits = defineEmits(['update:modelValue']);

const selectedValue = ref(props.modelValue);

watch(selectedValue, (newVal) => {
  emits('update:modelValue', newVal);
});
</script>

<style scoped>
.custom-image-radio-group {
  display: flex;
  align-items: center;
}

.custom-image-radio-label {
  display: flex;
  align-items: center;
  margin-right: 20px;
  cursor: pointer;
}

.custom-image-radio-input {
  display: none; /* 隐藏原生单选框 */
}

.custom-image-radio-img {
  width: 20px; /* 根据实际图片调整大小 */
  height: 20px;
  margin-right: 5px;
  transition: opacity 0.3s ease;
}

/* 选中状态切换图片 */
.custom-image-radio-input:checked + .custom-image-radio-img {
  content: url('@/assets/image/patient/yes.png'); /* 男的选中图,实际要根据选项动态处理,这里只是示例思路,下面会优化 */
  /* 实际更灵活的做法是结合动态绑定,这里先简单演示,完整优化见下方说明 */
}

.custom-image-radio-text {
  font-size: 14px;
}
</style>

网站公告

今日签到

点亮在社区的每一天
去签到