| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458 |
- <template>
- <div class="pcEdit">
- <div class="pcEdit-pages">
- <el-header class="flex items-center h-[50px] bg-primary px-[20px]">
- <div class="text-white cursor-pointer flex items-center" @click="goBack">
- <el-icon size="14">
- <ArrowLeft />
- </el-icon>
- <span class="pl-[5px] text-[14px]">返回</span>
- </div>
- <div class="text-white ml-[10px] mr-[20px] flex items-center">
- <span class="mr-[5px] text-[rgba(255,255,255,.5)]">|</span>
- <span class="mr-[5px] text-[14px]">正在装修:{{ query.title || '页面名字' }}</span>
- </div>
- <div class="flex-1"></div>
- <el-button @click="preview()">保存并预览</el-button>
- <el-button @click="save()">保存</el-button>
- </el-header>
- <div class="full-container flex flex-row flex-1 bg-page">
- <div class="component-list w-[192px]">
- <!-- 组件列表区域 -->
- <el-collapse v-model="activeNames" @change="handleChange">
- <el-collapse-item v-for="(item, key) in collapse" :key="key" :title="item.name" :name="key">
- <ul class="flex flex-row flex-wrap">
- <li
- v-for="(compItem, compKey) in item.list"
- :key="compKey"
- class="w-2/4 text-center cursor-pointer h-[65px]"
- :title="compItem.name"
- @click="diyStore.addComponent(compItem, compKey)"
- >
- <icon v-if="compItem.icon" :name="compItem.icon" size="20px" class="inline-block mt-[3px]" />
- <icon v-else name="iconfont iconkaifazujian" size="20px" class="inline-block mt-[3px]" />
- <span class="block text-[12px] truncate">{{ compItem.name }}</span>
- </li>
- </ul>
- </el-collapse-item>
- </el-collapse>
- </div>
- <div class="preview-wrap">
- <!-- 组件编辑区域 -->
- <div class="preview-pages shadow-lg">
- <!-- @end="onDragEnd" -->
- <draggable v-model="diyStore.componentList" item-key="itemKey" class="drag-area">
- <template #item="{ element, index }">
- <div @click="diyStore.onComponent(element, index)" class="component-bos">
- <div class="component-box" :style="{ borderWidth: diyStore.currentIndex == index ? '2px' : '0px' }"></div>
- <component :is="element.components" :key="element.itemKey" :index="index"></component>
- </div>
- </template>
- </draggable>
- </div>
- </div>
- <!-- 编辑组件属性区域 -->
- <div class="edit-attribute-wrap w-[400px]">
- <!-- 编辑组件属性区域 -->
- <el-scrollbar>
- <el-card class="box-card" shadow="never">
- <template #header>
- <div class="card-header flex justify-between items-center">
- <span class="title flex-1">{{ diyStore.currentIndex == -99 ? '页面设置' : diyStore.editComponent.name }}</span>
- <div class="tab-wrap flex rounded-[50px] bg-gray-100 text-[14px]">
- <span
- class="cursor-pointer rounded-[50px] py-[5px] px-[15px]"
- :class="{ 'bg-primary text-white': diyStore.editTab == 'content' }"
- @click="diyStore.editTab = 'content'"
- >内容</span
- >
- <span
- class="cursor-pointer rounded-[50px] py-[5px] px-[15px]"
- :class="{ 'bg-primary text-white': diyStore.editTab == 'style' }"
- @click="diyStore.editTab = 'style'"
- >样式</span
- >
- </div>
- </div>
- </template>
- <div class="edit-component-wrap">
- <component
- v-if="diyStore.currentKey"
- :is="diyStore.editComponent.edit"
- :key="diyStore.currentIndex"
- :value="diyStore.componentList[diyStore.currentIndex]"
- >
- <template #style>
- <div class="edit-attr-item-wrap">
- <h3 class="mb-[10px]">组件样式</h3>
- <el-form label-width="90px" class="px-[10px]">
- <template v-if="diyStore.editComponent.ignore.indexOf('pageBgColor') == -1">
- <el-form-item label="底部背景">
- <el-color-picker v-model="diyStore.editComponent.pageStartBgColor" show-alpha :predefine="diyStore.predefineColors" />
- <icon name="iconfont iconmap-connect" size="20px" class="block !text-gray-400 mx-[5px]" />
- <el-color-picker v-model="diyStore.editComponent.pageEndBgColor" show-alpha :predefine="diyStore.predefineColors" />
- </el-form-item>
- <div class="text-sm text-gray-400 ml-[90px] mb-[10px]">底部背景包含边距和圆角</div>
- </template>
- <el-form-item label="渐变角度" v-if="diyStore.editComponent.ignore.indexOf('pageBgColor') == -1">
- <el-radio-group v-model="diyStore.editComponent.pageGradientAngle">
- <el-radio value="to bottom">从上到下</el-radio>
- <el-radio value="to right">从左到右</el-radio>
- </el-radio-group>
- </el-form-item>
- <el-form-item label="组件背景色" v-if="diyStore.editComponent.ignore.indexOf('componentBgColor') == -1">
- <el-color-picker v-model="diyStore.editComponent.componentStartBgColor" show-alpha :predefine="diyStore.predefineColors" />
- <icon name="iconfont iconmap-connect" size="20px" class="block !text-gray-400 mx-[5px]" />
- <el-color-picker v-model="diyStore.editComponent.componentEndBgColor" show-alpha :predefine="diyStore.predefineColors" />
- </el-form-item>
- <el-form-item label="渐变角度" v-if="diyStore.editComponent.ignore.indexOf('componentBgColor') == -1">
- <el-radio-group v-model="diyStore.editComponent.componentGradientAngle">
- <el-radio value="to bottom">从上到下</el-radio>
- <el-radio value="to right">从左到右</el-radio>
- </el-radio-group>
- </el-form-item>
- <el-form-item label="上边距" v-if="diyStore.editComponent.ignore.indexOf('marginTop') == -1">
- <el-slider
- v-model="diyStore.editComponent.padding.top"
- show-input
- size="small"
- :min="-100"
- class="ml-[10px] diy-nav-slider"
- />
- </el-form-item>
- <el-form-item label="下边距" v-if="diyStore.editComponent.ignore.indexOf('marginBottom') == -1">
- <el-slider
- v-model="diyStore.editComponent.padding.bottom"
- show-input
- size="small"
- class="ml-[10px] diy-nav-slider"
- :min="-100"
- />
- </el-form-item>
- <el-form-item label="左右边距" v-if="diyStore.editComponent.ignore.indexOf('marginBoth') == -1">
- <el-slider v-model="diyStore.editComponent.padding.both" show-input size="small" class="ml-[10px] diy-nav-slider" />
- </el-form-item>
- <el-form-item label="上圆角" v-if="diyStore.editComponent.ignore.indexOf('topRounded') == -1">
- <el-slider
- v-model="diyStore.editComponent.topRounded"
- show-input
- size="small"
- class="ml-[10px] diy-nav-slider"
- :max="100"
- />
- </el-form-item>
- <el-form-item label="下圆角" v-if="diyStore.editComponent.ignore.indexOf('bottomRounded') == -1">
- <el-slider
- v-model="diyStore.editComponent.bottomRounded"
- show-input
- size="small"
- class="ml-[10px] diy-nav-slider"
- :max="100"
- />
- </el-form-item>
- </el-form>
- </div>
- </template>
- </component>
- </div>
- </el-card>
- </el-scrollbar>
- <!-- <div v-for="(item, index) in diyStore.componentList" :key="index">
- <component v-if="item.itemKey == diyStore.currentKey" :is="item.edit" :value="item"> </component>
- </div> -->
- </div>
- </div>
- </div>
- </div>
- </template>
- <script setup name="Index" lang="ts">
- import { pcAddDiy } from '@/api/diy/index';
- import icon from '@/components/icon/index.vue';
- import draggable from 'vuedraggable';
- import usePcdiyStore from '@/store/modules/pcdiy';
- const diyStore = usePcdiyStore();
- const route = useRoute();
- const query = route.query;
- // 头部组件
- import head from '@/views/diy/pcPages/head.vue';
- const headRef = shallowRef(head);
- import headEdit from '@/views/diy/pcEdit/head-edit.vue';
- const headEditRef = shallowRef(headEdit);
- //文本标题
- import textTitle from '@/views/diy/pcPages/textTitle.vue';
- const ctextTitleRef = shallowRef(textTitle);
- import textTitleEdit from '@/views/diy/pcEdit/textTitle-edit.vue';
- const textTitleEditRef = shallowRef(textTitleEdit);
- //图文导航
- import navigation from '@/views/diy/pcPages/navigation.vue';
- const navigationRef = shallowRef(navigation);
- import navigationEdit from '@/views/diy/pcEdit/navigation-edit.vue';
- const navigationEditRef = shallowRef(navigationEdit);
- //图片魔方
- import imageCube from '@/views/diy/pcPages/imageCube.vue';
- const imageCubeRef = shallowRef(imageCube);
- import imageCubeEdit from '@/views/diy/pcEdit/imageCube-edit.vue';
- const imageCubeEditRef = shallowRef(imageCubeEdit);
- //轮播图
- import carousel from '@/views/diy/pcPages/carousel.vue';
- const carouselRef = shallowRef(carousel);
- import carouselEdit from '@/views/diy/pcEdit/carousel-edit.vue';
- const carouselEditRef = shallowRef(carouselEdit);
- //文章咨询
- import article from '@/views/diy/pcPages/article.vue';
- const articleRef = shallowRef(article);
- import articleEdit from '@/views/diy/pcEdit/article-edit.vue';
- const articleEditRef = shallowRef(articleEdit);
- //品牌组件
- import brand from '@/views/diy/pcPages/brand.vue';
- const brandeRef = shallowRef(brand);
- import brandEdit from '@/views/diy/pcEdit/brand-edit.vue';
- const brandEditRef = shallowRef(brandEdit);
- //图文广告
- import advert from '@/views/diy/pcPages/advert.vue';
- const advertRef = shallowRef(advert);
- import advertEdit from '@/views/diy/pcEdit/advert-edit.vue';
- const advertEditRef = shallowRef(advertEdit);
- //楼层组件
- import floor from '@/views/diy/pcPages/floor.vue';
- const floorRef = shallowRef(floor);
- import floorEdit from '@/views/diy/pcEdit/floor-edit.vue';
- const floorEditRef = shallowRef(floorEdit);
- //商品组件
- import goods from '@/views/diy/pcPages/goods.vue';
- const goodsRef = shallowRef(goods);
- import goodsEdit from '@/views/diy/pcEdit/goods-edit.vue';
- const goodsEditRef = shallowRef(goodsEdit);
- //多商品组
- import goodsList from '@/views/diy/pcPages/goodsList.vue';
- const goodsListRef = shallowRef(goodsList);
- import goodsListEdit from '@/views/diy/pcEdit/goodsList-edit.vue';
- const goodsListEditRef = shallowRef(goodsListEdit);
- //发现组件
- import discover from '@/views/diy/pcPages/discover.vue';
- const discoverRef = shallowRef(discover);
- import discoverEdit from '@/views/diy/pcEdit/discover-edit.vue';
- const discoverEditRef = shallowRef(discoverEdit);
- const itemKey = ref<any>(0);
- //左边得组件
- const uniqueIdCounter = ref<any>(0);
- const activeNames = ref<any>([0]);
- const collapse = ref<any>([
- {
- name: '基础组件',
- list: [
- {
- name: '头部组件',
- icon: 'iconfont iconfuwenbenpc',
- id: 1,
- components: markRaw(headRef.value),
- edit: markRaw(headEditRef.value)
- },
- {
- name: '文本标题',
- icon: 'iconfont iconbiaotipc',
- id: 2,
- components: markRaw(ctextTitleRef.value),
- edit: markRaw(textTitleEditRef.value)
- },
- {
- name: '图文导航',
- icon: 'iconfont icontuwendaohangpc',
- id: 3,
- components: markRaw(navigationRef.value),
- edit: markRaw(navigationEditRef.value)
- },
- {
- name: '图片魔方',
- icon: 'iconfont iconmofangpc',
- id: 4,
- components: markRaw(imageCubeRef.value),
- edit: markRaw(imageCubeEditRef.value)
- },
- {
- name: '活动魔方',
- icon: 'iconfont iconmofangpc',
- id: 5
- },
- {
- name: '轮播图',
- icon: 'iconfont icona-tupianzhanbopc302',
- id: 6,
- components: markRaw(carouselRef.value),
- edit: markRaw(carouselEditRef.value)
- },
- {
- name: '文章咨询',
- icon: 'iconfont icongonggaopc',
- id: 7,
- components: markRaw(articleRef.value),
- edit: markRaw(articleEditRef.value)
- },
- {
- name: '品牌组件',
- icon: 'iconfont iconmiaoshashangpin',
- id: 8,
- components: markRaw(brandeRef.value),
- edit: markRaw(brandEditRef.value)
- },
- {
- name: '图文广告',
- icon: 'iconfont icontupiandaohangpc',
- id: 9,
- components: markRaw(advertRef.value),
- edit: markRaw(advertEditRef.value)
- },
- {
- name: '楼层组件',
- icon: 'iconfont iconshangpinliebiaopc',
- id: 10,
- components: markRaw(floorRef.value),
- edit: markRaw(floorEditRef.value)
- },
- {
- name: '商品组件',
- icon: 'iconfont icona-shangpintuijianpc30',
- id: 11,
- components: markRaw(goodsRef.value),
- edit: markRaw(goodsEditRef.value)
- },
- {
- name: '多商品组',
- icon: 'iconfont iconduoshangpinzupc',
- id: 12,
- components: markRaw(goodsListRef.value),
- edit: markRaw(goodsListEditRef.value)
- },
- {
- name: '发现组件',
- icon: 'iconfont iconrequpc',
- id: 13,
- components: markRaw(discoverRef.value),
- edit: markRaw(discoverEditRef.value)
- }
- ]
- }
- ]);
- const componentList = ref<any>([
- // {
- // components: ctextTitleRef
- // }
- ]);
- const handleChange = (val: string[]) => {};
- // 返回上一页
- const goBack = () => {};
- // 预览
- const preview = () => {};
- // 保存
- const save = () => {
- const datas = {
- name: query.title,
- siteId: '',
- clientId: '',
- type: query.type,
- remark: '',
- previewPicUrls: '',
- property: JSON.stringify(diyStore.componentList),
- isHome: 1
- };
- const api = pcAddDiy;
- api(datas)
- .then((res: any) => {
- if (res.code == 200) {
- }
- })
- .catch(() => {});
- };
- </script>
- <style lang="scss" scoped>
- .pcEdit {
- width: 100%;
- overflow: auto;
- }
- .pcEdit-pages {
- min-height: calc(100vh - 84px);
- // min-width: 1900px;
- .full-container {
- height: calc(100vh - 134px);
- background-color: #f2f2f2;
- .component-list {
- height: 100%;
- background-color: #ffffff;
- padding: 0 10px;
- }
- .component-list ul li {
- &:not(.disabled):hover {
- color: var(--el-color-primary);
- background: var(--el-color-primary-light-9);
- }
- }
- .preview-wrap {
- flex: 1;
- display: flex;
- justify-content: center;
- .preview-pages {
- margin: 30px auto;
- width: 1300px;
- background: var(--el-bg-color-page);
- overflow: auto;
- height: calc(130vh - 194px);
- zoom: 0.7;
- // height: calc(100vh - 194px);
- /* 为了兼容某些情况,可能还需要配合 display */
- display: inline-block;
- }
- .component-bos {
- position: relative;
- .component-box {
- position: absolute;
- width: 100%;
- height: 100%;
- top: 0;
- left: 0;
- border: 2px solid var(--el-color-primary);
- z-index: 2;
- cursor: move;
- }
- }
- }
- //编辑组件属性区域
- .edit-attribute-wrap {
- background: var(--el-bg-color);
- }
- .edit-attribute-wrap .box-card {
- border: none;
- }
- .edit-attr-item-wrap {
- border-top: 2px solid var(--el-color-info-light-8);
- padding-top: 20px;
- &:first-of-type {
- border-top: none;
- padding-top: 0;
- }
- }
- }
- :deep(.el-header) {
- height: 50px;
- }
- }
- </style>
|