您好,登錄后才能下訂單哦!
這篇文章主要介紹“Vue怎么實現(xiàn)增刪改查功能”,在日常操作中,相信很多人在Vue怎么實現(xiàn)增刪改查功能問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Vue怎么實現(xiàn)增刪改查功能”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!
關(guān)于vue的樹形展示 使用到項目:以樹的形式異步展現(xiàn)
效果圖先放:
找到element-ui的官方文檔,el-tree。(地址:https://element.eleme.cn/#/zh-CN/component/tree )
項目需求:以懶加載的形式展示,目錄根據(jù)需求需要有新增 編輯 刪除 操作以及操作后的刷新樹結(jié)構(gòu)
那我們現(xiàn)在開始吧
懶加載:Tree的懶加載,用一個屬性控制:lazy。使用lazy,就要使用load來加載數(shù)據(jù)進行渲染樹
原理:初始化觸發(fā)load函數(shù)先加載初始數(shù)據(jù),通過點擊某個節(jié)點,觸發(fā)load函數(shù),來加載這個節(jié)點下的子節(jié)點。
優(yōu)點:適合數(shù)據(jù)量比較大的時候,對部分節(jié)點刷新也比較友好
自定義節(jié)點:節(jié)點后添加操作按鈕
簡單例子官網(wǎng)上就有示例
**
主要講講更新節(jié)點
**
當(dāng)對節(jié)點進行編輯、刪除時,需要更新樹,只需更新節(jié)點,不必更新全部的樹即可。
原理:更新節(jié)點,其實更新的是該節(jié)點的子節(jié)點,不包括本節(jié)點。刪除該節(jié)點的子節(jié)點,重新請求數(shù)據(jù)獲取本節(jié)點的子節(jié)點數(shù)據(jù)進行重新渲染。
// refreshNode:要刷新的節(jié)點;newNodeData:新的子節(jié)點數(shù)據(jù) refreshNode.splice(0, refreshNode.length); refreshNode.doCreateChildren(newNodeData);
理解一下:
1>.方法node-click調(diào)用函數(shù)menuNodeClick,記錄點擊的節(jié)點信息,對節(jié)點操作前,必然先點擊選中某個節(jié)點。此函數(shù)監(jiān)聽點擊節(jié)點事件,只要點擊了節(jié)點,就觸發(fā):
menuNodeClick(data, node, treeNode) { this.selectNodeData = data this.selectNode = node }
2>.節(jié)點操作后刷新節(jié)點即可,通過不同場景可以選擇刷新本節(jié)點(node)還是刷新本節(jié)點的父節(jié)點(node.parent):
/** * 刷新節(jié)點數(shù)據(jù) * @node [node/Object]: 刷新的節(jié)點node,刷新node以下的所有節(jié)點 * @type [String]: node的類型,'node'表示node是樹的節(jié)點信息Node;'data'表示node是樹節(jié)點信息中的data數(shù)據(jù) */ refreshTreeNode(node, type) { let refreshNode; // 拿到要更新節(jié)點的子節(jié)點 if(type === 'node') { refreshNode = node.childNodes }else if(type === 'data') { let getNode = this.$refs.tree.getNode(node) refreshNode = getNode.childNodes } // 刪除原有的子節(jié)點 refreshNode.splice(0, refreshNode.length); //重新請求數(shù)據(jù),更新節(jié)點 this.requestTreeNode(node) }
3.選擇框checkBox:
如果懶加載中,有選擇框,需要將有選擇框的數(shù)據(jù)加載出來,然后通過屬性default-checked-keys來勾選,通過default-expanded-keys設(shè)置展開的節(jié)點。
4.單選:
如果在懶加載中,有單選項,則設(shè)置選中即可:
// 設(shè)置當(dāng)前節(jié)點選中 this.$refs.tree.setCurrentKey( this.selectNodeData[this.nodeKey] )
不管是單選還是多選,在第一次加載時,后臺要給的,不只是選中信息,還需要選中節(jié)點所在分支的所有節(jié)點信息,賦值給default-expanded-keys以便可使節(jié)點所在分支從上到選擇項都展開。但往往,后臺可能給的,只是選中值的信息,這就要前端自己封裝數(shù)據(jù),獲取需要展開的分支信息。根據(jù)數(shù)據(jù)格式不同,用不同的方法
1)樹形單層數(shù)據(jù)格式:
[
{...},
{...},
{...}
]
這種格式的數(shù)據(jù),【點擊一層,加載一層】、【點擊一層,加載該點擊層的多層子節(jié)點】兩種情況都可以滿足。第一種不需要進行數(shù)據(jù)處理;第二種情況,需要在每條數(shù)據(jù)中注入一個字段,用來關(guān)聯(lián)父子節(jié)點,然后將數(shù)據(jù)封裝處理成el-tree所需要的格式,用一個遞歸函數(shù)整合數(shù)據(jù)(假設(shè)關(guān)聯(lián)字段為parentId,nodeKey為id,樹的子節(jié)點字段為children,需要加載id為'N'的多層子節(jié)點)(注:遞歸函數(shù)會影響性能,謹慎使用)
2).多層數(shù)據(jù)(假設(shè)子節(jié)點的屬性名是children)
[ { ..., children: [ { ..., children: [ { ..., children: [...], }, { ..., children: [...], } ] }, { ..., children: [ { ..., children: [...], } ] } ] } ]
這種格式的數(shù)據(jù),單層、多層都可以滿足,不需要做處理。
選中值整合并展開選中值所在的樹:多層數(shù)據(jù)可由后臺給出選中節(jié)點所在的整個分支的值,賦給default-expanded-keys進行展開。也可以自己做篩選,寫一個遞歸函數(shù),將多層數(shù)據(jù)循環(huán),找到選中值的節(jié)點的分支來設(shè)置展開(假設(shè)nodeKey為id,樹的子節(jié)點字段為children,需要展開id為'N'的節(jié)點所在的整個分支)
懶加載示例:
HTML控件:
<el-tree :data="treeData" :props="defaultProps" :load="loadNodeTree" @node-click="handleNodeClick" lazy :expand-on-click-node="false" :default-expanded-keys="['1']" node-key="id" :highlight-current="true" > <span class="custom-tree-node" slot-scope="{ node, data }"> <span class="treeLeft">{{ node.label }}</span> <span class="treeRight"> <i v-if="node.level === 1" @click="() => appendNode(node, data)" class="el-icon-plus" ></i> <!--增加分組--> <!-- 根節(jié)點不需要刪除和重命名 --> <i v-if="data.id !== 0" @click="() => deleteNode(node, data)" class="el-icon-delete" ></i> <!--刪除分組--> <i v-if="data.id !== 0" @click="() => editNode(node, data)" class="el-icon-edit" ></i> <!--重命名分組--> </span> </span> </el-tree>
vue:
data里面定義變量
// 樹形菜單 treeData: [], // 樹節(jié)點 defaultProps: { // 修改el-tree默認data數(shù)組參數(shù) children: 'children', label: 'name', id: 'id', parentId: 'parentId', isLeaf: 'leaf' // 指定節(jié)點是否為葉子節(jié)點,僅在指定了 lazy 屬性的情況下生效 },
methods:
加載樹形菜單部分
// 加載 樹數(shù)據(jù) loadNodeTree(node, resolve) { const that = this if (node.level === 0) { that.loadtreeData(node, resolve) } else if (node.level === 1) { that.getChildByList(node, resolve) } }, // 獲取loadtreeData 就是父節(jié)點數(shù)據(jù),getChildByList就是異步獲取子節(jié)點數(shù)據(jù) loadtreeData(nodeData, resolve) { const dataType = { pageIndex: 1, pageSize: 100000 } getAlltype(dataType) .then(res => { const rootChildren = [] if (res.code === 200) { const data = res.data.list data.map(item => { rootChildren.push({ name: item.typeName, parentId: '', id: item.id, leaf: false, children: [] }) }) //如果resolve有內(nèi)容就是懶加載走查詢 否則走的是修改 if (resolve) { resolve(rootChildren) } else { nodeData.childNodes = [] nodeData.doCreateChildren(rootChildren) } } else { resolve([]) } }) }, // 獲取子節(jié)點請求 getChildByList(nodeData, resolve) { var _parentID = nodeData.data.id const typeSpec = { typeId: _parentID, pageIndex: 1, pageSize: 100000 } getAlltypeSpec(typeSpec).then(res => { const rootChildren = [] if (res.code === 200) { const data = res.data.list data.map(item => { rootChildren.push({ name: item.description, parentId: item.typeId, id: item.id, leaf: true, children: [] }) }) if (resolve) { resolve(rootChildren) } else { nodeData.childNodes = [] nodeData.doCreateChildren(rootChildren) } } else { return false } }).catch(err => { console.log(err) }) }, // 節(jié)點點擊事件 handleNodeClick(data, node) { this.addnode = node this.adddata = data if (node.level === 1) { this.queryForm.typeId = node.data.id this.queryForm.typeSpecId = '' } else if (node.level === 2) { this.queryForm.typeId = node.data.parentId this.queryForm.typeSpecId = node.data.id } this.query() },
節(jié)點操作:增加節(jié)點 修改節(jié)點 刪除節(jié)點 (操作自己節(jié)點要傳父節(jié)點信息才能找到自己當(dāng)前節(jié)點,操作子節(jié)點就傳當(dāng)前節(jié)點 結(jié)論:父節(jié)點操作子節(jié)點)
// 樹節(jié)點增加 類型規(guī)格 appendNode(node, data) { this.addTypesSpec = { typeName: node.data.name, typeId: node.data.id } this.createTypesSpecDialog = true }, // 樹類型修改 editNode(node, data) { const typeId = node.data.parentId // 一級 類型 if (node.level === 1) { this.editTypesDialog = true this.editTypes = { id: node.data.id, typeName: node.data.name } } else { this.editTypesSpecDialog = true this.getSelectTypes() // this.editTypesSpec = Object.assign({}, node.data) this.editTypesSpec = { typeId: typeId, id: node.data.id, description: node.data.name } } }, // 樹類型刪除 deleteNode(node, data) { // 一級 類型 if (node.level === 1) { this.$msgbox.confirm('此操作將刪除資產(chǎn)類型數(shù)據(jù), 是否繼續(xù)?', '刪除提示', { confirmButtonText: '確定', cancelButtonText: '取消', type: 'warning' }).then(() => { typeDel(node.data.id).then( resp => { this.$message('刪除成功') this.query() this.loadNodeTree(node.parent) }, err => { console.log('err', err) } ) }).catch(() => { this.$message.error('已取消') }) } else { this.$msgbox.confirm('此操作將刪除資產(chǎn)類型規(guī)格數(shù)據(jù), 是否繼續(xù)?', '刪除提示', { confirmButtonText: '確定', cancelButtonText: '取消', type: 'warning' }).then(() => { typeSpecDel(node.data.id).then( resp => { this.loadNodeTree(node.parent) this.$message('刪除成功') this.query() }, err => { console.log('err', err) } ) }).catch(() => { this.$message.error('已取消') }) } },
節(jié)點觸發(fā)之后顯示彈框 走正常的彈框增加修改刪除操作,只不過在提交后臺請求返回操作成功之后需要再一次加載樹形結(jié)構(gòu) 所以在這里再一次調(diào)用加載樹形方法,傳的node 當(dāng)觸發(fā)點擊樹形的時候可以保存一下,我的是handleNodeClick這個方法 不管點擊修改 增加還是刪除都保存下點擊的node
this.$message('編輯成功') this.loadNodeTree(this.addnode.parent)
1.設(shè)置展開和收縮
if (!node.expanded) { node.expand(); }else { node.collapse(); }
2.獲取父節(jié)點
node.parent
到此,關(guān)于“Vue怎么實現(xiàn)增刪改查功能”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。