liyongli 2 년 전
부모
커밋
46d93dd97a

+ 46 - 24
src/view/allMedia/H5Editor.vue

@@ -1,8 +1,20 @@
 <template>
   <div class="H5Editor">
-    <div class="H5Editor_left">
-        <component v-show="H5Editor" :is="H5EditorObj[H5Editor.type]"  :item="H5Editor"></component>
-    </div>
+    <van-popup
+      v-model:show="leftEle"
+      position="left"
+      :style="{
+        width: '300px',
+        'background-color': '#f3f3f3',
+        height: '100%',
+      }"
+    >
+      <component
+        v-if="H5Editor && leftEle"
+        :is="H5EditorObj[H5Editor.type]"
+        :item="H5Editor"
+      ></component>
+    </van-popup>
     <div class="H5Editor_center">
       <div class="pageClient">
         <div class="page">
@@ -33,10 +45,16 @@
                   <h5-van-field
                     v-if="v.type === 'van-field'"
                     :item="v"
+                    @click="
+                      () => selectComponent({ ...v, leftEle: true }, index)
+                    "
                   ></h5-van-field>
                   <h5-van-buttom
                     v-if="v.type === 'van-buttom'"
                     :item="v"
+                    @click="
+                      () => selectComponent({ ...v, leftEle: true }, index)
+                    "
                   ></h5-van-buttom>
                 </template>
               </h5-from-component>
@@ -71,16 +89,23 @@ import H5VanField from './components/H5Editor/van_field.vue';
 import H5VanButtom from './components/H5Editor/van_buttom.vue';
 
 // 左侧编辑模块组件
-import H5ImgEditor from "./components/H5Editor/imgEditor";
+import H5ImgEditor from './components/H5EditorLeft/imgEditor';
+import H5VanFieldLeft from './components/H5EditorLeft/vanField';
+import H5VanButtomLeft from './components/H5EditorLeft/vanButtom';
 
 const H5EditorObj = {
-    H5ImgEditor
-}
+  H5ImgEditor,
+  H5VanFieldLeft,
+  H5VanButtomLeft,
+};
 const H5EditorObjEle = {
-    "image": "H5ImgEditor"
-}
+  image: 'H5ImgEditor',
+  'van-field': 'H5VanFieldLeft',
+  'van-buttom': 'H5VanButtomLeft',
+};
 
 const H5Editor = ref({});
+const leftEle = ref(false);
 const route = useRoute();
 const item = JSON.parse(route.query.item || '{}');
 const selectPage = ref(0);
@@ -89,6 +114,11 @@ const page = ref({ width: 375, height: 0 });
 const selectPageFunc = (index = 0) => {
   selectPage.value = index;
 };
+const selectComponent = v => {
+  const type = H5EditorObjEle[v.type];
+  H5Editor.value = { item: v, type };
+  leftEle.value = v.leftEle || false;
+};
 
 // 查看页面大小,
 const img = new Image();
