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

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

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

瀏覽:195日期: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久久,三上悠亚国产精品一区二区三区
久久精品72免费观看| 精品不卡一区| 亚洲精品成人图区| 国产精品毛片久久久| 午夜在线观看免费一区| 午夜欧美精品久久久久久久| 久久久成人网| 久久久成人网| 亚洲午夜精品久久久久久app| 国产精品字幕| 欧美成人综合| 久久成人精品| 日本不卡的三区四区五区| 日韩一区二区三区高清在线观看| 日韩精品成人| 国产精品videossex久久发布 | 久久午夜视频| 欧美日韩国产在线一区| 快she精品国产999| 色狠狠一区二区三区| 91亚洲精品在看在线观看高清| 欧美中文高清| 欧美a一区二区| 国产91欧美| 国产综合亚洲精品一区二| 午夜免费一区| 亚洲开心激情| 国产精品亚洲欧美日韩一区在线 | 久久久91麻豆精品国产一区| 国产精品久久国产愉拍| 久久精品资源| 亚洲91精品| 亚洲理论在线| 精品国产亚洲一区二区三区| 成人免费电影网址| 一区二区国产在线| 麻豆视频久久| 欧美不卡视频| 欧美久久香蕉| 日韩黄色大片| 男人的天堂亚洲一区| 国产精品九九| 欧美日韩在线二区| 欧美亚洲免费| 日韩一区电影| 日韩在线观看一区二区| 国产精品一级| 国模 一区 二区 三区| 日本午夜精品久久久久| 日韩国产欧美一区二区| 影音先锋久久精品| 精品国产乱码久久久久久樱花| 在线日韩中文| 麻豆成人综合网| 五月天激情综合网| 亚洲另类黄色| 国产伊人久久| 首页亚洲欧美制服丝腿| 国产精品115| 亚洲福利精品| 每日更新成人在线视频| 精品理论电影在线| 久久国产99| 成人亚洲精品| 亚洲一区二区av| 国产一区二区三区视频在线| 国产亚洲一区在线| 精品日韩一区| 免费的成人av| 日韩中文影院| 国产日产精品_国产精品毛片| 99成人在线视频| 国产精品久久久久久av公交车 | 国产伊人久久| 国产精品三p一区二区| 日产精品一区二区| 一区二区三区四区日韩| 韩国久久久久久| 69堂精品视频在线播放| 99在线精品免费视频九九视 | 99日韩精品| 粉嫩av一区二区三区四区五区| 喷白浆一区二区| 国产在线|日韩| 日本视频一区二区| 中文日韩欧美| 国产精品字幕| 麻豆国产精品视频| 97精品资源在线观看| 亚洲深夜av| 日本精品不卡| 精品成av人一区二区三区 | 91p九色成人| 亚洲一区国产一区| 久久视频国产| 欧产日产国产精品视频| 国产精品大片| 亚洲免费资源| 在线视频免费在线观看一区二区| 老牛影视精品| 精品美女在线视频| 欧美亚洲一级| 亚洲精品动态| 国产视频亚洲| 91成人网在线观看| 日韩精品影视| 日韩不卡一区| 国产成人精品免费视| 国产精品欧美大片| 日韩av一区二区三区四区| 中文字幕一区二区精品区| 欧美特黄一区| 日韩成人亚洲| 在线手机中文字幕| 国产一区二区三区久久 | а√天堂8资源在线| 蜜桃久久久久| 麻豆国产精品视频| 国产精品2023| 国产精品theporn| 国产精品美女久久久久久不卡| 欧美在线91| 日韩精品免费一区二区夜夜嗨| 亚洲日韩中文字幕一区| 一本色道精品久久一区二区三区| 国产精品91一区二区三区| 国产一区日韩欧美| 香蕉人人精品| 伊人影院久久| 亚洲在线电影| 日韩精品一级二级| 亚洲专区视频| 日韩影片在线观看| 日韩精品亚洲专区| 欧美日韩在线精品一区二区三区激情综合| 日韩精品一区二区三区中文在线| 日本成人中文字幕| 国产日韩免费| 你懂的国产精品| 免费看一区二区三区| 久久只有精品| 免费在线小视频| 亚洲激情五月| 亚洲毛片网站| 国产激情综合| 成人精品久久| re久久精品视频| 天堂va蜜桃一区二区三区| 日韩精品一页| 免费一级欧美片在线观看网站 | 久久精品国产亚洲aⅴ| 福利精品在线| 99精品网站| 日韩视频二区| 亚洲精品在线a| 国产欧美日韩亚洲一区二区三区| 国产精品xxxav免费视频| 日韩综合一区| 欧美精品一线| 日本不卡一区二区三区| 久久久国产精品网站| 欧美13videosex性极品| 好吊一区二区三区| 日韩国产一二三区| 激情中国色综合| 国产99久久| 亚洲1区在线观看| 免费一级欧美片在线观看网站 | 久久精品九色| 亚洲网站视频| 日本久久二区| 日韩综合在线| 久久先锋影音| 精品国产精品国产偷麻豆| 国内精品99| 日韩成人精品一区二区三区 | 精品一区二区三区的国产在线观看 | 久久精品99国产精品| 国产一区二区色噜噜| 精品中文字幕一区二区三区av| 日韩高清在线不卡| 欧美成人精品三级网站| 亚洲啊v在线免费视频| 国产一区丝袜| 丝袜诱惑制服诱惑色一区在线观看 | 免费成人在线观看| 精品久久久亚洲| 蘑菇福利视频一区播放| 国产精品毛片视频| 99在线|亚洲一区二区| 久久99视频| 男人的天堂亚洲一区| 日韩综合在线| 亚欧成人精品| 日韩av福利| 日韩av一二三| 午夜免费一区| 国产成人调教视频在线观看| 美国三级日本三级久久99 | 麻豆国产91在线播放|