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