【代码优化】MALL: 修复模板装修时组件属性响应式丢失的问题

This commit is contained in:
puhui999 2025-01-18 17:47:10 +08:00
parent ae0cc94da0
commit 625426566c
4 changed files with 54 additions and 52 deletions

View File

@ -4,7 +4,7 @@
<div v-for="(cell, cellIndex) in cellList" :key="cellIndex" :style="getCellStyle(cell)"> <div v-for="(cell, cellIndex) in cellList" :key="cellIndex" :style="getCellStyle(cell)">
<span v-if="cell.type === 'text'">{{ cell.text }}</span> <span v-if="cell.type === 'text'">{{ cell.text }}</span>
<img v-else-if="cell.type === 'image'" :src="cell.imgUrl" alt="" class="h-full w-full" /> <img v-else-if="cell.type === 'image'" :src="cell.imgUrl" alt="" class="h-full w-full" />
<SearchBar v-else :property="getSearchProp" /> <SearchBar v-else :property="getSearchProp(cell)" />
</div> </div>
</div> </div>
<img <img
@ -51,14 +51,14 @@ const getCellStyle = (cell: NavigationBarCellProperty) => {
} as StyleValue } as StyleValue
} }
// //
const getSearchProp = (cell: NavigationBarCellProperty) => { const getSearchProp = computed(() => (cell: NavigationBarCellProperty) => {
return { return {
height: 30, height: 30,
showScan: false, showScan: false,
placeholder: cell.placeholder, placeholder: cell.placeholder,
borderRadius: cell.borderRadius borderRadius: cell.borderRadius
} as SearchProperty } as SearchProperty
} })
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.navigation-bar { .navigation-bar {

View File

@ -110,7 +110,7 @@
<el-tag <el-tag
v-if="showPageConfig" v-if="showPageConfig"
:effect="selectedComponent?.uid === pageConfigComponent.uid ? 'dark' : 'plain'" :effect="selectedComponent?.uid === pageConfigComponent.uid ? 'dark' : 'plain'"
:type="selectedComponent?.uid === pageConfigComponent.uid ? '' : 'info'" :type="selectedComponent?.uid === pageConfigComponent.uid ? 'primary' : 'info'"
size="large" size="large"
@click="handleComponentSelected(pageConfigComponent)" @click="handleComponentSelected(pageConfigComponent)"
> >
@ -121,7 +121,7 @@
<el-tag <el-tag
v-if="component.position === 'fixed'" v-if="component.position === 'fixed'"
:effect="selectedComponent?.uid === component.uid ? 'dark' : 'plain'" :effect="selectedComponent?.uid === component.uid ? 'dark' : 'plain'"
:type="selectedComponent?.uid === component.uid ? '' : 'info'" :type="selectedComponent?.uid === component.uid ? 'primary' : 'info'"
closable closable
size="large" size="large"
@click="handleComponentSelected(component)" @click="handleComponentSelected(component)"
@ -191,7 +191,7 @@ import { cloneDeep, includes } from 'lodash-es'
import { component as PAGE_CONFIG_COMPONENT } from '@/components/DiyEditor/components/mobile/PageConfig/config' import { component as PAGE_CONFIG_COMPONENT } from '@/components/DiyEditor/components/mobile/PageConfig/config'
import { component as NAVIGATION_BAR_COMPONENT } from './components/mobile/NavigationBar/config' import { component as NAVIGATION_BAR_COMPONENT } from './components/mobile/NavigationBar/config'
import { component as TAB_BAR_COMPONENT } from './components/mobile/TabBar/config' import { component as TAB_BAR_COMPONENT } from './components/mobile/TabBar/config'
import { isString } from '@/utils/is' import { isEmpty, isString } from '@/utils/is'
import { DiyComponent, DiyComponentLibrary, PageConfig } from '@/components/DiyEditor/util' import { DiyComponent, DiyComponentLibrary, PageConfig } from '@/components/DiyEditor/util'
import { componentConfigs } from '@/components/DiyEditor/components/mobile' import { componentConfigs } from '@/components/DiyEditor/components/mobile'
import { array, oneOfType } from 'vue-types' import { array, oneOfType } from 'vue-types'
@ -238,24 +238,42 @@ const props = defineProps({
watch( watch(
() => props.modelValue, () => props.modelValue,
() => { () => {
const modelValue = isString(props.modelValue) const modelValue =
? (JSON.parse(props.modelValue) as PageConfig) isString(props.modelValue) && !isEmpty(props.modelValue)
: props.modelValue ? (JSON.parse(props.modelValue) as PageConfig)
pageConfigComponent.value.property = modelValue?.page || PAGE_CONFIG_COMPONENT.property : props.modelValue
pageConfigComponent.value.property =
(typeof modelValue !== 'string' && modelValue?.page) || PAGE_CONFIG_COMPONENT.property
navigationBarComponent.value.property = navigationBarComponent.value.property =
modelValue?.navigationBar || NAVIGATION_BAR_COMPONENT.property (typeof modelValue !== 'string' && modelValue?.navigationBar) ||
tabBarComponent.value.property = modelValue?.tabBar || TAB_BAR_COMPONENT.property NAVIGATION_BAR_COMPONENT.property
tabBarComponent.value.property =
(typeof modelValue !== 'string' && modelValue?.tabBar) || TAB_BAR_COMPONENT.property
// //
pageComponents.value = (modelValue?.components || []).map((item) => { pageComponents.value = ((typeof modelValue !== 'string' && modelValue?.components) || []).map(
const component = componentConfigs[item.id] (item) => {
return { ...component, property: item.property } const component = componentConfigs[item.id]
}) return { ...component, property: item.property }
}
)
}, },
{ {
immediate: true immediate: true
} }
) )
/** 选择组件修改其属性后更新它的配置 */
watch(
selectedComponent,
(val: any) => {
if (!val || selectedComponentIndex.value === -1) {
return
}
pageComponents.value[selectedComponentIndex.value] = selectedComponent.value!
},
{ deep: true }
)
// //
const handleSave = () => { const handleSave = () => {
// //

View File

@ -1,7 +1,7 @@
<template> <template>
<el-input v-model="valueRef" v-bind="$attrs"> <el-input v-model="modelValue" v-bind="$attrs">
<template #append> <template #append>
<el-color-picker v-model="colorRef" :predefine="PREDEFINE_COLORS" /> <el-color-picker v-model="color" :predefine="PREDEFINE_COLORS" />
</template> </template>
</el-input> </el-input>
</template> </template>
@ -9,6 +9,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import { propTypes } from '@/utils/propTypes' import { propTypes } from '@/utils/propTypes'
import { PREDEFINE_COLORS } from '@/utils/color' import { PREDEFINE_COLORS } from '@/utils/color'
import { useVModels } from '@vueuse/core'
/** /**
* 带颜色选择器输入框 * 带颜色选择器输入框
@ -19,33 +20,8 @@ const props = defineProps({
modelValue: propTypes.string.def('').isRequired, modelValue: propTypes.string.def('').isRequired,
color: propTypes.string.def('').isRequired color: propTypes.string.def('').isRequired
}) })
watch(
() => props.modelValue,
(val: string) => {
if (val === unref(valueRef)) return
valueRef.value = val
}
)
const emit = defineEmits(['update:modelValue', 'update:color']) const emit = defineEmits(['update:modelValue', 'update:color'])
const { modelValue, color } = useVModels(props, emit)
//
const valueRef = ref(props.modelValue)
watch(
() => valueRef.value,
(val: string) => {
emit('update:modelValue', val)
}
)
//
const colorRef = ref(props.color)
watch(
() => colorRef.value,
(val: string) => {
emit('update:color', val)
}
)
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
:deep(.el-input-group__append) { :deep(.el-input-group__append) {

View File

@ -52,7 +52,9 @@ const formLoading = ref(false) // 表单的加载中1修改时的数据加
const formData = ref<DiyTemplateApi.DiyTemplatePropertyVO>() const formData = ref<DiyTemplateApi.DiyTemplatePropertyVO>()
const formRef = ref() // Ref const formRef = ref() // Ref
// //
const currentFormData = ref<DiyTemplateApi.DiyTemplatePropertyVO | DiyPageApi.DiyPageVO>() const currentFormData = ref<DiyTemplateApi.DiyTemplatePropertyVO | DiyPageApi.DiyPageVO>({
property: ''
} as DiyPageApi.DiyPageVO)
// templateItem // templateItem
const currentFormDataMap = ref< const currentFormDataMap = ref<
Map<string, DiyTemplateApi.DiyTemplatePropertyVO | DiyPageApi.DiyPageVO> Map<string, DiyTemplateApi.DiyTemplatePropertyVO | DiyPageApi.DiyPageVO>
@ -92,17 +94,21 @@ const handleTemplateItemChange = (val: number) => {
// //
if (val === 0) { if (val === 0) {
libs.value = templateLibs libs.value = templateLibs
currentFormData.value = isEmpty(data) ? formData.value : data currentFormData.value = (isEmpty(data) ? formData.value : data) as
| DiyTemplateApi.DiyTemplatePropertyVO
| DiyPageApi.DiyPageVO
return return
} }
// //
libs.value = PAGE_LIBS libs.value = PAGE_LIBS
currentFormData.value = isEmpty(data) currentFormData.value = (
? formData.value!.pages.find( isEmpty(data)
(page: DiyPageApi.DiyPageVO) => page.name === templateItems[val].name ? formData.value!.pages.find(
) (page: DiyPageApi.DiyPageVO) => page.name === templateItems[val].name
: data )
: data
) as DiyTemplateApi.DiyTemplatePropertyVO | DiyPageApi.DiyPageVO
} }
// //
@ -170,7 +176,9 @@ const recoverPageIndex = () => {
sessionStorage.removeItem(DIY_PAGE_INDEX_KEY) sessionStorage.removeItem(DIY_PAGE_INDEX_KEY)
// //
currentFormData.value = formData.value currentFormData.value = formData.value as
| DiyTemplateApi.DiyTemplatePropertyVO
| DiyPageApi.DiyPageVO
currentFormDataMap.value = new Map< currentFormDataMap.value = new Map<
string, string,
DiyTemplateApi.DiyTemplatePropertyVO | DiyPageApi.DiyPageVO DiyTemplateApi.DiyTemplatePropertyVO | DiyPageApi.DiyPageVO