| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- <template>
- <div class="background-selector">
- <template v-if="isCanvas">
- <el-radio-group v-model="bgType" class="bg-type-radio" size="small">
- <el-radio-button label="image">图片</el-radio-button>
- <el-radio-button label="color">纯色</el-radio-button>
- </el-radio-group>
- <div class="bg-section" v-if="bgType === 'image'">
- <div class="bg-label">选择背景图片</div>
- <MediaFileSelector v-model="mediaId" accept="image/*" :single="true" :onlyImage="true" />
- </div>
- <div class="bg-section" v-else>
- <div class="bg-label">选择纯色背景</div>
- <el-color-picker v-model="color" />
- </div>
- </template>
- <template v-else>
- <div class="bg-section">
- <div class="bg-label">选择颜色</div>
- <el-color-picker v-model="color" />
- </div>
- </template>
- </div>
- </template>
- <script setup lang="ts">
- import { ref, watch, computed } from 'vue';
- import MediaFileSelector from './MediaFileSelector.vue';
- const props = defineProps<{
- modelValue: string; // bg 字段,canvas 可能是图片url或颜色,其他组件为颜色
- isCanvas?: boolean; // 是否画布
- }>();
- const emit = defineEmits(['update:modelValue', 'change']);
- const bgType = ref<'image' | 'color'>('color');
- const mediaId = ref<string | null>(null);
- const color = ref<string>(props.modelValue || '#ffffff');
- // 初始化类型
- if (props.isCanvas) {
- if (props.modelValue && /^https?:\/\//.test(props.modelValue)) {
- bgType.value = 'image';
- mediaId.value = props.modelValue;
- } else {
- bgType.value = 'color';
- color.value = props.modelValue || '#ffffff';
- }
- }
- // 切换类型时同步
- watch(bgType, (val) => {
- if (val === 'image') {
- if (mediaId.value) {
- emit('update:modelValue', mediaId.value);
- emit('change', mediaId.value);
- }
- } else {
- emit('update:modelValue', color.value);
- emit('change', color.value);
- }
- });
- // 监听图片选择
- watch(mediaId, (val) => {
- if (bgType.value === 'image' && val) {
- emit('update:modelValue', val);
- emit('change', val);
- }
- });
- // 监听颜色选择
- watch(color, (val) => {
- if (bgType.value === 'color') {
- emit('update:modelValue', val);
- emit('change', val);
- }
- });
- // 外部变更时同步内部
- watch(
- () => props.modelValue,
- (val) => {
- if (props.isCanvas) {
- if (val && /^https?:\/\//.test(val)) {
- bgType.value = 'image';
- mediaId.value = val;
- } else {
- bgType.value = 'color';
- color.value = val || '#ffffff';
- }
- } else {
- color.value = val || '#ffffff';
- }
- }
- );
- </script>
- <style scoped>
- .background-selector {
- display: flex;
- flex-direction: column;
- gap: 6px;
- }
- .bg-section {
- margin-bottom: 6px;
- }
- .bg-label {
- font-size: 13px;
- color: #888;
- margin-bottom: 2px;
- }
- .bg-type-radio {
- margin-bottom: 8px;
- }
- </style>
|