本文主要內容分三部分,第一部分是需求分析,第二部分是實現步驟,第三部分是問題詳解。
如果您只需要解決問題,請閱讀第一、二部分即可。
如果您有更多時間,進一步學習問題相關知識點,請閱讀至第三部分。
實現一個CMS內容管理系統,在后臺進行內容編輯,在官網更新展示內容。
關于后臺的編輯功能,大致分為兩部分:組件拖拽預覽、組件內容編輯實時預覽。
對于組件拖拽預覽,用戶可以在含有各種功能組件的列表中,選擇需要的組件進行拖拽。將組件拖拽到預覽畫布中后,可以在畫布中預覽組件的內容。
對于組件內容編輯實時預覽,用戶可以點擊編輯按鈕,顯示對應組件的內容編輯信息。當修改組件內容時,在畫布中可以實時預覽組件的變化。
關于拖拽組件庫,在github上有很多,最熱門的當屬vuedraggable這個庫。
它基于Sortable.js,擁有完整的中文文檔,所以很多朋友在做拖拽功能時,都會優先考慮它。
但是,我在使用的過程中,在組件拖拽、取消組件拖拽這里,遇到了一些小問題。不知道是我操作的問題,還是庫本身存在BUG,所以最終沒有選用它。
于是我發現了,一個更加好用的拖拽庫vue-draggable-next。
它的出現是參考了vuedraggable這個庫,所以說很多用法很相似,但是使用起來較之更加友善??偨Y為一個詞,自由。
下面我們的拖拽功能實現,就是利用了vue-draggable-next這個庫。
如果你對拖拽底層原理感興趣,并且有空余時間,勞請閱至第三部分拖拽原理總結。
模版和邏輯中代碼都分為了三部分:組件列表、預覽畫布、內容編輯。
布局時,樣式根據需求自定義,此處只是提供了功能的基本邏輯實現。
使用時,關于拖拽組件的需求,根據文檔中提供的屬性和事件的描述,靈活配置完善。
vue-draggable-next庫文檔地址:https://github.com/anish2690/vue-draggable-next。
安裝依賴:
npm install vue-draggable-next//oryarn add vue-draggable-next
模板代碼:
<template><div style="display: flex;cursor: pointer;"><!-- 組件列表 左側 --><div style="width:30vw;padding:30px;height:300px;border: 1px solid #000;text-align: center"><h1>組件列表</h1><VueDraggableNext :list="componentNameList" :group="{ name: 'people', pull: 'clone', put: false }" :sort="false"><div v-for="element in componentNameList" :key="element.name"><div style="padding: 10px;background: #ccc;margin-bottom: 10px"><el-button> {{ element.name }}</el-button></div></div></VueDraggableNext></div><!-- 預覽畫布 中間 --><div style="width:30vw;padding:30px;height:300px;border: 1px solid #000;text-align: center"><h1>預覽畫布</h1><VueDraggableNext :list="componentList" group="people" :sort="false"><div v-for="(element, index) in componentList" :key="element.name"><div><el-button @click="changeComponent(element)" size="small">編輯</el-button><el-button @click="deleteComponent(index)" size="small">刪除</el-button></div><component :is="element.component" :details="element.details"></component></div></VueDraggableNext></div><!-- 內容編輯 右側 --><div style="width:30vw;padding:30px;height:300px;border: 1px solid #000;text-align: center"><h1>內容編輯</h1><div v-for="(nowDetails, index) in nowComponentDetail.details" :key="index">{{ nowDetails.key }}: <el-input clearable v-model="nowDetails.value" /></div></div></div></template>
邏輯代碼:
<script setup>import {markRaw, reactive, ref, watch, nextTick} from "vue";// 引入需要拖拽的組件import About from "@/views/AboutView.vue"http:// 引入拖拽庫import { VueDraggableNext } from "vue-draggable-next";// 組件列表數據const componentNameList = [{// 組件IDcomponentId:0,// 組件名name:'關于組件',// 組件描述description: '關于組件',// 組件信息component: markRaw(About),// 組件需要編輯內容details: About.props.details.default},{componentId:1,name:'關于組件1',description: '關于組件1',component:markRaw(About),details: About.props.details.default},];// 預覽畫布數據let componentList = reactive([]);watch(componentList, () => {console.log(componentList, 'componentList')})// 畫布中刪除的點擊事件const deleteComponent = (index) => {componentList.splice(index, 1);};// 內容編輯數據let nowComponentDetail = ref({});// 畫布中編輯的點擊事件const changeComponent = (element) => {nowComponentDetail.value = element;};</script>
此處提供了組件列表中,任意功能組件的編寫實例,組件的具體功能根據需求自定義。
特別注意,組件Props中details對象屬性的結構寫法,要靈活應用。
模版代碼:
<template><div style="padding: 10px;background: pink;margin-bottom: 10px">{{ props.details.content }}</div></template>
邏輯代碼:
<script setup>import { defineProps } from "vue";const props = defineProps({details: {type: Object,default: {content: {key: '內容',value: "我是About",},}}})</script>
拖拽的實現原理可以簡單描述為以下幾個步驟:
以下是拖拽實現的基本原理代碼實例:
// 獲取拖拽元素const draggableElement = document.getElementById('draggable');// 記錄拖拽起始位置和拖拽元素的初始位置let startX, startY, initialX, initialY;// 監聽鼠標按下事件draggableElement.addEventListener('mousedown', dragStart);draggableElement.addEventListener('touchstart', dragStart);// 監聽鼠標移動事件document.addEventListener('mousemove', drag);document.addEventListener('touchmove', drag);// 監聽鼠標釋放事件document.addEventListener('mouseup', dragEnd);document.addEventListener('touchend', dragEnd);// 拖拽開始事件處理程序function dragStart(event) {event.preventDefault();if (event.type === 'touchstart') {startX = event.touches[0].clientX;startY = event.touches[0].clientY;} else {startX = event.clientX;startY = event.clientY;}initialX = draggableElement.offsetLeft;initialY = draggableElement.offsetTop;}// 拖拽事件處理程序function drag(event) {event.preventDefault();if (event.type === 'touchmove') {const currentX = event.touches[0].clientX - startX;const currentY = event.touches[0].clientY - startY;draggableElement.style.left = initialX + currentX + 'px';draggableElement.style.top = initialY + currentY + 'px';} else {const currentX = event.clientX - startX;const currentY = event.clientY - startY;draggableElement.style.left = initialX + currentX + 'px';draggableElement.style.top = initialY + currentY + 'px';}}// 拖拽結束事件處理程序function dragEnd() {// 執行拖拽結束后的操作}
vue-draggable-next 庫特點和功能的補充說明:
本文鏈接:http://www.www897cc.com/showinfo-26-66547-0.htmlVue3問題:如何實現組件拖拽實時預覽功能?
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com
上一篇: React和Vue的生態系統有何不同?