relation between components

本文介绍了一种在父容器中管理多个子组件时,如何通过声明事件和触发机制实现组件间的有效通信。通过具体代码示例展示了如何在一个子组件中触发事件,并由父组件统一管理其他相关组件的状态更新。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    in my project.i meet a problem

    there is a father container .and it contains multiple components.and we generate  an event in one of these child components,but the event  can work needs other child ones.so  we don't  handler it inner itself .and  when we need other ones to support , we assume the event method . it is bad work;

 

   we should do it like this

   we declare an event ,when we tigger the child event ,we can tigger the one we declared earlier. and in the child component ,we need an other method the father container have a call. and in the father component ,we can manager the other ones easily;

 

code

 

componet child 1:

public event EventHander ButtonClick;

private void button1_click(object sender,eventargs e)

{

      if( ButtonClick != null)

       ButtonClick(sender,e);

}

public void ClickButton()

{

   this.textbox.text = "fadfasd";

}

componet child 2;

ListView listview ;

 

componet father ;

componetChild1 c = new componetChild1();

c.ButtonClick += ButtonClick;

componetchild2 p = new componetchild2();

private void ButtonClick(object sender,EventArgs e)

{

    p.listview.enabled= false;

    c.clickButton();

}

修改下面代码,让其只在管理员账号显示商务这个字条(可以通过v-if="$store.state.user.userInfo.businessFlag === 20"代码来判断当前账号是否为管理员账号,但请注意作用域)<!-- --> <template> <div class="table-main"> <div class="flex items-center justify-between"> <div class="flex gap-y-2"> <el-button size="mini" type="warning" v-verify="'root.members.membersBussiness.disable'" @click="stopItem"> 停用 </el-button> <el-button size="mini" type="primary" v-verify="'root.members.membersBussiness.enable'" @click="startItem"> 启动 </el-button> <el-button size="mini" type="primary" v-verify="'root.members.membersBussiness.user'" @click=" visible = !visible resetData('form') " > 添加客户 </el-button> <el-button size="mini" type="danger" v-verify="'root.members.membersBussiness.deleteBatch'" @click="delItem"> 删除 </el-button> <el-button size="mini" type="primary" v-verify="'root.members.membersBussiness.export'" url="/platform/user/export" v-export:userIdList="selected" > 导出 </el-button> <el-button size="mini" @click=" () => { if (selected.length == 0) return $message.warning('请选择数据') quickAxios('/qianhu/api/syncqianhu', 'POST', { ids: selected, paramType: 20 }) } " > 推送 </el-button> <!-- <el-button--> <!-- size="mini"--> <!-- type="primary"--> <!-- v-verify="'root.members.membersBussiness.addUserLabel'"--> <!-- @click="$refs.labelDialog.visible = true">--> <!-- 为选中客户标记标签--> <!-- </el-button>--> </div> <div class="dis-flex"> <!-- <div class="dis-flex" style="padding-right: 10px; white-space: nowrap; align-items: center">--> <!-- 所属商务:--> <!-- <el-input size="mini" v-model="searchForm.relationSaleName" @change="resetData('pages')"></el-input>--> <!-- </div>--> <j-search @change=" val => { params.queryType = Object.keys(val)[0] params.queryValue = val[Object.keys(val)[0]] resetData('pages') } " :options="selectList" /> </div> </div> <div class="mt-4"> <j-table v-loading="loading" :columns="columns" :pages.sync="pages" :total="total" :rows="list" data-key="userId" @pagesChange="getItem" select @select="val => (selected = val)" > <template #userLabelList="{ text }"> <div v-if="text" class="flex flex-wrap items-center gap-2"> <el-tag v-for="(item, index) of text" :key="index" size="small" class="!border-none" :style="{ 'background-color': item.labelColor }" effect="dark" > {{ item.labelName }} </el-tag> </div> </template> <template #masterFlag="{ row }"> <div v-if="accountTypeList.includes(10)"> {{ row.masterFlag ? '主账号' : '子账号' }} </div> <div v-else>{{ row.accountType == 20 ? '常规子账号' : '渠道账号' }}</div> </template> <template #userPackageList="{ text }"> <div v-if="text" class="flex flex-wrap items-center gap-2"> <el-tag class="!border-none" v-for="(item, index) of text" :key="index" size="small" effect="dark"> {{ item.packageLabelName }} </el-tag> </div> </template> <template #custom="{ row }"> <!-- <el-button type="text" @click=" form = { ...row } visible = true "> 编辑 </el-button> --> <el-button type="text" @click="viewItem(row.userId)" v-verify="'root.members.membersBussiness.edit'"> 编辑 </el-button> <el-button type="text" @click="getDitch(row)" v-verify="'root.members.membersBussiness.ditchTag'"> 渠道标签 </el-button> <el-button type="text" @click="getPackTag(row)" v-verify="'root.members.membersBussiness.packTag'"> 包装标签 </el-button> </template> </j-table> </div> <j-dialog v-model="isShow" title="账户详情" width="1200px" cancel="关闭" @cancel="getItem" height="490px"> <account-details ref="details" v-if="isShow" type="company" :params="{ userId }"></account-details> </j-dialog> <j-dialog v-model="visible" title="新增/编辑客户" cancel confirm @ok="sendForm"> <div class="flex items-center mb-4"> <div class="w-[135px] text-right pr-3">账户类型:</div> <div> <el-radio v-model="userType" :label="10" v-if="accountTypeList.includes(10)">主账号</el-radio> <el-radio v-model="userType" :label="20" v-else>子账号</el-radio> </div> </div> <template v-if="userType == 10"> <j-form-auto :config="config" label-width="135px" size="small" v-model="form" ref="form"> <template #levelId> <el-form-item label="客户等级:" prop="levelId" :rules="[{ required: true, message: '请选择客户等级', trigger: 'blur' }]" > <j-dict-select class="w-[220px]" :defOptions="levelList" value-key="id" value-label="levelName" v-model="form.levelId" ></j-dict-select> </el-form-item> </template> <template #storeHouseId="{ item }"> <el-form-item :label="item.label + ':'" prop="storeHouseId" :rules="[{ required: true, message: '请选择仓库', trigger: 'blur' }]" > <el-button @click="$refs.depot.isShow = true" type="primary" size="mini">选择仓库</el-button> <el-tag effect="plain" class="ml-4" v-if="form.storeHouseName"> {{ form.storeHouseName }} </el-tag> </el-form-item> </template> </j-form-auto> <j-form-auto :config="extendConfig" v-model="form.extendInfo" label-width="135px" size="small" ref="extendForm"> <template #mallOrganId> <el-form-item label="归属管理组织:" prop="mallOrganId"> <el-cascader ref="cascader" :props="{ checkStrictly: true, value: 'id', label: 'organName', children: 'childrenList', }" :value="[form.extendInfo.mallGroupId, form.extendInfo.mallOrganId]" :options="organTree" @change="selectChart" ></el-cascader> </el-form-item> </template> <template #relationSaleId> <el-form-item label="商务:" prop="relationSaleId"> <el-button type="primary" size="mini" @click="$refs.relation.isShow = true">绑定商务</el-button> <el-tag type="primary" class="ml-4" size="small" v-if="form.extendInfo.relationSaleName"> {{ form.extendInfo.relationSaleName }} </el-tag> </el-form-item> </template> </j-form-auto> <j-form-auto :config="comConfig" v-model="form.corpInfo" label-width="135px" size="small" ref="comForm"> <template #legalInfoCertList="{ item }"> <el-form-item :label="item.label + ':'" prop="legalInfoCertList" :rules="item.rules"> <div class="flex items-center gap-3"> <div class="flex-col flex-center" v-for="(item, index) of form.corpInfo.legalInfoCertList" :key="index" > <j-upload v-model="item.certFileUrl" :limit="1" serialize /> <div class="mt-2 text-xs text-neutral-500">{{ item.certName }}</div> </div> </div> </el-form-item> </template> <el-form-item label="所在地址:" prop="" :rules="[ { required: true, message: '请选择地址', trigger: ['change', 'blur'], }, { validator: (rule, e, callback) => { const value = this.form.extendInfo console.log(value) if (value) { if (!value.province) { callback(new Error('请选择省份')) return } if (!value.city) { callback(new Error('请选择城市')) return } if (!value.county) { callback(new Error('请选择区/县')) return } callback() } else { callback(new Error('省份')) } }, trigger: 'blur', }, ]" > <j-address :attrs="{ province: { disabled: false }, city: { disabled: false }, }" class="!grid !grid-cols-3 [&_.el-select]:block" @change="onChangeArea" ></j-address> </el-form-item> </j-form-auto> </template> <template v-else> <j-form-auto :config="sonConfig" label-width="135px" size="small" v-model="form" ref="sonForm"> <template #masterId> <el-form-item label="所属主账号:" prop="masterId" :rules="[{ required: true, message: '请选择主账号', trigger: 'blur' }]" > <el-button type="primary" @click="$refs.user.isShow = true">绑定主账号</el-button> <div>{{ form.masterName }}</div> </el-form-item> </template> </j-form-auto> </template> </j-dialog> <label-dialog ref="labelDialog" :userIdList="selected" @closeDialog=" $refs.labelDialog.visible = false getItem() " ></label-dialog> <j-dialog ref="channel" title="标记渠道标签" cancel confirm @ok="val => quickAxios(`/platform/user/channel/save/${userId}`, 'POST', { channelList }, val)" > <j-dict-multiple v-if="masterFlag" type="checkbox" size="small" key="master" :value="form.channelIdList" value-key="id" @change=" val => { channelList = val.map(item => { return { channelName: item.itemName, channelId: item.id } }) } " dictCode="10007" ></j-dict-multiple> <j-dict-multiple v-else-if="channels.length && row.accountType != 20" type="checkbox" size="small" json key="son" value-key="channelId" value-label="channelName" :value="channelList" @change="val => (channelList = val)" :defOptions="channels" ></j-dict-multiple> <div v-else>该账户暂无关联渠道</div> </j-dialog> <j-dialog ref="packaging" title="标记包装标签" cancel confirm @ok="setPackTag"> <div v-if="masterFlag"> <el-button type="primary" size="mini" @click="$refs.packTag.isShow = true">添加</el-button> </div> <table class="mt-4"> <tr> <th>标签名称</th> <th>标签可选包装</th> </tr> <tr v-for="(item, index) of packList" :key="index"> <td> {{ item.itemName }} </td> <td> <template v-if="item.itemExtend"> <el-checkbox :disabled="ele.disabled" v-for="(ele, i) of item.itemExtend" :key="i" :true-label="10" :false-label="20" v-model="ele.checkedFlag" > {{ ele.itemName }} </el-checkbox> </template> </td> </tr> </table> </j-dialog> <j-dialog ref="packTag" title="选择包装标签" cancel confirm @ok=" packList = $refs.packList.idList.map(item => { return { ...item, itemExtend: JSON.parse(item.itemExtend) } }) $refs.packTag.isShow = false " > <pack-tag ref="packList"></pack-tag> </j-dialog> <relation-list ref="relation" :params="{ businessFlag: 10, organId: form.extendInfo.mallOrganId }" @change=" val => { form.extendInfo.relationSaleId = val.id form.extendInfo.relationSaleName = val.loginAccount } " ></relation-list> <j-dialog ref="depot" width="1200px" title="选择仓库" cancel confirm @ok="$refs.depot.isShow = false"> <goods-depot ref="goodsDepot" class="!p-0" radio @radioChange=" val => { form.storeHouseId = val.id form.storeHouseName = val.storeHouseName } " ></goods-depot> </j-dialog> <user-list :params="{ accountTypeList: [10], userType: 20 }" ref="user" json @change=" val => { form.masterName = val.loginAccount form.masterId = val.userId $refs.user.isShow = false } " ></user-list> </div> </template> <script> import jSearch from '@/components/j-search.vue' import AccountDetails from '../AccountDetails.vue' import LabelDialog from './labelDialog.vue' import packTag from '../../category/packTag.vue' import UserList from '@/components/user-list.vue' import RelationList from '@/components/relation-list.vue' import JUpload from '@/components/j-upload.vue' import GoodsDepot from '../../commodity/goodsDepot.vue' import JAddress from '@/components/j-address.vue' // import引入的组件需要注入到对象中才能使用 export default { props: { accountTypeList: { type: Array, default: () => [], }, }, components: { jSearch, AccountDetails, LabelDialog, packTag, UserList, RelationList, JUpload, GoodsDepot, JAddress }, data() { // 这里存放数据 return { loading: true, row: {}, // 组织集合 organTree: [], // 已选渠道标签 channelList: [], // 渠道标签集合 channels: [], // 包装标签集合 packList: [], params: { userType: 20 }, userInfo: {}, pages: { pageNum: 1, pageSize: 10, }, userType: this.accountTypeList.includes(10) ? 10 : 20, userId: '', isShow: false, visible: false, masterFlag: false, searchForm: { relationSaleName: '', }, form: { levelId: '', accountType: 20, storeHouseId: '', storeHouseName: '', masterName: '', corpInfo: { legalInfoCertList: [], }, extendInfo: { relationSaleName: '', mallOrganId: '', relationSaleId: '', }, }, list: [], config: [ { label: '用户名', name: 'loginAccount', type: 'input', required: true, attrs: { maxlength: 50, 'show-word-limit': true, }, }, { label: '密码', name: 'loginPwd', type: 'input', required: true, rules: [{ type: 'password' }] }, { label: '确认密码', name: 'userPwdCfm', type: 'input', required: true, rules: [ { validator: (rule, value, callback) => { if (value === '') { callback(new Error('请输入密码')) } else if (value != this.form.loginPwd) { callback(new Error('两次密码输入不一致')) } else { callback() } }, trigger: 'blur', }, ], }, { label: '手机号', name: 'phone', type: 'phone', required: true, rules: [{ type: 'phone' }] }, { label: '客户等级', name: 'levelId' }, { label: '客户生日', name: 'extendInfo.birthday', type: 'date' }, { required: true, label: '仓库', name: 'storeHouseId' }, ], extendConfig: [ { label: '归属组织', name: 'mallOrganId', type: 'input', required: true }, { label: '商务', name: 'relationSaleId', type: 'input', required: true }, ], comConfig: [ { label: '企业名称', name: 'corpName', type: 'input', required: true }, { label: '统一信用社代码', name: 'unifiedSocialCreditCode', type: 'input', required: true, rules: [{ type: 'creditCode' }], }, { label: '法定代表人', name: 'personName', type: 'input', required: true }, { label: '公司电话', name: 'corpPhone', type: 'phone', required: true, rules: [{ type: 'phone' }], }, { label: '公司网站', name: 'corpSite', type: 'input' }, { label: '企业类型', name: 'corpTypeId', type: 'dictCode', dictCode: 60001, attrs: { 'value-key': 'id' }, }, { label: '证照类型 ( 信息 )', name: 'legalInfoCertList', required: true, rules: [ { validator: (rule, value, callback) => { if (value && value.length) { const flag = value.find(item => { if (item.isNeed == 10) { return !!item.certFileUrl } else { return true } }) if (!flag) { callback(new Error('请上传营业执照')) } else { callback() } } else { callback(new Error('请上传营业执照')) } }, trigger: 'blur', }, ], }, ], sonConfig: [ { label: '子账号类型', name: 'accountType', type: 'radio-group', options: [ { label: '常规子账号', value: 20 }, { label: '渠道账号', value: 25 }, ], required: true, }, { name: 'masterId', }, { label: '用户名', name: 'loginAccount', type: 'input', required: true }, { label: '手机号', name: 'phone', type: 'phone', required: true, rules: [{ type: 'phone' }] }, { label: '密码', name: 'loginPwd', type: 'input', required: true }, { label: '邮箱', name: 'email', type: 'input', rules: [{ type: 'email' }], required: true }, ], selected: [], levelList: [], selectList: [ { label: '用户名', value: '10' }, { label: '手机号', value: '15' }, { label: '邮箱', value: '20' }, { label: '主账号', value: '25' }, { label: '真实姓名', value: '30' }, { label: '公司名称', value: '35' }, { label: '所属商务', value: '40' }, ], columns: [ // { label: '标签', name: 'userLabelList', width: 150 }, { label: '包装标签', name: 'userPackageList', width: 150 }, { label: '用户名', name: 'loginAccount' }, { label: '所属主账号', name: 'masterLoginAccount', hidden: this.accountTypeList.includes(10) }, // { label: '客户类型', name: 'userType', custom: val => (val == 10 ? '零售' : '企业客户') }, { label: '企业名称', name: 'legalName' }, { label: '账户类型', name: 'masterFlag', hidden: this.accountTypeList.includes(10) }, { label: '邮箱', name: 'email' }, { label: '手机号', name: 'phone' }, { label: '商务', name: 'extendInfo', custom: val => val.relationSaleName }, { label: '地区', name: 'extendInfo', custom: val => val.realAddress }, //{ label: '生日', name: 'extendInfo', custom: val => val.birthday }, { label: '创建时间', name: 'cdate' }, { label: '性别', name: 'extendInfo', custom: val => this.sexType[val.sex] || '未知' }, // { label: '注册IP', name: 'registerIp' }, { label: '状态', name: 'state', custom: val => (val == 10 ? '可用' : '禁用') }, { label: '操作', name: 'custom', width: '250px', fixed: 'right' }, ], total: 0, sexType: { 10: '男', 20: '女', 30: '未知', }, } }, watch: { 'form.corpInfo.corpTypeId': { handler(val) { Request.GET(`/platform/corpRelation/cert/listByCorpType/${val}`, {}, res => { if (res.code == 200) { this.form.corpInfo.legalInfoCertList = res.data.map(item => { return { ...item, certFileUrl: '', } }) } }) }, }, }, // 监听属性 类似于data概念 computed: { // 请求的包装标签字段 }, // 生命周期 - 创建完成(可以访问当前this实例) created() { this.getItem() Request.GET(`/platform/userLeveDict/listLevel`, { levelUserType: 20 }, res => { if (res.code == 200) { this.levelList = res.data } }) Request.GET(`/platadmin/organ/ztree`, {}, res => { if (res.code == 200) { res.data.forEach(item => { item.childrenList.forEach(ele => { ele.childrenList = [] }) }) this.organTree = this.getCascader(res.data) } }) }, // 生命周期 - 挂载完成(可以访问DOM元素) mounted() {}, // 方法集合 methods: { onChangeArea(e) { let form = { ...this.form.extendInfo } form = Object.assign({}, form, e) form.cityText = e.city form.city = e.cityCode form.countyText = e.county form.county = e.countyCode form.provinceText = e.province form.province = e.provinceCode this.form.extendInfo = form }, // 选择组织 selectChart(val) { this.form.extendInfo.mallGroupId = val[0] this.form.extendInfo.mallOrganId = val[1] const row = this.$refs['cascader'].getCheckedNodes()[0] this.form.extendInfo.mallGroupName = row.pathLabels[0] this.form.extendInfo.mallOrganName = row.pathLabels[1] }, // 获取关联的渠道 async getDitch(row) { this.masterFlag = row.masterFlag this.row = row this.channelList = [] if (!row.masterFlag) { Request.GET(`/platform/user/details/${row.masterId}`, {}, res => { this.channels = res.data.channelList || [] Request.GET(`/platform/user/channel/list/${row.userId}`, {}, res => { this.$nextTick(() => { this.channelList = res.data || [] }) }) }) } else { this.form = { ...row } } this.$refs.channel.isShow = true this.userId = row.userId this.$forceUpdate() }, // 获取关联的包装标签 async getPackTag(row) { this.masterFlag = row.masterFlag if (!row.masterFlag) { Request.GET(`/platform/user/details/${row.masterId}`).then(res => { Request.GET(`/platform/user/packageLabel/list/${row.userId}`, {}, ({ data }) => { const selected = [] const userPackageList = res.data.userPackageList || [] data.forEach(item => { item.packageList.forEach(ele => { if (ele.checkedFlag == 10) { selected.push(ele.itemId) } }) }) this.$refs.packaging.isShow = true this.userId = row.userId userPackageList.forEach(item => { item.packageList.forEach(ele => { if (ele.checkedFlag == 10) { ele.disabled = false } else { ele.disabled = true } if (selected.includes(ele.itemId)) { ele.checkedFlag = 10 } else { ele.checkedFlag = 20 } }) }) this.packList = userPackageList.map(item => { return { itemName: item.packageLabelName, itemId: item.packageLabelId, itemExtend: item.packageList, } }) }) }) } else { Request.GET(`/platform/user/packageLabel/list/${row.userId}`, {}, res => { this.$refs.packaging.isShow = true this.userId = row.userId this.packList = res.data && res.data.map(item => { return { itemName: item.packageLabelName, itemId: item.packageLabelId, itemExtend: item.packageList, } }) }) } }, setPackTag() { const itemList = this.packList.map(item => { const packageList = [] item.itemExtend.forEach(ele => { packageList.push({ itemId: ele.itemId, itemName: ele.itemName, checkedFlag: ele.checkedFlag == 10 ? 10 : 20, }) }) return { packageLabelId: item.itemId, packageLabelName: item.itemName, packageList, } }) Request.POST(`/platform/user/packageLabel/save/${this.userId}`, { itemList }, res => { if (res.code == 200) { this.$refs.packaging.isShow = false this.getItem() this.$message.success('保存成功') } }) }, startItem() { if (!this.selected.length) return this.$message.warning('请选择数据') Request.POST('/platform/user/updateUserState/10', { idList: this.selected }, res => { if (res.code == 200) { this.getItem() this.$message.success('启用成功') } }) }, stopItem() { if (!this.selected.length) return this.$message.warning('请选择数据') Request.POST('/platform/user/updateUserState/20', { idList: this.selected }, res => { if (res.code == 200) { this.getItem() this.$message.success('禁用成功') } }) }, delItem() { if (!this.selected.length) return this.$message.warning('请选择数据') Request.POST('/platform/user/deleteBatch', { idList: this.selected }, res => { if (res.code == 200) { this.getItem() this.$message.success('删除成功') } }) }, sendForm() { const form = { ...this.form } if (this.userType == 10) { this.$refs.form.submit().then(_ => { this.$refs.extendForm.submit().then(_ => { this.$refs.comForm.submit().then(_ => { if (this.form.userId) { Request.POST(`/platform/user/update/${this.form.userId}`, { ...form }, res => { if (res.code == 200) { this.visible = false this.getItem() this.$message.success('编辑成功') } }) } else { Request.POST('/platform/user/add', { ...form }, res => { if (res.code == 200) { this.visible = false this.getItem() this.$message.success('新增成功') } }) } }) }) }) } else { this.$refs.sonForm.submit().then(_ => { Request.POST('/platform/user/subAccount/add', { ...form }, res => { if (res.code == 200) { this.visible = false this.getItem() this.$message.success('新增成功') } }) }) } }, viewItem(id) { this.userId = id this.isShow = true }, getItem() { this.loading = true Request.POST( '/platform/user/pageList', { ...this.pages, ...this.params, accountTypeList: this.accountTypeList, ...this.searchForm, checkState: this.accountTypeList.includes(25) ? 20 : '', }, res => { this.loading = false if (res.code == 200) { this.list = res.data.content this.total = res.data.total } } ) }, }, } </script> <style lang="scss" scoped> //@import url(); 引入公共css类 table { border-collapse: collapse; } table, th, td { font-weight: 400; border: 1px solid #dcdfe6; padding: 8px 16px; } </style>
06-06
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值