vue自定義頁面

需求:拖拉拽形成頁面
效果:可定義客戶端和移動(dòng)端基本樣式:柵格,寬高,陰影等础拨,且客戶端與移動(dòng)端樣式互不影響氮块,這里只有大體樣式,并不是最終展示效果
附圖:


image.png

邏輯就不多說了诡宗,就是拖拽

<template>
  <div>
    <div class="custom_box">
      <div class="left">
        <div class="title_box">
          組件庫
        </div>
        <div class="main_box">
          <ul class="left_ul">
            <li
              v-for="(item, index) in leftList"
              :id="item.type"
              :key="item.iden"
              class="left_li"
              draggable="true"
              @dragstart="leftDrag($event, index)"
            >
              {{ item.name }}
            </li>
          </ul>
        </div>
      </div>
      <div
        class="center"
        @drop="contentDrop($event)"
        @dragover="contentDragover($event)"
      >
        <div class="title_box">
          <div>
            <a-form layout="inline" :label-col="{ span: 5 }">
              <a-form-item label="展示端">
                <a-select v-model="terminal">
                  <a-select-option value="pcInfo">
                    PC端
                  </a-select-option>
                  <a-select-option value="mobileInfo">
                    移動(dòng)端
                  </a-select-option>
                </a-select>
              </a-form-item>
            </a-form>
          </div>
          <div>
            <a-button type="primary" @click="watchFn('pcInfo')">
              預(yù)覽PC
            </a-button>
            <a-button type="primary" @click="watchFn('mobileInfo')">
              預(yù)覽Mobile
            </a-button>
          </div>
        </div>
        <div class="content main_box">
          <div
            v-for="(view, index) in info"
            :key="view.iden"
            class="content_item"
            draggable="true"
            @dragenter="enter($event, view)"
            @dragstart="handleDragStart($event, view)"
            @dragover.prevent="handleDragover($event)"
          >
            <component
              :is="view.type"
              :is-disabled="true"
              :terminal="terminal"
              :view-info="info[index]"
            />
            <div
              class="mask_box"
              :class="view.iden === notContentIden ? 'active' : ''"
              @click="editData(view, index)"
            >
              <a-icon
                class="icon_del"
                type="delete"
                @click="deleteFn(view, index)"
              />
            </div>
          </div>
        </div>
      </div>
      <div class="right">
        <div class="title_box">
          組件屬性
        </div>
        <div class="main_box">
          <div class="right_main">
            <WriteChildren
              v-for="(child, index) in rightList"
              :key="index"
              :edit-info.sync="editInfo"
              :terminal="terminal"
              :index="index"
            />
          </div>
        </div>
      </div>
    </div>
    <div class="dialog">
      <a-drawer
        title="預(yù)覽"
        :visible="visibleModal"
        width="100%"
        @close="onClose"
      >
        <div
          class="main"
          :style="{ width: watchType == 'pcInfo' ? '' : '375px' }"
        >
          <div
            v-for="(view, index) in info"
            :key="index"
            :style="[
              {
                width:
                  view.type != 'JrBanner' && watchType == 'pcInfo'
                    ? '1200px'
                    : '100%',
              },
              { margin: 'auto' },
            ]"
          >
            <component
              :is="view.type"
              :terminal="watchType"
              :usage-scenarios="true"
              :view-info="info[index]"
            />
          </div>
        </div>
      </a-drawer>
    </div>
  </div>
</template>

