日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

vue 實現拖拽動態生成組件的需求

瀏覽:200日期:2022-09-30 11:06:27
產品需求

開完產品需求會議,遇到了一個需求,首先頁面分成兩欄布局,左側展示數據組件,支持拖拽排序,點擊按鈕清除組件。右側支持將組件的縮略圖拖拽至左側生成一個新的組件。

思路

對于動態生成組件來說每一次都要是生成全新的一個組件,那么就可以把 組件放進函數當中 return。在JSX中調用函數,每次調用函數都會返回一個全新的組件。這對React來說非常簡單,但是對于Vue來說,直接將組件返回是不可能的。盡管這個 return 寫法不適合Vue,但是我們不可否認,思路是非常正確的,所以我們應該考慮一個別的寫法。至于動態的生成組件,我們必須以數據來驅動組件的生成。對于拖拽組件的排序,直接使用拖拽庫就OK了!!

面臨的問題 拖拽庫的選擇 如何生成組件 以數據驅動動態生成組件 拖拽庫的選擇

拖拽庫在這里我選擇的是項目中存在的一個拖拽庫 Vue.Draggable 點這里鏈接查看 Start 14.9K 蠻不錯的。如果你們的Vue項目中沒有用到這個拖拽庫,你們可以自行參考本片文章的設計思路。

如何生成組件

在這里我使用的是 Vue.extend() 不清楚如何使用的小伙伴請在官方文檔中查看過后再來學習這篇文章 Vue.extend 。 接下來我們創建一個js文件,用來書寫創建組件的代碼。

生成組件

/* generateComponents.js 文件名 */import Vue from 'vue';// 想要動態生成的組件,先引入這個文件。import components1 from './components/TestCom1.vue';import components2 from './components/TestCom2.vue';// 將組件的名稱和組件做一個對應Mapconst comMap = { components1, components2,};// 接收生成組件需要的組件名稱,和想要傳遞給組件的// props, 和 事件const ReturnNewCom = function ({ props, on }) { const { comItem: { name }, } = props; const newComponent = Vue.extend({ render(createElement) { // 使用傳進來的組件name來決定渲染哪一個組件。 return createElement(comMap[name], {props,on, }); }, }); return new newComponent();};export default ReturnNewCom;組件

在這里我們書寫兩個組件,用來演示這個Demo,分別為components1.vue,components2.vue。

