大项目解决方案 | 青训营笔记

163 阅读3分钟

这是我参与「第四届青训营 」笔记创作活动的第1天

拖拽解决方案

  1.       <div
              class="picItem"
              :key="index"
              v-for="(pic, index) in children"
              @dragstart="fnDragStart(pic)"
              draggable="true"
            >
              <div class="label" :class="[pic.text && index ? 'textTop' : '']">
                {{ pic.text }}
              </div>
              <div class="pic">
                <img :src="pic.pic" @click.stop="fnClickComponent(pic)" />
              </div>
            </div>
          </div>
    

    首先v-for遍历提前在vuex的state中定义好的组件对象数据,然后使用draggable属性,自定义事件深拷贝一份提前定义好的组件对象,赋值给state中component对象中

  2. 普遍使用draggable

页面元素放置,布局解决方案

  1. 使用drop事件,将之前拖拽时赋值给state中的组件,调用vuex中的方法,将该对象保存起来

        const fnDrop = (item, e) => {
          store.commit("activeView", item.id);
          let component = store.state.component;
          let id = Math.floor(Math.random() * 100000000);
          component['_id'] = id
          component['id'] = id
          store.commit("appendComponent", component);
          store.commit("setClickType", "component");
          store.commit("saveComponent", {});
          data.lastEnterEle = null
          data.enterIndex = -1;
          data.text = "可从左侧添加组件到此处";
    
          let historyIndex = store.state.historyIndex
          if(historyIndex != -1){
            let historyViews = store.state.historyViews
            // 获取当前操作,舍弃后面的数据
            let arr = historyViews.slice(0, historyIndex+1)
            store.commit('fnChangeHistoryView', deepClone(arr))
          }
          store.commit('fnAddHistoryView', deepClone(store.state.views))
          store.commit('changeHistoryIndex', - 1)
        };
    
  2. 普遍使用drop事件调用函数放置变量

预览解决方案

  1. 通过修改vuex中视图区域的变量,双向绑定使用该变量显示页面

    //视图区域
            views:[{
                focus: true,
                id: Math.floor(Math.random()*10000000),
                data:{
                    type: 1,
                    left: 0,
                    top: 0,
                    width: 375,
                    height: 225,
                    bgColor: '',
                    bgImg: '',
                },
                components:[]
            },{
                focus: false,
                id: Math.floor(Math.random()*10000000),
                data:{
                    type: 1,
                    left: 0,
                    top: 0,
                    width: 375,
                    height: 225,
                    bgColor: '',
                    bgImg: '',
                },
                components:[]
                }],
    
  2. 用拖拽生成的json数据,在页面v-for循环出来,之后使用iframe嵌入页面

图片视频上传解决方案

  1. 调用接口,返回数据

    const fnUpload = (e) => {
          let type = store.state.type
          let file = e.target.files[0]
          var _data = new FormData();
          _data.append('file', file);
          axios.post("http://127.0.0.1:3001/album/upload", _data, {
            headers:{
              "content-type": "application/x-www-form-urlencoded"
            }
          }).then(res => {
            if(type == 'component'){
              props.data.picContent = res?.data?.data?.path || 'https://p6-orange.byteorge.com/img/ad-tetris-site/brick_tpl_picture_0.png~noop.webp'
            }
            else{
              props.data.bgColor = ""
              props.data.bgImg = res?.data?.data?.path || 'https://p6-orange.byteorge.com/img/ad-tetris-site/brick_tpl_picture_0.png~noop.webp'
            }
            let historyIndex = store.state.historyIndex
            if(historyIndex != -1){
              let historyViews = store.state.historyViews
              // 获取当前操作,舍弃后面的数据
              let arr = historyViews.slice(0, historyIndex+1)
              store.commit('fnChangeHistoryView', deepClone(arr))
            }
            store.commit('fnAddHistoryView', deepClone(store.state.views))
            store.commit('changeHistoryIndex', - 1)
            e.target.value = ""
          }).catch(err => {
            console.log(err)
            e.target.value = ""
          })
        }
        return {
          fnUpload,
        }
      }
    
  2. 将页面中放图片的位置放默认图片或者默认视频,或者置空,给样式加flex-shrink:0;防止伸缩,之后后期将需要加的图片放到src中

修改属性解决方案

  1. 根据被点击的元素,遍历可修改的属性并返回,通过修改该对象进而修改显示结果

元素放置之后的布局定位问题

  1. 提前定义好容器,然后使用views定义的data样式![] 在外部的容器中使用

    .wrapCenter {
      flex: 1;
      height: 100%;
      background-color: antiquewhite;
      overflow-y: auto;
    }
    .editor {
      width: 375px;
      min-height: 740px;
      height: auto;
      background-color: #fff;
      margin: 0 auto;
      margin-top: 20
    }
    

遗留问题

  • 树形结构的预览
  • json与vue | html文件的转换
  • 全局数据管理
  • 发布文件,vue与html文件转换
  • 元素布局方式
  • 拖拽之后提示用户

解决方案(version 1.1)

  1. 首先布局分为left,center,right,header
  2. 将低代码每个组件封装的json数据放置到vuex中
  3. left将vuex中的组件数据循环出来
  4. left拖拽之后,拖到中间center区域,当dragover事件被触发时修改该被dragover的元素样式,提示用户,例如是在上方则在上方创建一个新的盒子,之后如果用户松手则与该盒子替换
  5. 替换之后更新center页面中的树形结构数据,页面照常预览
  6. 用户点击某一元素之后,根据该元素提前定义好的data值,在right中显示出相应要修改的属性
  7. 点击发布之后将json?how to vue or html ?之后生成链接供别人访问