组件通过v-model:XXXX实现数据双向绑定 ★ ★ ★ ★ ★

组件通过v-model:XXXX实现数据双向绑定,更新的时候通过emit("update:XXXX")向外抛出数据,即可被v-model绑定。

父组件:

 <emergencyLevelSelector v-model:emergency-level="taskData.emergencyLevel" />

子组件:

const props = defineProps({
  emergencyLevel: {
    type: String,
  },
})
const emit = defineEmits(["update:emergencyLevel"]);

//向外部抛出数据 emit("update:XXXXX", emergencyLevelItem.value)
const emergencyLevelChange = () => {
  emit("update:emergencyLevel", emergencyLevelItem.value)
}

=================================================================

案例:项目:gench.projectmanage.pc
E:\shimily\project\gench.projectmanage\gench.projectmanage.pc\src\views\components\emergencyLevelSelector.vue

父组件:moduleTask.vue

<a-form-item label="" name="emergencyLevel" :rules="[{ required: true, message: '请选择紧急程度', trigger: ['blur'] }]">
   <emergencyLevelSelector v-model:emergency-level="taskData.emergencyLevel" />
</a-form-item>

emergencyLevelSelector.vue

<template>
  <a-dropdown :trigger="['click']">
    <div class="emergency-selector">
      <HourglassOutlined class="emergency-icon-default"
        :style="{ color: getEmergencyLevelColorByKey(), borderColor: getEmergencyLevelColorByKey() }" />
      <div class="emergency-icon-content">
        <div class="emergency-status-value">{{ getEmergencyLevelLabelByKey() }}</div>
        <div class="emergency-status-label">紧急程度</div>
      </div>
    </div>
    <template #overlay>
      <a-menu @click="handleEmergencyLevel">
        <a-menu-item v-for="item in options" :key="item.value">
          {{ item.label }}
        </a-menu-item>
      </a-menu>
    </template>
  </a-dropdown>
</template>

<script setup lang="ts">
import { onMounted, ref, watch } from 'vue'
import { useDict } from '../../pinia';
const dict: any = useDict();
const props = defineProps({
  emergencyLevel: {
    type: String,
  },
})

const emergencyLevelItem: any = ref(props.emergencyLevel)
const emit = defineEmits(["update:emergencyLevel"]);
watch(() => props.emergencyLevel, (newVal, oldVal) => {
  emergencyLevelItem.value = newVal;
}, {
  deep: true,
})

const handleEmergencyLevel = ({ key }) => {
  emergencyLevelItem.value = key;
  emergencyLevelChange();
}

const getEmergencyLevelLabelByKey = () => {
  let findObj = options.value.find(obj => obj.value == emergencyLevelItem.value)
  return findObj ? findObj.label : "未选择"
}

const colorList = ["#1677ff", "#52c41a", "#fadb14", "#fa8c16", "#f5222d"]
const getEmergencyLevelColorByKey = () => {
  let findObj = options.value.find(obj => obj.value == emergencyLevelItem.value)
  return findObj ? colorList[emergencyLevelItem.value] : "#dadada"
}

const emergencyLevelChange = () => {
  emit("update:emergencyLevel", emergencyLevelItem.value)
}

const options: any = ref(dict.emergencyLevelTypes);


</script>

<style>
.emergency-selector {
  display: inline-flex;
  align-items: center;
  justify-content: flex-start;
}

.emergency-icon-content {
  margin-left: 10px;
  margin-right: 24px;
}

.emergency-icon-default {
  font-size: 24px;
  border: 3px dashed;
  border-radius: 50%;
  padding: 5px;
}

.emergency-status-value {
  font-size: 14px;
  line-height: 22px;
}

.emergency-status-label {
  color: #999;
}
</style>

  

 

posted @ 2024-06-25 08:46  Shimily  阅读(10)  评论(0)    收藏  举报