huangyinfeng
6 天以前 a9a03d64cf190188d3db04d14970fc0908b03491
提交 | 用户 | age
63d608 1 <template>
H 2   <div class="my-radio-group" v-if="type == 1">
3     <a-radio-group v-model:value="localValue" button-style="solid" size="small" name="color">
4       <a-radio-button
5         v-for="item in colors"
6         :key="item.type_id"
7         class="mr-5px"
8         :value="item.color"
9         :style="{ backgroundColor: item.color, borderColor: item.color }"
10       >
11         <span :class="localValue === item.color ? 'c-white' : 'c-white select-none op0'">✓</span>
12       </a-radio-button>
13     </a-radio-group>
14   </div>
15   <div v-else>
16     <a-dropdown :trigger="['click']">
17       <div @click.prevent>
18         <div style="display: flex; align-items: center">
19           <div class="bookmark" :style="{ backgroundColor: localValue }"></div>
20           <DownOutlined />
21         </div>
22       </div>
23       <template #overlay>
24         <a-menu class="my-radio-group" style="width: 154px">
25           <a-menu-item key="0">
26             <a-radio-group
27               v-model:value="localValue"
28               button-style="solid"
29               size="small"
30               name="color"
a9a03d 31               @change="groupChange"
63d608 32             >
H 33               <a-radio-button
34                 v-for="item in colors"
35                 :key="item.type_id"
36                 class="mr-5px"
37                 :value="item.color"
38                 :style="{ backgroundColor: item.color, borderColor: item.color }"
39               >
40                 <span :class="localValue === item.color ? 'c-white' : 'c-white select-none op0'"
41                   >✓</span
42                 >
43               </a-radio-button>
44             </a-radio-group>
45           </a-menu-item>
46         </a-menu>
47       </template>
48     </a-dropdown>
49   </div>
50 </template>
51
52 <script lang="ts" setup>
53   import { ref, watch, defineProps, defineEmits } from 'vue';
54   import { DownOutlined } from '@ant-design/icons-vue';
55   // 定义 props,接收父组件传递的 modelValue
56   const props = defineProps({
57     modelValue: {
58       type: String,
a9a03d 59       default: '#000000',
63d608 60       required: true,
H 61     },
62     // 1普通,2选择器模式
63     type: {
64       type: Number,
65       default: 0,
66       required: true,
67     },
68   });
69
70   // 定义 emits,用于双向绑定
a9a03d 71   const emit = defineEmits(['update:modelValue', 'change']);
63d608 72
H 73   // 颜色选项
74   const colors = ref([
75     { type_id: 1, color: '#000000', name: '黑' },
76     { type_id: 2, color: '#bc5959', name: '暗红' },
77     { type_id: 3, color: '#d87538', name: '橙红' },
78     { type_id: 4, color: '#209890', name: '青绿' }, // 被选中的颜色
79     { type_id: 5, color: '#4b679d', name: '深蓝' },
80     { type_id: 6, color: '#595dbf', name: '蓝紫' },
81     { type_id: 7, color: '#333333', name: '深灰' },
82     { type_id: 8, color: '#e43e3e', name: '红' },
83     { type_id: 9, color: '#eb9955', name: '浅橙' },
84     { type_id: 10, color: '#61bc81', name: '浅绿' },
85     { type_id: 11, color: '#5d89e9', name: '浅蓝' },
86     { type_id: 12, color: '#8d54bd', name: '紫' },
87     { type_id: 13, color: '#7b8291', name: '蓝灰' },
88     { type_id: 14, color: '#ee7b7b', name: '粉红' },
89     { type_id: 15, color: '#e2ad28', name: '金黄' },
90     { type_id: 16, color: '#80c463', name: '草绿' },
91     { type_id: 17, color: '#4aa8eb', name: '天蓝' },
92     { type_id: 18, color: '#acacac', name: '浅灰' },
93   ]);
94
95   // 定义本地状态,以便监听和更新
96   const localValue = ref(props.modelValue);
97
98   // 监听 modelValue 的变化,并同步更新本地值
99   watch(
100     () => props.modelValue,
101     (newValue) => {
102       localValue.value = newValue;
103     },
104   );
105
106   // 当本地值发生变化时,发出 update:modelValue 事件,通知父组件更新
107   watch(localValue, (newValue) => {
108     emit('update:modelValue', newValue);
a9a03d 109     // emit('change', newValue);
63d608 110   });
a9a03d 111
H 112   function groupChange() {
113     console.log(localValue.value, '------------2');
114     emit('change', localValue.value);
115   }
63d608 116 </script>
H 117
118 <style lang="less" scoped>
119   .mr-5px {
120     margin-right: 5px;
121   }
122
123   .c-white {
124     color: white;
125   }
126
127   .select-none {
128     user-select: none;
129   }
130
131   .op0 {
132     opacity: 0;
133   }
134
135   .my-radio-group {
136     :deep(.ant-radio-group) .ant-radio-button-wrapper::before {
137       width: 0;
138     }
139   }
140
141   .mr-5px {
142     margin-top: 4px;
143     border-radius: 4px;
144   }
145
146   .bookmark {
147     display: inline-block;
148     position: relative;
149     width: 14px;
150     height: 18px;
151     margin-right: 5px;
152     border-radius: 2px 2px 0 0; /* Rounded top corners */
153   }
154
155   .bookmark::after {
156     content: '';
157     position: absolute;
158     right: 0;
159     bottom: 0;
160     left: 0;
161     height: 8px;
162     background-color: #fff;
163     clip-path: polygon(50% 60%, 0% 100%, 100% 100%); /* Triangle at the bottom */
164   }
165 </style>