组件的好处就是可以重复使用,坏处就是父子组件之间的通信相对比较麻烦,但是掌握了父子组件之间的通信后组件的应用就很简单了。下面是实战,最后是思路。
项目的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才是关键