vue封装全局组件,this.$调用,带方法回调

vue封装全局组件,this.$调用,带方法回调

  1. 弹窗组件代码封装
<template>
  <a-config-provider :locale="locale">
    <a-modal
      :title="type == 3 ? '选择岗位' : '选择用户'"
      :visible="visible"
      :width="1400"
      :destroyOnClose="true"
      @ok="sureBtnFn"
      @cancel="cancelBtnFn"
      :zIndex="9999"
      okText="提交"
      cancelText="取消">
      <div class="main_box_page">
        <div class="main_box_page_left">
          <selectTree
            :orgInfo="treeOrgInfo"
            @selectInfo="selectInfo"
            :showChildren="showChildren"
            :orgTreeList="orgTreeList"
            ref="modalTree"></selectTree>
        </div>
        <div class="main_box_page_right">
          <!--  岗位与用户-->
          <a-descriptions title="部门"></a-descriptions>
          <a-row type="flex" :gutter="[8, 8]" class="row-box">
            <a-col :md="4" :sm="24" class="part-tree">
              <a-tree
                showLine
                :selectedKeys="depart"
                @select="partSelect"
                :tree-data="departList"
                :replaceFields="{ title: 'name', key: 'id', children: 'children' }">
              </a-tree>
            </a-col>
            <!-- 岗位树 -->
            <a-col :md="4" :sm="24" class="menu-list">
              <a-checkbox-group v-if="type == 3" v-model="group" name="checkboxgroup">
                <div v-for="item in stationList" :key="item.id" class="check-group">
                  <a-checkbox :value="item.id + '_' + item.stationName"> </a-checkbox
                  ><span @click="getUser(item)"> {{ item.stationName }}</span>
                </div>
              </a-checkbox-group>
              <a-menu v-else v-model="current" mode="inline" @select="selectStation">
                <a-menu-item key="0">全部用户</a-menu-item>
                <a-menu-item
                  :value="item.remark"
                  :title="item.stationName"
                  v-for="item in stationList"
                  :key="item.id"
                  >{{ item.stationName }}</a-menu-item
                >
              </a-menu>
            </a-col>
            <!-- 用户 -->
            <a-col :md="24 - 8" :sm="24">
              <!-- 表头栏 -->
              <a-row>
                <a-col :span="8">
                  <a-descriptions v-if="stationInfo.stationName">
                    <a-descriptions-item label="岗位">
                      {{ stationInfo.stationName }}</a-descriptions-item
                    >
                  </a-descriptions>
                  <span v-else>全部用户</span>
                </a-col>
                <a-col :span="4">
                  <div v-if="type != 3 && showSelf">
                    <a-descriptions>
                      <a-descriptions-item label="流程发起人">
                        <a-checkbox v-model="isSelf"></a-checkbox>
                      </a-descriptions-item>
                    </a-descriptions>
                  </div>
                </a-col>
                <a-col :span="12">
                  <div
                    style="
                      width: 100%;
                      display: flex;
                      justify-content: flex-end;
                      margin-bottom: 8px;
                    ">
                    <a-space :size="15">
                      <a-input-search
                        v-model.trim="queryParam.info"
                        placeholder="查找用户"
                        style="width: 200px"
                        @search="onSearch"
                        allowClear />
                    </a-space>
                  </div>
                </a-col>
              </a-row>
              <!-- Start table  -->
              <a-table
                bordered
                :rowKey="
                  (record, index) => {
                    return record.userId;
                  }
                "
                ref="table"
                size="middle"
                :pagination="ipagination"
                :columns="columns"
                :dataSource="orgUserList"
                :loading="loading"
                :rowSelection="
                  type == 3
                    ? null
                    : {
                        selectedRowKeys: selectedRowKeys,
                        onChange: onSelectChange,
                        type: type == 1 ? 'radio' : 'checkbox'
                      }
                "
                @change="handleTableChange"
                :scroll="{ y: 465 }">
              </a-table>
              <!-- End table  -->
            </a-col>
          </a-row>
        </div>
      </div>
    </a-modal>
  </a-config-provider>
