Vue子組件和父組件、子組件調用父組件的方法、子組件與父組件間的傳值:vue
第一: 子組件和父組件定義:ios
父組件:DeptMgrTop.vuejson
子組件:DeptMgrBody.vue(<top-body></top-body>)和DeptMgrBodyUser.vue(<top-bodyUser></top-bodyUser>)axios
方式以下:api
a. 在子組件DeptMgrBody.vue中添加一個全局的id:flex
代碼以下:ui
name: "TopBody"
如圖所示: this
b. 在父組件DeptMgrTop.vue中引入子組件DeptMgrBody.vue:spa
代碼以下:3d
<script> import {serverURL,toast} from '../../api' import TopBody from '../dept/DeptMgrBody' import TopBodyUser from '../dept/DeptMgrBodyUser' export default { name: "top", components: { TopBody, TopBodyUser, }, computed: { }, ...
如圖所示:
c. 在父組件DeptMgrTop.vue中調用子組件DeptMgrBody.vue:
對應TopBody的大寫變小寫,中間用-分隔:
代碼以下:
<top-body></top-body>
如圖所示:
第二: 子組件調用父組件的方法:
子組件<top-body>中添加:v-on:childDept="showChildDeptTitle",其中showChildDeptTitle爲父組件的方法,childDept爲子組件的方法;
調用方式:在子組件中經過this.$emit('childDept',dept),表示子組件調用父組件的childDept方法並傳遞dept參數。
第三:父組件調用子組件方法:
子組件<top-body>中添加:ref="topbody";
調用方式:在父組件中經過this.$refs.topbody.queryDeptList(data,this.chooses),表示父組件調用子組件的queryDeptList方法並傳遞data和this.chooses參數。
代碼以下:
1. 父組件DeptMgrTop.vue代碼:
<template> <div class="deptTop" style="height: 100%;width: 100%"> <div class="searchOutBox"> <van-search class="searchBox" placeholder="請輸入搜索關鍵詞" v-model="value" @search="onSearch(value)" @input="onSearch"/> <span id="shaixuan" class="shaixuan" @click="choosetags()">篩選</span> </div> <div style="margin-top: 45px;"> <div class="titleCell"> <span style="margin-left: 8px" @click="backFirst">金華市</span> <span style="margin-left: 8px" v-for="(titleCell,index) in titleCells" @click="backOne(titleCell,index)">> {{titleCell}}</span> </div> <div style="height: 10px;background: #DCDCDC; "></div> </div> <!--篩選--> <mt-popup class="choosePopup" v-model="popupVisible" popup-transition="popup-fade" position="bottom"> <div style="width: 100%;border-top:1px solid #d0d0d0"></div> <div class="choosePage"> <div class="switchBtn" v-for="(choose,index) in chooses"> <mt-cell :title="choose.title"> <mt-switch v-model="choose.switchValue" class="mtSwtitch"></mt-switch> <img slot="icon" :src="choose.iconSrc" width="24" height="24"> </mt-cell> </div> <mt-button class="chooseOK" size="large" type="primary" @click.native="handleClick">肯定</mt-button> </div> </mt-popup> <div> <top-body ref="topbody" v-on:childDept="showChildDeptTitle" v-on:backFirst="backFirst"></top-body> </div> <div> <top-bodyUser ref="topuser"></top-bodyUser> </div> </div> </template> <script> import {serverURL,toast} from '../../api' import TopBody from '../dept/DeptMgrBody' import TopBodyUser from '../dept/DeptMgrBodyUser' export default { name: "top", components: { TopBody, TopBodyUser, }, computed: { }, created () { this.getdeptlist(); }, mounted(){ }, methods:{ onSearch(data){ this.titleCells = []; this.$refs.topuser.queryUserList(data,this.chooses); this.$refs.topbody.queryDeptList(data,this.chooses); }, backFirst(){ this.titleCells = []; this.$refs.topbody.getdeptlist(); this.$refs.topuser.getUser(); }, backOne(deptTitle,index){ // if(this.titleCells.length != index+1){ // this.titleCells.splice(index+1,this.titleCells.length-index); // // this.$refs.topbody.backOneList(deptTitle,index); // // this.$refs.topuser.backUserListOne(index); // } }, choosetags(){ this.popupVisible = true; }, handleClick(){ this.popupVisible = false; }, getdeptlist(){ // this.$axios.get("/static/dept.json") this.$axios.get(this.CONST.BASEURL + "/static/dept.json") .then(res => { // console.log("部門列表",res,res.data.smDeptList); this.deptList = res.data.smDeptList; }); }, childDept(){ this.childDeptShow = true; }, /*titleCells添加*/ showChildDeptTitle(data){ this.titleCells.push(data.deptname); this.userList = data.userList; this.$refs.topuser.changeUserList(this.userList); } }, data () { return { value: "", popupVisible:false, chooses:[ {title:"組織機構",switchValue:true,iconSrc:require("../../../static/images/zzjg.png")}, /*{title:"所屬機構",switchValue:true,iconSrc:require("../../../static/images/ssjg.png")},*/ {title:"崗位",switchValue:true,iconSrc:require("../../../static/images/gw.png")}, {title:"電話",switchValue:true,iconSrc:require("../../../static/images/lxdh.png")}, {title:"姓名",switchValue:true,iconSrc:require("../../../static/images/xm.png")} ], deptList:[], props:{}, childDeptShow:false, titleCells: [], userList: [] } }, } </script> <style scoped> body { margin: 0; padding: 0; font-size: 14px; font-family: "microsoft yahei",'Arial', 'Verdana','Helvetica', sans-serif; } .searchOutBox{ display: flex; flex-direction: row; justify-content:center; align-items: center; width: 100%; position: fixed; top: 0; z-index: 1000; background-color: white; } .searchBox{ width: 85%; height: 100%; } .shaixuan { /*background-color: #00A0EA;*/ width: 10%; height: 100%; /* line-height: 30px;*/ margin-right: 2%; float: right; text-align: center; color: #7D7D7E; } .titleCell{ height: 40px; font-size: 14px; line-height: 40px; color: #00A0EA; } .choosePopup{ width: 100%; height: 100%; } .choosePage{ width: 90%; margin: auto; margin-top: 30px; } .mtSwtitch{ display:inline } .chooseOK{ margin-top: 10px; } .switchBtn{ height: 60px; /*background-color: #00A0EA;*/ /*border-bottom:1px solid #A4A4A4;*/ } </style>
2. 子組件DeptMgrBody.vue代碼:
<template> <div class="body" id="body"> <!--部門列表--> <div class="deptList" v-for="(dept,index) in deptList" @click="childDept(dept.smDeptList,dept.deptname,dept)" v-if="vdeptList"> <mt-cell :title="dept.deptname" value="" is-link> </mt-cell> </div> <div class="childDeptList" v-for="(dept,index) in childDeptList" @click="childDept(dept.smDeptList,dept.deptname,dept)" v-if="vchildDeptList"> <mt-cell :title="dept.deptname" value="" is-link> </mt-cell> </div> <div class="childDeptList" v-for="(dept,index) in queryTheDeptList" @click="queryChildDept(dept)" v-if="vchildQueryDeptList"> <mt-cell :title="dept.deptname" :label="dept.deptPath" value="" is-link> </mt-cell> </div> <div style="height: 15px;background: #DCDCDC;" v-if="deptList.length > 0 || childDeptList.length > 0"></div> </div> </template> <script> import {serverURL,toast} from '../../api' export default { name: "TopBody", computed: { }, created () { this.getdeptlist(); this.getdeptlistAll(); }, mounted(){ }, methods:{ getdeptlist(){ this.$axios.get(this.CONST.BASEURL + "/static/dept.json") // this.$axios.get("/static/dept.json") .then(res => { console.log("部門列表",res,res.data.smDeptList); this.deptList = res.data.smDeptList; }); this.vdeptList = true; this.vchildDeptList = false; this.vchildQueryDeptList = false; }, getdeptlistAll(){ this.$axios.get(this.CONST.BASEURL + "/static/deptdept.json") // this.$axios.get("/static/deptdept.json") .then(res => { this.deptListAll = res.data.deptList; }); }, childDept(childDeptList,deptTitle,dept){ this.deptList = []; this.childDeptList = childDeptList; this.vdeptList = false; this.vchildDeptList = true; // this.$emit('childDept',deptTitle) this.$emit('childDept',dept) this.tempDeptList.push(childDeptList); }, /*返回到某個列表*/ backOneList(deptTitle,index){ this.tempDeptList.splice(index+1,this.tempDeptList.length-index); this.childDeptList = this.tempDeptList[index]; // childDept(this.childDeptList,deptTitle); }, /*搜索框查詢*/ queryDeptList(queryTerm,chooses){ this.queryTheDeptList = []; var newDeptList = []; if(queryTerm!="" && queryTerm!=null){ chooses.forEach((choitem, index, arr) => { if(choitem.title=="組織機構" && choitem.switchValue){ this.deptListAll.forEach((item, index, arr) => { if(item.deptname.indexOf(queryTerm)>-1){ newDeptList.push(item); } }) } this.queryTheDeptList = newDeptList; }) this.vdeptList = false; this.vchildQueryDeptList = true; }else{ this.vdeptList = true; this.vchildQueryDeptList = false; this.$emit('backFirst'); } }, /*點擊查詢出來的結果加載子部門列表*/ queryChildDept(dept){ this.$axios.get(this.CONST.BASEURL + "/static/dept.json") // this.$axios.get("/static/dept.json") .then(res => { this.deptList = res.data.smDeptList; }); this.getChildDepts(this.deptList,dept.deptname,dept.deptPath); this.vchildDeptList = true; this.vchildQueryDeptList = false; }, getChildDepts(deptList,deptname,deptPath){ deptList.forEach((item, index, arr) => { if(item.deptname == deptname){ this.flag = true; this.childDeptList = item.smDeptList; /*部門標題鏈處理*/ var strs = deptPath.split("-"); strs.splice(0,1); strs.splice(strs.length-1,1); strs.forEach((item2) => { var deptTt = {"deptname":item2,"userList":[]}; this.$emit('childDept',deptTt); }) this.$emit('childDept',item); }else{ this.getChildDepts(item.smDeptList,deptname,deptPath); } }) } }, data () { return { deptList:[], deptListAll:[], childDeptList:[], queryTheDeptList:[], props:{}, vdeptList: true, vchildDeptList: false, vchildQueryDeptList: false, lineDiv: true, /*臨時列表*/ tempDeptList: [], flag: false } }, props:[] } </script> <style scoped> body { margin: 0; padding: 0; font-size: 14px; font-family: "microsoft yahei",'Arial', 'Verdana','Helvetica', sans-serif; } .deptList{ height: 75%; } .childDeptList{ height: 75%; } </style>
3. 子組件DeptMgrBodyUser.vue代碼:
<template> <div class="bodyUser" id="bodyUser"> <!--用戶列表--> <van-cell class="userList" v-for="(user,index) in userList" @click="getUserDetail(user)"> <div style="width: 14%;display:inline-block"> <van-icon name="friends" color="#38ADFF" size="40px" style="/*background-color: #7D7D7E*/"/> </div> <div style="width: 80%;display:inline-block;/*background-color: #00A0EA*/"> <div style="width: 100%;"> <span style="font-size: 20px;color: #7D7D7E">{{user.name}}</span> <span style="color: #7D7D7E"> {{user.position}}</span> <span style="font-size: 18px;color: #7D7D7E;float: right">{{user.mobile}}</span> </div> <div style="font-size: 13px;line-height: 17px;color: #7D7D7E;height:17px;">( {{user.deptPath}} )</div> </div> </van-cell> </div> </template> <script> import {serverURL, toast} from '../../api' export default { name: "TopBodyUser", computed: {}, created () { this.getUser(); this.getUserAll(); }, mounted(){ }, methods: { getUser(){ this.$axios.get(this.CONST.BASEURL + "/static/dept.json") // this.$axios.get("/static/dept.json") .then(res => { this.userList = res.data.userList; this.tempUserList.push(this.userList); }); }, getUserAll(){ this.$axios.get(this.CONST.BASEURL + "/static/deptuser.json") // this.$axios.get("/static/deptuser.json") .then(res => { this.userListAll = res.data.userList; }); }, getUserDetail(user){ // alert(user); this.$router.push({name: "UserDetail", params: {user: user}}) }, changeUserList(userList){ this.userList = userList; this.tempUserList.push(userList); }, backUserListOne(index){ this.tempUserList.splice(index, this.tempUserList.length - index); this.userList = this.tempUserList[index]; }, /*查詢列表--*/ queryUserList(queryTerm, chooses){ var newUserList = []; if (queryTerm != "" && queryTerm != null) { chooses.forEach((choitem, index, arr) => { if (choitem.title == "組織機構" && choitem.switchValue) { this.userListAll.forEach((item, index, arr) => { if (item.deptName.indexOf(queryTerm) > -1) { newUserList.push(item); } }) } /*if(choitem.title=="所屬機構" && choitem.switchValue){ this.userListAll.forEach((item, index, arr) => { if(item.deptPath.indexOf(queryTerm)>-1){ newUserList.push(item); } }) }*/ if (choitem.title == "崗位" && choitem.switchValue) { /*組織機構模糊搜索*/ this.userListAll.forEach((item, index, arr) => { if (item.position.indexOf(queryTerm) > -1) { newUserList.push(item); } }) } if (choitem.title == "電話" && choitem.switchValue) { this.userListAll.forEach((item, index, arr) => { if (item.mobile.indexOf(queryTerm) > -1) { newUserList.push(item); } }) } if (choitem.title == "姓名" && choitem.switchValue) { this.userListAll.forEach((item, index, arr) => { if (item.name.indexOf(queryTerm) > -1) { newUserList.push(item); } }) } }) this.userList = newUserList; } /*else { this.$axios.get("/static/dept.json") .then(res => { this.userList = res.data.userList; this.tempUserList.push(this.userList); }); }*/ } }, data () { return { userList: [], userListAll: [], tempUserList: [] } }, props: [] } </script> <style scoped> .userList { height: 69px; padding-top: 16px; /*background-color: #8c939d;*/ } </style>
運行界面:
以上便是Vue子組件和父組件、子組件調用父組件的方法、父組件調用子組件方法、子組件與父組件間的傳值的方式之一,還有其餘方式如:經過props傳值等,選擇合適場景的使用便可。