<script>
import { debounce } from "@/libs/utils";
// 編寫
import WriteChildren from "./writeChildren/index";
// 視圖
import JrBanner from "./viewChildren/jrBanner";
import JrCard from "./viewChildren/jrCard";
import JrAdvert from "./viewChildren/jrAdvert";
export default {
  name: "Custom",
  components: {
    // 編寫
    WriteChildren,
    // 視圖
    JrBanner,
    JrCard,
    JrAdvert,
  },
  data() {
    return {
      data: [],
      contentList: [],
      leftList: [
        {
          iden: 1,
          type: "JrBanner",
          name: "輪播",
          field_name: "banner",
        },
        {
          iden: 2,
          type: "JrCard",
          name: "卡片",
        },
        {
          iden: 20,
          type: "JrAdvert",
          name: "廣告",
        },
      ],
      editInfo: {},
      info: [],
      rightList: [],
      terminal: "pcInfo",
      checkInfo: {},
      notContentIden: null,
      visibleModal: false,
      watchType: "pcInfo",
    };
  },
  computed: {
    formInfo() {
      let arr = [];
      this.info.map((item) => {
        arr.push({
          title: item.name,
          dataIndex: item.field_name,
        });
      });
      return arr;
    },
    itemId() {
      return this.$route.query.id;
    },
  },
  created() {
    this.enter = debounce(this.handleDragEnter, 300);
  },
  methods: {
    leftDrag(ev) {
      ev.dataTransfer.setData("Text", ev.target.id);
    },
    //添加
    contentDrop(ev) {
      if (this.type) {
        this.type = false;
        return false;
      }
      ev.preventDefault();
      let newLeftList = JSON.parse(JSON.stringify(this.leftList));
      var index = newLeftList.findIndex((item) => {
        return item.type === ev.dataTransfer.getData("Text");
      });
      let data = newLeftList[index];
      data.iden = new Date().getTime();
      data.show_title = false;
      data.fatherCode = ""; // 廣告位code
      data.pcInfo = {
        height: 300,
        count: 3,
        bgColor: "",
        shadow: true,
        alignment: "left",
      };
      data.mobileInfo = {
        height: 300,
        count: 2,
        bgColor: "",
        shadow: true,
        alignment: "center",
      };
      this.notContentIden = data.iden;
      data.options = [
        // value:值滔蝉,key:鍵,main_text:主文本僚焦,sub_text:副文本锰提,topNumber:距離頂部距離
        { value: "", key: "", main_text: "", sub_text: "", topNumber: 0 },
      ];
      this.editInfo = data;
      this.rightList = [];
      this.info.push(data);
      this.rightList.push(data);
    },
    contentDragover(ev) {
      ev.preventDefault();
    },
    //編輯/修改
    editData(data) {
      this.notContentIden = data.iden;
      this.rightList = [];
      this.rightList.push(data);
      this.editInfo = data;
    },

    /* 換位 */
    handleDragStart(ev, data) {
      this.type = true;
      this.checkInfo = data;
    },
    handleDragover(ev) {
      ev.dataTransfer.dropEffect = "move";
      ev.preventDefault();
    },
    handleDragEnter(ev, data) {
      ev.dataTransfer.effectAllowed = "move";
      if (data === this.checkInfo) {
        return false;
      }
      const newData = [...this.info];
      const src = newData.indexOf(this.checkInfo);
      const dst = newData.indexOf(data);
      newData.splice(dst, 0, ...newData.splice(src, 1));
      this.info = newData;
    },
    //刪除
    deleteFn(data, index) {
      this.info.splice(index, 1);
    },
    //查看/預(yù)覽
    watchFn(type) {
      this.watchType = type;
      this.visibleModal = true;
    },
    onClose() {
      this.visibleModal = false;
    },
  },
};
</script>
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市芳悲,隨后出現(xiàn)的幾起案子立肘,更是在濱河造成了極大的恐慌,老刑警劉巖名扛,帶你破解...
    沈念sama閱讀 217,826評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件谅年,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡肮韧,警方通過查閱死者的電腦和手機(jī)融蹂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來弄企,“玉大人超燃,你說我怎么就攤上這事【辛欤” “怎么了意乓?”我有些...
    開封第一講書人閱讀 164,234評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)约素。 經(jīng)常有香客問我届良,道長(zhǎng),這世上最難降的妖魔是什么圣猎? 我笑而不...
    開封第一講書人閱讀 58,562評(píng)論 1 293
  • 正文 為了忘掉前任士葫,我火速辦了婚禮,結(jié)果婚禮上送悔,老公的妹妹穿的比我還像新娘慢显。我一直安慰自己,他們只是感情好欠啤,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,611評(píng)論 6 392
  • 文/花漫 我一把揭開白布鳍怨。 她就那樣靜靜地躺著,像睡著了一般跪妥。 火紅的嫁衣襯著肌膚如雪鞋喇。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,482評(píng)論 1 302
  • 那天眉撵,我揣著相機(jī)與錄音侦香,去河邊找鬼落塑。 笑死,一個(gè)胖子當(dāng)著我的面吹牛罐韩,可吹牛的內(nèi)容都是我干的憾赁。 我是一名探鬼主播,決...
    沈念sama閱讀 40,271評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼散吵,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼龙考!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起矾睦,我...
    開封第一講書人閱讀 39,166評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤晦款,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后枚冗,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體缓溅,經(jīng)...
    沈念sama閱讀 45,608評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,814評(píng)論 3 336
  • 正文 我和宋清朗相戀三年赁温,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了坛怪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,926評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡股囊,死狀恐怖袜匿,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情稚疹,我是刑警寧澤沉帮,帶...
    沈念sama閱讀 35,644評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站贫堰,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏待牵。R本人自食惡果不足惜其屏,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,249評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望缨该。 院中可真熱鬧偎行,春花似錦、人聲如沸贰拿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽膨更。三九已至妙真,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間荚守,已是汗流浹背珍德。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工练般, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人锈候。 一個(gè)月前我還...
    沈念sama閱讀 48,063評(píng)論 3 370
  • 正文 我出身青樓薄料,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親泵琳。 傳聞我的和親對(duì)象是個(gè)殘疾皇子摄职,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,871評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容