</template>

<script>
  import zhCN from "ant-design-vue/lib/locale-provider/zh_CN";
  import selectTree from "./selectTree";
  export default {
    components: {
      selectTree
    },
    data() {
      return {
        //可传参数
        type: 1, //类型(1单选人2多选人3岗位)默认单选必填
        showChildren: false, //是否展示子层级默认不展示
        orgTreeList: null, //组织树可选默认展示当前项目层级
        treeOrgInfo: {}, //展示项目树的信息(默认当前项目的信息)
        limit: "", //最多勾选的数量
        noEmpty: false, //是否默认必须勾选(默认不必)
        showSelf: false, //是否展示流程发起人勾选框(默认不展示,仅流程配置的时候展示)
        //不可传参数
     
      };
    },
    methods: {
      // 初始化函数
      init() {
        this.visible = true;
        //
        if (this.showSelf) {
          this.isSelf = this.selectionRows.some((item) => item.userId === "${startUserId}");
        }
        //可以通过this.$xx的方式调用之后通过.then(表示确定)或.catch(表示取消)来表示是取消还是成功
        return new Promise((resolve, resject) => {
          this.promiseResult = { resolve, resject };
        });
      },
      // 确定函数
      sureBtnFn() {
        console.log(this.selectionRows, "选中的人");
        console.log(this.group, "选中的组");
        if (this.noEmpty && this.selectionRows.length == 0 && this.group.length == 0) {
          return this.$message.warning("请选中数据后提交!");
        }
        let selectData = this.type == 3 ? this.group : this.selectionRows;
        this.success(selectData);
        //执行销毁组件实例函数
        this.destruction();
      },
      // 取消函数
      cancelBtnFn() {
        // this.promiseResult.resject();
        this.cancel();
        this.destruction();
      },
      // 销毁函数
      destruction() {
        this.visible = false;
        //   销毁实例
        this.$destroy(true);
        //将组件从body中移除
        this.$el.parentNode.removeChild(this.$el);
      },
</script>
<style scoped lang="less">
 
</style>

2、简单分析
现在我们有了一个公共的组件和样式,那么我们就要想,要怎么实现再任意地方使用this. $xxx的方式调用呢。既然通过this. $xxx的方式调用那么我们会想到我们什么时候这样用过这种方式去调用呢?
vuex中我们使用过,全局事件总线我们也使用过。那么我们就必须利用一个vue的一个重要的内置关系VueComponent.prototype.proto===Vue.prototype
那么我就需要把我们组件的一些方法放到Vue的原型上边。只有这样才能实现全局通过this. $xxx的方式调用
使用过vuex的我们都知道,我们需要在创建vm之前使用Vue.use(vuex)的方式才能在全局使用,里边复杂的东西我也不太清楚,不过能确定的一点就是,他里边一定有一个Vue.prototype. $ xxx=xxx,还有就是vuex里边肯定有一个install函数,而且vue会自动调用这个函数
3.Vue.use之前的准备
既然知道了这些,我们就可以利用这些东西写一个配置文件,用于最后的Vue.use最后就能全局使用了,这个是js文件而非vue文件

// 引入弹窗组件
import mySelectUser from './selectUser.vue'
//引入Vue
import Vue from 'vue'

// 创建组件构造函数
const hint = Vue.extend(mySelectUser)
// 注册全局组件
Vue.component('htlSelectUser', hint)
// 创建函数(传入配置对象)
const selectUserFn = function (options) {
    let data = {
        treeOrgInfo: {
            orgId: (options && options.treeOrgInfo && options.treeOrgInfo.orgId) || this.$store.state.project.orgId,
            orgName: (options && options.treeOrgInfo && options.treeOrgInfo.orgName) || this.$store.state.project.orgName,
            orgType: (options && options.treeOrgInfo && options.treeOrgInfo.orgType) || this.$store.state.project.orgType
        },
        type: (options && options.type) || 1,
        limit: (options && options.limit) || '',
        noEmpty: (options && options.noEmpty) || false,
        showChildren: (options && options.showChildren) || false,
        selectionRows: (options && options.type != 3) ? (options && options.selectData) || [] : [],
        selectedRowKeys: (options && options.type != 3) ? ((options && options.selectData) ? options.selectData.map(e => e.userId) : []) || [] : [],
        group: (options && options.type == 3) ? ((options && options.selectData) ? options.selectData.map((e) => `${e.userId}_${e.realname}`) : []) : [],
        showSelf: (options && options.showSelf) || false
    }//参数配置

    // 实例化组件对象
    const Instance = new hint({
        data: data,
        methods: {
            //方法配置
            success(data) {
                if (options && options.showSelf) {
                    options.success(data, this.isSelf)
                } else {
                    options.success(data)
                }
            },
            cancel(data) {
                options.cancel && options.cancel(data)
            },
        }
    })
    // 挂载
    let vm = Instance.$mount()
    // 添加到body里边
    document.body.appendChild(vm.$el)
    //调用的是弹窗组件的init方法

    return vm.init()
}
// 暴露
export default {
    install: (Vue) => {
        Vue.prototype.$htlSelectUser = selectUserFn // 挂到Vue的原型上使用
    }
}

4.main文件的配置及组件的使用

import Vue from 'vue'
import App from './App.vue'
//引入上一步写的js文件
import htlSelectUser from '@/components/htlComps/selectUser/index'
//使用
Vue.use(htlSelectUser )

new Vue({
  render: h => h(App),
   mounted() {
   //我们可以在这里输出的this的原型上看到我们自己定义的方法$hintFn
    console.log('this', this);
  },
}).$mount('#app')

5.使用实例

```vue
<template>
  <div>
    <button @click="show">单选</button>
    <button @click="show1">多选</button>
    <button @click="show2">选择岗位</button>
    <div>选中的数据:{{ SelectData }}</div>
  </div>
</template>

<script>
  export default {
    name: "SelectUser",
    data() {
      return {
        SelectData: []
      };
    },
    methods: {
      show() {
        this.$htlSelectUser({
          type: 1, //类型(1单选人2多选人3岗位)默认单选必填
          selectData: this.SelectData, //回显数据
          showChildren: true, //是否展示子层级默认不展示
          treeOrgInfo: {
            orgId: "so22120617500200000410135",
            orgName: "哈哈哈",
            orgType: 2
          }, //展示项目树的信息(默认当前项目的信息)
          orgTreeList: null, //组织树可选默认展示当前项目层级
          success: (data) => {
            console.log("点击了确定", data);
            this.SelectData = data;//深层对象赋值用$set赋值
          },
          cancel: () => {
            console.log("点击了取消");
          }
        });
      },
      show1() {
        this.$htlSelectUser({
          type: 2,
          selectData: this.SelectData,
          showChildren: true,
          success: (data) => {
            console.log("点击了确定", data);
            this.SelectData = data;
          },
          cancel: () => {
            console.log("点击了取消");
          }
        });
      },
      show2() {
        this.$htlSelectUser({
          type: 3,
          selectData: this.SelectData,
          success: (data) => {
            console.log("点击了确定", data);
            this.SelectData = data.map((item) => {
              let info = item.split("_");
              return { userId: info[0], realname: info[1] };
            });
          },
          cancel: () => {
            console.log("点击了取消");
          }
        });
      }
    }
  };
</script>

参数配置

参数类型必填说明
typestringY类型(1 单选人 2 多选人 3 岗位)默认单选
selectDataArreyY(必传,数据回显)
showChildrenBooleanN是否展示子层级,默认不展示
treeOrgInfoObjectN展示项目树的信息
orgTreeListArreyN组织树可选默认展示当前项目层级
limitNumberN限制选择的最大人数(默认不限制)
noEmptyBooleanN是否必勾选(默认不必)
showSelfBooleanN是否展示流程发起人勾选框(默认不选仅流程配置页面需要) 传True时, success多返回一个参数判断是否勾选的字段 isSelf
successFunctionY点击确定按钮回调
cancelFunctionN点击取消按钮回调

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值