vue中自定义组件的用法(企业微信通讯录选人)

组件的好处就是可以重复使用,坏处就是父子组件之间的通信相对比较麻烦,但是掌握了父子组件之间的通信后组件的应用就很简单了。下面是实战,最后是思路。

项目的index.html中引入https://res.wx.qq.com/open/js/jweixin-1.2.0.js">

1.子组件

<template>
  <div class="add-photo-con">
    <div class="photo-icon-con" :key="item.id" v-for="item in selectedUserList">
      <div class="del-phone-icon">
        <img class="" style="height: 100%;width: 100%;" @click="delPic(item.id)" src="../assets/images/m-del-red.png">
      </div>
      <div class="add-photo-icon1">
        <img class="add-photo-icon1" v-if="item.avatar" :src="item.avatar">
        <img class="add-photo-icon1" v-else src="../assets/images/m-head-sculpture-default.png">
      </div>
   </div>
   <img @click="selectMeetingUsers" class="add-photo-icon" src="../assets/images/m-add-photo.png">
 </div>
</template>
<style scoped>
  .add-photo-icon {
    width: 30px;
    height: 30px;
    margin-right: 10px;
  }
  .add-photo-icon1 {
    width: 45px;
    height: 45px;
    border-radius: 3px;
  }
  .del-phone-icon{
    height: 12px;
    width: 12px;
    margin-left: 38px;
    margin-bottom: -5px;
    z-index: 10;
  }
  .photo-icon-con{
    width: 45px;
    height: 45px;
    margin-right: 10px;
    margin-bottom: 10px;
    display: flex;
    flex-direction: column;
  }
  .add-photo-con {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: flex-start;
    align-items: center;
    padding-left: 10px;
    padding-top: 10px;
  }
  .textarea-title {
    font-size: 14px;
    font-family: "Microsoft YaHei";
    font-weight: 500;
    color: #434343;
    line-height: 28px;
  }
  .textarea-title:before {
    content: "* ";
    color: #FF0000;
  }
  .textarea-con {
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    align-items: flex-start;
    background: #ffffff;
    padding: 5px 10px;
    border-bottom: 1px solid #f2f2f2;
  }
</style>
<script>
  export default {
    name: 'selectComponents',
    props:{
      name: {
        type: String
      }
    },
    data() {
      return {
        selectedUserList: [],
        selectedUserIds: [],
      }
    },
    methods: {
      getpeopleArrList(val){
        this.selectedUserList = val
        this.getSelectedUserIds();
      },
      delPic(id){
        for(let i=0; i<this.selectedUserList.length; i++){
          if(this.selectedUserList[i].id == id){
            this.selectedUserList.splice(i, 1);
          }
        }
        this.getSelectedUserIds();
        this.invokeEmit();
      },
      selectMeetingUsers () {
        var that = this;
        wx.invoke("selectEnterpriseContact", {
            "fromDepartmentId": -1,// 必填,表示打开的通讯录从指定的部门开始展示,-1表示自己所在部门开始, 0表示从最上层开始
            "mode": "multi",// 必填,选择模式,single表示单选,multi表示多选
            "type": ["department", "user"],// 必填,选择限制类型,指定department、user中的一个或者多个
            "selectedDepartmentIds": [],// 非必填,已选部门ID列表。用于多次选人时可重入,single模式下请勿填入多个id
            "selectedUserIds": that.selectedUserIds // 非必填,已选用户ID列表。用于多次选人时可重入,single模式下请勿填入多个id
          },function(res){
            if (res.err_msg == "selectEnterpriseContact:ok")
            {
              if(typeof res.result == 'string')
              {
                res.result = JSON.parse(res.result) //由于目前各个终端尚未完全兼容,需要开发者额外判断result类型以保证在各个终端的兼容性
              }

              that.selectedUserList = res.result.userList; // 已选的成员列表
              that.getSelectedUserIds();
              that.invokeEmit();
            }
          }
        );
      },
      getSelectedUserIds(){
        this.selectedUserIds = [];
        for (var i = 0; i < this.selectedUserList.length; i++)
        {
          var user = this.selectedUserList[i];
          this.selectedUserIds.push(user.id); // 已选的单个成员ID
        }
      },
      invokeEmit(){
        var that = this;
        if(this.name == 'person'){
          that.$emit('getPersonList', that.selectedUserList)
        }else if(this.name = 'leader'){
          that.$emit('getLeaderList', that.selectedUserList)
        }
      }
    },
    mounted() {

    }
  }
</script>

2.父组件

<template>
	<div class="textarea-con">
        <div class="textarea-title">参会人员</div>
        <select-child @getPersonList="getPersonList" ref="peopleArr" :name="'person'"></select-child>
      </div>
</template>
<script>
import selectChild from '@/components/selectComponents'
import { initWxConfig } from '@/pub/js/initWxConfig'
 export default {
    components:{
      'select-child': selectChild
    },
    name: 'meetingApply',
    data() {
	    return {
	    	peoples: [],
		}
	},
    methods: {
		getPersonList(value){
	        this.peoples = value
	      },
	}mounted() {
      initWxConfig(this);
    }
   }
</script>

3.initWxConfig

/* 企业微信js配置 */
//注意:如果要在页面调用企业微信内部方法,请现在下面的jsApiList数组中添加方法
import { Toast } from 'mint-ui'
export function initWxConfig(vm){
  var that = vm;
  var token = vm.util.getCookie('hbzy-user-token')
  // var url = encodeURIComponent(location.href)
  var url = 'https://weixin.hbtobacco.cn/hbwebchat/meeting/'
  vm.axios({
    url: '获取签名的后台服务地址='+ token + '&url=' + url
  })
  .then( (response) => {
    // console.log(JSON.stringify(response))
    if(response.status == 200){
      var timestamp = response.data.timestamp //时间戳
      var nonceStr = response.data.nonceStr //随机字符串
      var signature = response.data.signature //签名
      var appId = response.data.appId //企业id

      wx.config({
        beta: true,// 必须这么写,否则wx.invoke调用形式的jsapi会有问题
        debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
        appId: appId, // 必填,企业微信的corpID
        timestamp: timestamp, // 必填,生成签名的时间戳
        nonceStr: nonceStr, // 必填,生成签名的随机串
        signature: signature,// 必填,签名,见附录1
        jsApiList: ['selectEnterpriseContact'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
      });
      wx.ready(function () {
      });
      wx.error(function(res){
        Toast('initWxConfig:'+JSON.stringify(res))
      });
    }else{
        Toast('else='+response.data.status_msg)
    }
  })
  .catch( (error) => {
    Toast('catch='+JSON.stringify(error))
  });
}

注意:

1.子组件建好后,然后在父组件中导入并注册
2.父组件中有一个值:name="'leader'",子组件可以通过 props属性取得,这里传值只是为了告诉读者子组件如何获取父组件的值
3.由于在父组件中已经引入了子组件,在点击组件的时候触发的是子组件中的selectMeetingUsers方法(在企业微信api调用的文章中),选择并显示图片,delPic方法为删除图片
4.最后调用invokeEmit方法通过 this.$emit('getPersonList', this.selectedUserList)将selectedUserList数组传递到父组件的getPersonList
最后说一句:props和this.$emit才是关键
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章