|
|
@@ -0,0 +1,160 @@
|
|
|
+<template>
|
|
|
+ <div class="color-picker-wrapper">
|
|
|
+ <el-color-picker
|
|
|
+ :model-value="confirmedColor"
|
|
|
+ @change="handleColorConfirm"
|
|
|
+ :size="size"
|
|
|
+ :predefine="predefineColors"
|
|
|
+ v-bind="$attrs"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+export default {
|
|
|
+ name: 'ColorPickerWithRecent',
|
|
|
+ props: {
|
|
|
+ modelValue: {
|
|
|
+ type: String,
|
|
|
+ default: ''
|
|
|
+ },
|
|
|
+ size: {
|
|
|
+ type: String,
|
|
|
+ default: 'default'
|
|
|
+ },
|
|
|
+ // 默认预设颜色
|
|
|
+ defaultPredefine: {
|
|
|
+ type: Array,
|
|
|
+ default: () => ['#FFFFFF', '#000000', '#FF0000', '#00FF00', '#0000FF', '#FFFF00', '#FF00FF', '#00FFFF']
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ // 全局最近使用的颜色(所有实例共享)
|
|
|
+ recentColors: [],
|
|
|
+ // 已确认的颜色(只有点击OK后才更新)
|
|
|
+ confirmedColor: this.modelValue
|
|
|
+ }
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ // 合并最近使用颜色和默认颜色
|
|
|
+ predefineColors() {
|
|
|
+ // 如果有最近使用的颜色,优先显示最近使用的 + 默认颜色
|
|
|
+ if (this.recentColors.length > 0) {
|
|
|
+ // 合并并去重
|
|
|
+ const combined = [...this.recentColors, ...this.defaultPredefine];
|
|
|
+ return [...new Set(combined)].slice(0, 10); // 限制总数量
|
|
|
+ }
|
|
|
+ // 如果没有最近使用的颜色,只显示默认颜色
|
|
|
+ return this.defaultPredefine;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ // 处理颜色确认(用户点击OK按钮)
|
|
|
+ handleColorConfirm(color) {
|
|
|
+ if (color) {
|
|
|
+ // 添加到最近使用的颜色列表
|
|
|
+ this.addToRecentColors(color);
|
|
|
+
|
|
|
+ // 更新已确认的颜色(CSS会自动更新显示)
|
|
|
+ this.confirmedColor = color;
|
|
|
+
|
|
|
+ // 触发父组件的change事件
|
|
|
+ this.$emit('update:modelValue', color);
|
|
|
+ this.$emit('change', color);
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 添加颜色到最近使用列表
|
|
|
+ addToRecentColors(color) {
|
|
|
+ // 使用全局存储,确保所有实例同步
|
|
|
+ const globalRecentColors = this.getGlobalRecentColors();
|
|
|
+
|
|
|
+ // 移除已存在的相同颜色
|
|
|
+ const filtered = globalRecentColors.filter(c => c !== color);
|
|
|
+
|
|
|
+ // 添加到列表开头
|
|
|
+ const newColors = [color, ...filtered].slice(0, 10); // 最多保留10个
|
|
|
+
|
|
|
+ // 更新全局存储
|
|
|
+ this.setGlobalRecentColors(newColors);
|
|
|
+
|
|
|
+ // 更新当前实例的数据
|
|
|
+ this.recentColors = newColors;
|
|
|
+
|
|
|
+ // 通知其他实例更新
|
|
|
+
|
|
|
+
|
|
|
+ this.notifyOtherInstances(newColors);
|
|
|
+ },
|
|
|
+
|
|
|
+ // 获取全局最近颜色
|
|
|
+ getGlobalRecentColors() {
|
|
|
+ try {
|
|
|
+ const stored = localStorage.getItem('canvasEditorRecentColors');
|
|
|
+ return stored ? JSON.parse(stored) : [];
|
|
|
+ } catch (error) {
|
|
|
+ console.warn('Failed to load recent colors from localStorage:', error);
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 设置全局最近颜色
|
|
|
+ setGlobalRecentColors(colors) {
|
|
|
+ try {
|
|
|
+ localStorage.setItem('canvasEditorRecentColors', JSON.stringify(colors));
|
|
|
+ } catch (error) {
|
|
|
+ console.warn('Failed to save recent colors to localStorage:', error);
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 通知其他实例更新
|
|
|
+ notifyOtherInstances(colors) {
|
|
|
+ // 通过自定义事件通知其他ColorPickerWithRecent实例
|
|
|
+ window.dispatchEvent(new CustomEvent('colorPickerRecentColorsUpdate', {
|
|
|
+ detail: { colors }
|
|
|
+ }));
|
|
|
+ },
|
|
|
+
|
|
|
+ // 监听其他实例的颜色更新
|
|
|
+ handleGlobalColorsUpdate(event) {
|
|
|
+ this.recentColors = event.detail.colors;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ // 监听父组件传入的modelValue变化
|
|
|
+ modelValue: {
|
|
|
+ handler(newValue) {
|
|
|
+ this.confirmedColor = newValue;
|
|
|
+ },
|
|
|
+ immediate: true
|
|
|
+ }
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ // 组件挂载时从localStorage加载最近使用的颜色
|
|
|
+ this.recentColors = this.getGlobalRecentColors();
|
|
|
+
|
|
|
+ // 监听其他实例的颜色更新事件
|
|
|
+ window.addEventListener('colorPickerRecentColorsUpdate', this.handleGlobalColorsUpdate);
|
|
|
+ },
|
|
|
+ beforeUnmount() {
|
|
|
+ // 组件销毁前移除事件监听
|
|
|
+ window.removeEventListener('colorPickerRecentColorsUpdate', this.handleGlobalColorsUpdate);
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+.color-picker-wrapper {
|
|
|
+ --picker-color: v-bind(confirmedColor);
|
|
|
+}
|
|
|
+
|
|
|
+.color-picker-wrapper :deep(.el-color-picker__color-inner) {
|
|
|
+ background-color: var(--picker-color) !important;
|
|
|
+}
|
|
|
+
|
|
|
+/* 确保在所有情况下都应用这个样式 */
|
|
|
+.color-picker-wrapper :deep(.el-color-picker) {
|
|
|
+ --el-color-primary: var(--picker-color);
|
|
|
+}
|
|
|
+</style>
|