/*components1.vue*/<template> <div class='widget-wrapper'> <header class='header'>{{ comDetail.name }}--{{ comDetail.id }}</header> <h1>查詢條件:{{ queryObj }}</h1> <button @click='handleDelete'>清除</button> </div></template><script>export default { data() { return { comDetail: this.comItem, _queryObj: this.queryObj, }; }, props: { comItem: { type: Object, default() {return { id: 0, name: '',}; }, }, queryObj: { // 可以接收父組件傳遞的曬選條件,必須是Object type: Object, default() {// 定義默認的查詢條件。return { num: 0,}; }, }, }, watch: { comItem(val) { this.comDetail = val; return val; }, queryObj(val) { this._queryObj = val; return val; }, }, created() { console.log('data -> this.comItem', this.comItem); }, methods: { handleDelete() { // 刪除組件方法 this.$el.remove(); // 調用父組件的函數。修改父組件中的 leftComList 數組的數據。 this.$emit('handleDelete', this.comDetail); }, },};</script><style scoped>.widget-wrapper { background: #ff7b7b; border-radius: 12px; overflow: hidden; width: 200px;}.header { height: 50px; padding: 0 15px;}</style>

其實components2.vue文件中的代碼和components1.vue文件的代碼類似,唯一不同的地方就是背景顏色不一樣。

以數據驅動動態組件的生成

接下來就得使用Vue.Draggable 這個拖拽庫進行拖拽和數據的修改。 我們可以直接在App.vue文件中直接書寫。

/* App.vue */<template> <div class='dragCom'> <h1>{{ leftComList }}</h1> <button @click='queryObj.num++'>改變查詢條件</button> <div class='body'> <div class='left'><draggable :list='leftComList' :group='’people’'> <div ref='comBody' v-for='({ name, id }, index) in leftComList' :key='id' > <!-- 循環 leftComList 數組,利用數據來渲染組件, 將動態生成的數組添加到這個DOM元素當中。 --> {{ handleAddCom({props: { comItem: { name, id }, queryObj },index, }) }} </div></draggable> </div> <div class='right'><draggable :list='rightComList' :group='{ name: ’people’, pull: ’clone’, put: false }' :clone='handleCloneDog'> <div v-for='element in rightComList' :key='element.id'> {{ element.name }} </div> <!-- 右側的 卡片 數據, rightComList 數組對象中的name就對應了generateComponents.js 中的ComMap中的屬性 --></draggable> </div> </div> </div></template><script>import draggable from 'vuedraggable';import CreateCom from './generateComponents';export default { components: { draggable, }, data() { return { rightComList: [{ id: Math.random(), name: 'components1',},{ id: Math.random(), name: 'components2',}, ], leftComList: [], // 存儲驅動動態生成組件的數據。 comMap: new Map(), // 主要的作用就是用來記錄 // 組件有沒有渲染到 這個DOM中, // 如果渲染了就不能再往進添加子元素了。 queryObj: {// 主要的作用就是向子組件傳遞查詢條件num: 0, }, }; }, beforeDestroy() { // 清除 記錄 的數據 this.comMap.clear(); }, methods: { handleAddCom({ index, on = {}, props = { comItem: { name: '', id: 0 } } }) { const {comItem: { id }, } = props; this.$nextTick(() => {// 獲取該節點的子節點的長度const childNodesLength = this.$refs.comBody[index].childNodes.length;// 獲取comBody 這個DOM 數組的長度const comLine = this.$refs.comBody.length;if (!this.comMap.get(id)) { // 如果沒有渲染過組件 // 1. 調用 CreateCom 方法 創建組件。 并傳遞 props 和 事件 const com = CreateCom({ props, on: { handleDelete: this.handleDeleteCom, ...on, }, }); // 2. 生成組件 com.$mount(); if (childNodesLength === 2) { // 如果要添加到兩個組件中間。那么就將新生成的組件DOM位置進行修改放到中間。 // 將最后的組件DOM添加到正確的位置 this.$refs.comBody.splice( index, 0, this.$refs.comBody[comLine - 1] ); } // 3. 將生成的組件添加到改DOM中。 this.$refs.comBody[index].appendChild(com.$el); // 4. 記錄該組件實現了渲染。 this.comMap.set(id, true);} else { // 該位置的組件已經渲染,不需要再次渲染直接返回 return;} }); }, handleDeleteCom({ id }) { // 傳遞給子組件刪除的方法,根據組件的id來刪除數據 const index = this.leftComList.findIndex((item) => item.id === id); if (~index) {// 如果存在這個id的組件,就刪除this.leftComList.splice(index, 1); } }, handleCloneDog(item) { // 給 leftComList 數組添加數據 return {...item,id: Math.random(), }; }, },};</script><style>.dragCom { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px;}.body { width: 100%; height: 800px; display: flex; justify-content: space-between;}.left { flex: 1; height: 800px; border: 1px solid pink;}.right { width: 20%; height: 800px;}.card { height: 50px; background-color: #40cec7; margin: 12px 0; font-size: 12px; line-height: 50px; cursor: pointer;}.comCard { margin: 12px; display: inline-block;}</style>

這樣就實現了動態的組件渲染和拖拽排序。

效果

vue 實現拖拽動態生成組件的需求

源碼

想要嘗試的同學可以自行下載本文的代碼源碼github

以上就是vue 實現拖拽動態生成組件的需求的詳細內容,更多關于vue拖拽動態生成組件的資料請關注好吧啦網其它相關文章!

標簽: Vue
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
99久久久久国产精品| 日韩精品一区二区三区中文在线| 激情国产在线| 国产成人精品一区二区三区在线| 91九色综合| 久久激五月天综合精品| 午夜久久美女| 在线日韩一区| 久久男女视频| 欧美sss在线视频| 四虎影视精品| 亚洲a在线视频| 日韩理论视频| 捆绑调教日本一区二区三区| 日韩精品一页| 亚洲综合图色| 日本高清久久| 亚洲精品在线国产| 日韩中文字幕无砖| 久久激五月天综合精品| 欧美天堂一区二区| 国产欧美日韩免费观看| 国产视频一区三区| 综合国产精品| 日韩中文字幕视频网| 欧美日本久久| 精品网站999| 国产调教精品| 亚洲福利久久| 日本美女一区| 国产日韩专区| 国产精品hd| 亚洲v在线看| 欧美亚洲三区| 欧美不卡高清一区二区三区| av不卡在线看| 牛牛精品成人免费视频| 都市激情国产精品| 日精品一区二区三区| 日韩欧美三级| 午夜在线精品偷拍| 99精品在线观看| 亚洲涩涩av| 丝袜美腿诱惑一区二区三区 | 国产成人黄色| 一区二区三区四区在线看| 激情久久久久久久| 777久久精品| 青青久久av| 国产精品亚洲一区二区在线观看| 免费日韩av片| 国精品产品一区| 久久午夜精品| 午夜精品一区二区三区国产| 男女精品网站| 黄色在线观看www| 国产无遮挡裸体免费久久| 国产一区日韩一区| 国产在线不卡一区二区三区| 黄色av日韩| 亚洲激情久久| 一本一道久久a久久精品蜜桃| 免费日韩一区二区| 99久久夜色精品国产亚洲1000部| 亚洲激精日韩激精欧美精品| 亚洲综合电影| 精品国产鲁一鲁****| 精品久久久久久久| 超级白嫩亚洲国产第一| 三上亚洲一区二区| 成人影视亚洲图片在线| 高清不卡亚洲| 亚洲成人国产| 五月天久久久| 蜜桃视频一区二区三区| 丝袜美腿一区二区三区| 欧美在线91| 国产精品草草| 正在播放日韩精品| 日韩精品一二三| 日韩激情视频网站| 麻豆视频一区| 99久久精品网| 日韩精品一级| 国产高潮在线| 亚洲网站视频| 日韩中文一区二区| 久久精品国产成人一区二区三区| 亚洲欧美不卡| 日韩国产成人精品| 成人在线免费观看91| 欧美午夜不卡影院在线观看完整版免费| 亚洲影院天堂中文av色| 欧美日本不卡高清| 国产精品xx| 中文视频一区| 亚洲欧美日本国产专区一区| 日本不卡一区二区三区| 在线视频精品| 精品中国亚洲| 亚洲免费在线| 欧产日产国产精品视频| 日韩专区视频网站| 在线看片国产福利你懂的| 国产精品日韩精品在线播放| 日韩免费av| 国产精品www994| 亚洲性视频在线| 欧美激情一区| 国产欧美一区| 女同性一区二区三区人了人一 | 免费亚洲婷婷| 免费一区二区视频| 成人日韩在线观看| 国产精品扒开腿做爽爽爽软件| 日韩av成人高清| 亚洲福利免费| а√天堂中文在线资源8| 国产日韩欧美一区在线| 蜜桃久久av一区| 涩涩涩久久久成人精品| 蜜臀av亚洲一区中文字幕| 欧美综合国产| 国内亚洲精品| 日韩精品一区二区三区免费观看| 欧美日韩一二三四| 久久a爱视频| 久久精品xxxxx| 麻豆视频在线观看免费网站黄| 国产精品成久久久久| 久久精品 人人爱| 青青草精品视频| 久久精品99国产精品| 国产欧美日韩一级| 精精国产xxxx视频在线播放| 精品伊人久久| 成年男女免费视频网站不卡| 国产va免费精品观看精品视频| 久久九九电影| 激情欧美丁香| 免费在线观看视频一区| 欧美日韩国产在线观看网站 | 69堂精品视频在线播放| 日韩国产欧美| 亚洲影院天堂中文av色| 亚洲午夜久久| 欧美日韩 国产精品| 精品一区二区三区在线观看视频| 欧洲激情综合| 国产精品亚洲综合在线观看| 国产精成人品2018| 国产亚洲一区二区手机在线观看 | 在线一区欧美| 日韩精品亚洲aⅴ在线影院| 国产精品久久久亚洲一区| 久久不见久久见中文字幕免费| 欧美高清不卡| 亚洲乱码视频| 99国产精品私拍| 亚洲狼人精品一区二区三区| 成人av三级| 九一精品国产| 欧美一区免费| 欧美日韩一区二区三区视频播放| 人人精品久久| 色欧美自拍视频| 免费观看在线色综合| 在线人成日本视频| 香蕉久久国产| 日韩一区自拍| 青草国产精品久久久久久| 久久久久.com| 国产免费久久| 视频一区免费在线观看| av免费不卡国产观看| 日韩午夜视频在线| 国产精品蜜芽在线观看| 亚洲永久字幕| 国产综合婷婷| 亚洲精品电影| 在线视频亚洲| 欧美亚洲三级| 97久久中文字幕| 亚洲欧美日本视频在线观看| 国产美女亚洲精品7777| 国产99久久| 在线视频观看日韩| 精品中文一区| 日韩久久视频| 国产精品成久久久久| 91亚洲自偷观看高清| 97久久中文字幕| 精品一区亚洲| 99久久www免费| 黄页网站一区| 久久国产欧美日韩精品| 国产日韩欧美| 美女视频免费精品| 久久国产生活片100| 偷拍精品精品一区二区三区|