Vue子组件和父组件、子组件调用父组件的方法、父组件调用子组件方法、子组件与父组件间的传值

 Vue子组件和父组件、子组件调用父组件的方法、子组件与父组件间的传值:


第一: 子组件和父组件定义

    父组件:DeptMgrTop.vue

    子组件:DeptMgrBody.vue(<top-body></top-body>)和DeptMgrBodyUser.vue(<top-bodyUser></top-bodyUser>)

    方式如下:

      a. 在子组件DeptMgrBody.vue中添加一个全局的id:

        代码如下:

name: "TopBody"

        如图所示:       

        

      b. 在父组件DeptMgrTop.vue中引入子组件DeptMgrBody.vue:

        代码如下:

<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%; 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)">>&nbsp;&nbsp;&nbsp;{{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=" 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=" 14%;display:inline-block">
        <van-icon name="friends" color="#38ADFF" size="40px" style="/*background-color: #7D7D7E*/"/>
      </div>

      <div style=" 80%;display:inline-block;/*background-color: #00A0EA*/">
        <div style=" 100%;">
          <span style="font-size: 20px;color: #7D7D7E">{{user.name}}</span>
          <span style="color: #7D7D7E">&nbsp;{{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;">(&nbsp;{{user.deptPath}}&nbsp;)</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传值等,选择合适场景的使用即可。

原文地址:https://www.cnblogs.com/hooly/p/11162381.html