@@ -116,18 +146,16 @@ const saveParagraph = (paragraph, index) => {
 
 // provide 传递方法
 provide('starEditorFormwork', value => {
-    const type = H5EditorObjEle[value.type];
-    value.type = type;
-    H5Editor.value = value;
+  selectComponent(value);
 });
 
-provide("saveComponents", value => {
-    console.log(value);
-})
+provide('saveComponents', value => {
+  console.log(value);
+});
 
-provide("deleteItemComponents", value => {
-    console.log(value);
-})
+provide('deleteItemComponents', value => {
+  console.log(value);
+});
 </script>
 
 <style scoped>
@@ -144,7 +172,6 @@ provide("deleteItemComponents", value => {
   min-width: 1200px;
 }
 
-.H5Editor_left,
 .H5Editor_center,
 .H5Editor_right {
   display: inline-block;
@@ -152,7 +179,7 @@ provide("deleteItemComponents", value => {
 }
 
 .H5Editor_center {
-  width: calc(100% - 600px);
+  width: calc(100% - 300px);
   position: relative;
 }
 
@@ -186,11 +213,6 @@ provide("deleteItemComponents", value => {
   background-color: #f3f3f3;
 }
 
-.H5Editor_left {
-  width: 300px;
-  background-color: #f3f3f3;
-}
-
 .H5Editor_right .selectPage {
   border: 3px solid #409eff;
 }

+ 1 - 1
src/view/allMedia/components/H5Editor/from.vue

@@ -1,6 +1,6 @@
 <template>
   <div>
-    <van-form class="pragraph" disabled>
+    <van-form class="pragraph">
       <van-cell-group inset>
         <div
           class="text"

+ 2 - 1
src/view/allMedia/components/H5Editor/img.vue

@@ -28,7 +28,8 @@ const outStyle = () => {
 
 const editorFunc = () => {
     const p = {
-        ...props.item
+        ...props.item,
+        leftEle: true
     }
     if(oriUrl.value) p.src = oriUrl.value;
     starEditorFormwork(p);

+ 7 - 2
src/view/allMedia/components/H5Editor/paragraph.vue

@@ -1,6 +1,6 @@
 <template>
   <div>
-    <van-cell-group inset class="pragraph">
+    <van-cell-group inset class="pragraph" @click="selectThis">
       <div
         class="text"
         @input="inputFuncTitle"
@@ -21,8 +21,9 @@
 </template>
 
 <script setup>
-import { defineProps, defineEmits } from 'vue';
+import { defineProps, defineEmits,inject } from 'vue';
 import 'vant/lib/index.css';
+const starEditorFormwork  = inject("starEditorFormwork");
 
 const props = defineProps({
   item: Object,
@@ -39,6 +40,10 @@ const inputFuncTitle = e => {
   newItem.title = e.target.innerHTML;
   emit('saveParagraph', newItem);
 };
+
+const selectThis = () => {
+    starEditorFormwork(newItem);
+}
 </script>
 
 <style scoped>

+ 17 - 2
src/view/allMedia/components/H5Editor/van_buttom.vue

@@ -1,8 +1,9 @@
 <template>
-  <div :style="item.style">
-    <van-button :block="block" :type="btnType" disabled :native-type="nativeType">
+  <div class="button-bg" :style="item.style">
+    <van-button :block="block" :type="btnType" :native-type="nativeType">
       {{ label }}
     </van-button>
+    <div class="button-item"></div>
   </div>
 </template>
 <script setup>
@@ -16,3 +17,17 @@ const block = ref(item.attr.block);
 const nativeType = ref(item.attr.nativeType);
 const btnType = ref(item.attr.type);
 </script>
+
+<style scoped>
+.button-bg {
+  position: relative;
+}
+.button-item {
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  z-index: 1;
+}
+</style>

+ 35 - 13
src/view/allMedia/components/H5Editor/van_field.vue

@@ -1,18 +1,26 @@
 <template>
-  <van-field :required="isRequired" :label="label" :placeholder="placeholder">
-    <template v-if="item.child_list && item.child_list.length" #input>
-      <template v-for="(v, i) in item.child_list" :key="i">
-        <h5-van-radio-group
-          :item="v"
-          v-if="v.type === 'van-radio-group'"
-        ></h5-van-radio-group>
-        <h5-van-uploader
-          :item="v"
-          v-if="v.type === 'van-uploader'"
-        ></h5-van-uploader>
+  <div class="van_field_bg">
+    <van-field
+      :required="isRequired"
+      :label="label"
+      :placeholder="placeholder"
+      readonly
+    >
+      <template v-if="item.child_list && item.child_list.length" #input>
+        <template v-for="(v, i) in item.child_list" :key="i">
+          <h5-van-radio-group
+            :item="v"
+            v-if="v.type === 'van-radio-group'"
+          ></h5-van-radio-group>
+          <h5-van-uploader
+            :item="v"
+            v-if="v.type === 'van-uploader'"
+          ></h5-van-uploader>
+        </template>
       </template>
-    </template>
-  </van-field>
+    </van-field>
+    <div class="van_field_item"></div>
+  </div>
 </template>
 <script setup>
 import H5VanRadioGroup from './van_radio_group.vue';
@@ -28,3 +36,17 @@ const item = JSON.parse(JSON.stringify(props.item || '{}'));
 label.value = item.attr.label;
 placeholder.value = item.attr.placeholder;
 </script>
+
+<style scoped>
+.van_field_bg {
+  position: relative;
+}
+.van_field_item {
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  z-index: 1;
+}
+</style>

+ 3 - 3
src/view/allMedia/components/H5Editor/van_radio.vue

@@ -1,5 +1,5 @@
 <template>
-<van-radio :name="radioName">{{label}}</van-radio>
+  <van-radio checked-color="#f63634" :name="radioName">{{ label }}</van-radio>
 </template>
 <script setup>
 import { defineProps, ref } from 'vue';
@@ -7,6 +7,6 @@ const props = defineProps({
   item: Object,
 });
 const item = JSON.parse(JSON.stringify(props.item || '{}'));
-const label = ref(item.attr.label || "");
-const radioName = ref(item.attr.name || "");
+const label = ref(item.attr.label || '');
+const radioName = ref(item.attr.name || '');
 </script>

+ 4 - 3
src/view/allMedia/components/H5Editor/van_radio_group.vue

@@ -1,12 +1,13 @@
 <template>
-  <van-radio-group disabled :direction="item.attr.direction">
+  <van-radio-group v-model="select" :direction="item.attr.direction">
     <h5-van-radio v-for="(v,i) in (item.child_list || [])" :key="i" :item="v"></h5-van-radio>
   </van-radio-group>
 </template>
 <script setup>
-import { defineProps } from 'vue';
+import { defineProps, ref } from 'vue';
 import H5VanRadio from './van_radio.vue';
-defineProps({
+const props = defineProps({
   item: Object,
 });
+const select = ref(props.item.child_list ? props.item.child_list[0].attr.name : "");
 </script>

+ 0 - 1
src/view/allMedia/components/H5Editor/van_uploader.vue

@@ -1,7 +1,6 @@
 <template>
   <van-uploader
     accept="video/*"
-    disabled 
     :max-count="maxCount"
     :max-size="maxSize"
     :result-type="resultType"

+ 1 - 1
src/view/allMedia/components/H5Editor/imgEditor.vue → src/view/allMedia/components/H5EditorLeft/imgEditor.vue

@@ -17,7 +17,7 @@
 
 <script setup>
 import { defineProps, ref, inject } from 'vue';
-import leftSkeleton from './leftSkeleton.vue';
+import leftSkeleton from '../H5Editor/leftSkeleton.vue';
 
 const inputText = ref('');
 const uploadEle = ref(null);

+ 50 - 0
src/view/allMedia/components/H5EditorLeft/vanButtom.vue

@@ -0,0 +1,50 @@
+<template>
+  <left-skeleton @save="save" @deleteFunc="deleteFunc">
+    <el-form :model="form">
+      <el-form-item label="按钮名称">
+        <el-input v-model="form.name" placeholder="请输入按钮名称"/>
+      </el-form-item>
+      <el-form-item label="api">
+        <el-input v-model="form.api" placeholder="请输入按钮调用api" />
+      </el-form-item>
+    </el-form>
+  </left-skeleton>
+</template>
+
+<script setup>
+import { defineProps, inject, ref } from 'vue';
+import leftSkeleton from '../H5Editor/leftSkeleton.vue';
+
+const saveComponents = inject('saveComponents');
+const deleteItemComponents = inject('deleteItemComponents');
+
+const props = defineProps({
+  item: Object,
+});
+
+
+const form = ref({
+    name: props.item.item.text || "",
+    api: props.item.item.api || "",
+});
+
+const save = () => {
+  saveComponents('保存');
+};
+
+const deleteFunc = () => {
+  /**
+   * 1.删除本地
+   * 2.删除远程
+   */
+  deleteItemComponents(props.item);
+};
+
+console.log(form.value,props.item);
+</script>
+
+<style scoped>
+.upload-demo {
+  margin-top: 1em;
+}
+</style>

+ 86 - 0
src/view/allMedia/components/H5EditorLeft/vanField.vue

@@ -0,0 +1,86 @@
+<template>
+  <left-skeleton @save="save" @deleteFunc="deleteFunc">
+    <el-form :model="form" v-if="defaultForm">
+      <el-form-item label="组件名称">
+        <el-input v-model="form.name" />
+      </el-form-item>
+      <el-form-item label="默认提示">
+        <el-input v-model="form.placeholder" />
+      </el-form-item>
+      <el-form-item label="是否必填">
+        <el-switch v-model="form.isRequired" />
+      </el-form-item>
+    </el-form>
+    <div v-else>
+      <component
+        v-for="(item, index) in form.eleList"
+        :key="index"
+        :is="H5EditorObj[item.type]"
+        :item="item"
+        :index="index"
+        @change="seacechange"
+      ></component>
+    </div>
+  </left-skeleton>
+</template>
+
+<script setup>
+import { defineProps, inject, ref } from 'vue';
+import leftSkeleton from '../H5Editor/leftSkeleton.vue';
+
+import vanRadioGroup from "./van_radio_group"
+import vanUploader from "./van_uploader"
+
+const H5EditorObj = {
+    "van-radio-group": vanRadioGroup,
+    "van-uploader": vanUploader,
+}
+
+const saveComponents = inject('saveComponents');
+const deleteItemComponents = inject('deleteItemComponents');
+
+const props = defineProps({
+  item: Object,
+});
+const item = JSON.parse(JSON.stringify(props.item.item));
+const defaultForm = ref(false);
+
+const formSele = {};
+if (!item.child_list || !item.child_list.length) {
+  defaultForm.value = true;
+  formSele.name = item.attr.label;
+  formSele.placeholder = item.attr.placeholder;
+  formSele.isRequired = item.attr.isRequired;
+} else {
+  defaultForm.value = false;
+  formSele.eleList = item.child_list;
+}
+
+const form = ref(formSele);
+
+
+// 获取子组件内更新的数据
+const seacechange = (item, index) => {
+    item.eleList[index] = item;
+}
+
+const save = () => {
+  saveComponents('保存');
+};
+
+const deleteFunc = () => {
+  /**
+   * 1.删除本地
+   * 2.删除远程
+   */
+  deleteItemComponents(props.item);
+};
+
+console.log(props.item);
+</script>
+
+<style scoped>
+.upload-demo {
+  margin-top: 1em;
+}
+</style>

+ 12 - 0
src/view/allMedia/components/H5EditorLeft/van_radio.vue

@@ -0,0 +1,12 @@
+<template>
+  <van-radio checked-color="#f63634" :name="radioName">{{ label }}</van-radio>
+</template>
+<script setup>
+import { defineProps, ref } from 'vue';
+const props = defineProps({
+  item: Object,
+});
+const item = JSON.parse(JSON.stringify(props.item || '{}'));
+const label = ref(item.attr.label || '');
+const radioName = ref(item.attr.name || '');
+</script>

+ 110 - 0
src/view/allMedia/components/H5EditorLeft/van_radio_group.vue

@@ -0,0 +1,110 @@
+<template>
+  <div>
+    <van-radio-group v-model="select" :direction="localItem.attr.direction">
+      <div
+        v-for="(v, i) in localItem.child_list || []"
+        @close="close"
+        :key="i"
+        class="leftTag"
+      >
+        <div class="closeCss">
+          <el-icon @click="() => editEle(v, i)"><Edit /></el-icon>
+          <el-icon @click="() => close(v, i)"><Close /></el-icon>
+        </div>
+        <h5-van-radio :item="v"></h5-van-radio>
+      </div>
+    </van-radio-group>
+    <div style="padding-top: 1em">
+      <el-icon
+        v-if="!showEle"
+        color="#409eff"
+        :size="30"
+        @click="() => editEle()"
+        ><FolderAdd
+      /></el-icon>
+
+      <el-form class="formEle" :model="form" v-if="showEle">
+        <el-form-item label="文案">
+          <el-input v-model="form.name" />
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" @click="onSubmit">保存</el-button>
+          <el-button @click="cancel">取消</el-button>
+        </el-form-item>
+      </el-form>
+    </div>
+  </div>
+</template>
+<script setup>
+import { defineProps, ref, defineEmits } from 'vue';
+import H5VanRadio from './van_radio.vue';
+const props = defineProps({
+  item: Object,
+  index: Number,
+});
+
+const localItem = ref(JSON.parse(JSON.stringify(props.item)));
+
+const select = ref(
+  localItem.value.child_list ? localItem.value.child_list[0].attr.name : ''
+);
+
+const showEle = ref(false);
+
+const emit = defineEmits(['change']);
+const form = ref({
+  name: '',
+});
+
+const editEle = (v, i) => {
+  showEle.value = true;
+  form.value.isEdit = !!v;
+  if (v) {
+    form.value.index = i;
+    form.value.name = v.attr.label;
+  }
+};
+
+const close = (v, i) => {
+  const li = JSON.parse(JSON.stringify(localItem.value.child_list));
+  li.splice(i, 1);
+  localItem.value.child_list = li;
+  emit('change', localItem.value, props.index);
+};
+
+const onSubmit = () => {
+  if (!form.value.name) return;
+  showEle.value = false;
+  if (form.value.isEdit) {
+    localItem.value.child_list[form.value.index].attr.name = form.value.name;
+  } else {
+    localItem.value.child_list.push({
+      attr: {
+        label: form.value.name,
+        name: form.value.name,
+      },
+      type: 'van-radio',
+    });
+  }
+  form.value.name = '';
+  emit('change', localItem.value, props.index);
+};
+
+const cancel = () => {
+  showEle.value = false;
+};
+</script>
+
+<style scoped>
+.leftTag {
+  padding: 5px 35px 5px 5px;
+  position: relative;
+  margin-right: 4px;
+  min-width: 4em;
+}
+.closeCss {
+  position: absolute;
+  top: 7px;
+  right: 3px;
+}
+</style>

+ 29 - 0
src/view/allMedia/components/H5EditorLeft/van_uploader.vue

@@ -0,0 +1,29 @@
+<template>
+   <el-form :model="localitem">
+    <el-form-item label="介绍文案">
+      <el-input @input="setData" v-model="localitem.subtitle" />
+    </el-form-item>
+    <el-form-item label="api">
+      <el-input @input="setData" v-model="localitem.attr.api" placeholder="请输入文件上传地址" />
+    </el-form-item>
+  </el-form>
+</template>
+<script setup>
+import { defineProps, ref, defineEmits } from 'vue';
+const props = defineProps({
+  item: Object,
+  index: Number
+});
+
+
+const localitem = ref(JSON.parse(JSON.stringify(props.item)));
+
+const emit = defineEmits(['change']);
+const setData = () => {
+    emit('change', localitem.value, props.index);
+};
+
+</script>
+
+<style scoped>
+</style>