关于vue2 antd 碰到的问题总结下

 // 当 realReceiveMoney 改变时,handleRealReceiveMoneyChange 方法会被触发,这会强制重新验证 remark 字段。

    // 这确保了当 realReceiveMoney 小于 20 时,remark 字段变为必填,而在其他情况下则不必填。

1.关于vue2 antd 视图更新问题

1.一种强制更新 

Vue2是通过用Object…defineProperty来设置数据的getter和setter实现对数据和以及视图改变的监听的。对于数组和对象这种引用类型来说,getter和setter无法检测到它们内部的变化。用这种

 this.$set(this.form, "fileUrl", urlArr.join(","));

2.如果碰到

a-form :form="form"

 form: this.$form.createForm(this),

    <a-form :form="form" @submit="handleSubmit">
        <a-form-item
          :labelCol="labelCol"
          :wrapperCol="wrapperCol"
          label="上级仓库"
          hasFeedback
        >
          <a-tree-select
            :treeData="dataSource"
            placeholder="请选择"
            :replaceFields="{
              title: 'name',
              key: 'id',
              value: 'id',
              children: 'children',
            }"
            v-decorator="['parentId', { initialValue: formData.parentId }]"
          />
        </a-form-item>
        <a-form-item
          :labelCol="labelCol"
          :wrapperCol="wrapperCol"
          label="仓库名称"
          hasFeedback
        >
          <a-input
            placeholder="仓库名称"
            v-decorator="[
              'name',
              {
                initialValue: formData.name,
                rules: validatorRules.inputIf.rules,
              },
            ]"
          />
        </a-form-item>
        <a-form-item
          :labelCol="labelCol"
          :wrapperCol="wrapperCol"
          label="所属机构"
          required
        >
          <vorganTree
            v-decorator="[
              'orgId',
              {
                initialValue: formData.orgId,
                rules: validatorRules.inputIf.rules,
              },
            ]"
          ></vorganTree>
        </a-form-item>
        <a-form-item
          :labelCol="labelCol"
          :wrapperCol="wrapperCol2"
          label="位置地点"
        >
          <div class="disflex">
            <a-input
              v-decorator="[
                'address',
                {
                  initialValue: formData.address,
                  rules: validatorRules.inputIf.rules,
                },
              ]"
            />
            <a-icon type="environment" @click="mapShow(true)" class="mapico" />
            <a-button type="link" @click="mapShow(true)">选择地点</a-button>
          </div>
        </a-form-item>
      </a-form>

a-form :form="form"

 form: this.$form.createForm(this),

那么使用

this.form.setFieldsValue({ address: val.address })来更新表单的值,以触发视图的更新。

清空的话

this.form.resetFields();

3.通常双向绑定如果不行试试前两种。

2.关于封装好了表格 使用

1.导入

import STable from "@/components/table/";

index.js

import T from "ant-design-vue/es/table/Table";
import get from "lodash.get"
export default {
  data() {
    return {
      needTotalList: [],
      selectedRows: [],
      selectedRowKeys: [],

      localLoading: false,
      localDataSource: [],
      localPagination: Object.assign({}, T.props.pagination)
    };
  },
  props: Object.assign({}, T.props, {
    rowKey: {
      type: [String, Function],
      default: 'id'
    },
    data: {
      type: Function,
      required: true
    },
    pageNum: {
      type: Number,
      default: 1
    },
    pageSize: {
      type: Number,
      default: 10
    },
    showSizeChanger: {
      type: Boolean,
      default: true
    },
    showAlertInfo: {
      type: Boolean,
      default: false
    },
    showPagination: {
      default: 'auto'
    },
    deleteShow: { // 删除键
      type: Boolean,
      default: false
    },
    bordered: {
      type: Boolean,
      default: true
    },
  }),
  watch: {
    'localPagination.current'(val) {
      this.$router.push({
        name: this.$route.name,
        params: Object.assign({}, this.$route.params, {
          current: val
        }),
      });
    },
    pageNum(val) {
      Object.assign(this.localPagination, {
        current: val
      });
    },
    pageSize(val) {
      Object.assign(this.localPagination, {
        pageSize: val
      });
    },
    showSizeChanger(val) {
      Object.assign(this.localPagination, {
        showSizeChanger: val
      });
    }
  },
  zzh() {
    const that = this
    return that;
  },
  created() {
    this.localPagination = ['auto', true].includes(this.showPagination) && Object.assign({}, this.localPagination, {
      current: this.pageNum,
      pageSize: this.pageSize,
      showSizeChanger: this.showSizeChanger
    });
    this.needTotalList = this.initTotalList(this.columns)
    this.loadData();
  },
  methods: {
    loadingShow(value) {
      this.localLoading = value
    },
    refresh() {
      var mm = {
        current: 1,
        total: 0,
        size: this.pageSize,
      }
      this.loadData(mm);
    },
    deleteRefresh() {
      this.loadData()
    },
    loadData(pagination, filters, sorter) {
      this.localLoading = true
      var result = this.data(
        Object.assign({
          current: (pagination && pagination.current) ||
            this.localPagination.current,
          size: (pagination && pagination.pageSize) ||
            this.localPagination.pageSize
        },
          (sorter && sorter.field && {
            sortField: sorter.field
          }) || {},
          (sorter && sorter.order && {
            sortOrder: sorter.order
          }) || {}, {
          ...filters
        }
        )
      );

      if (result instanceof Promise) {
        result.then(r => {
          this.localPagination = Object.assign({}, this.localPagination, {
            current: (pagination && pagination.current) ||
              this.localPagination.current,  // 返回结果中的当前分页数
            total: r.totalCount, // 返回结果中的总记录数
            showSizeChanger: this.showSizeChanger,
            pageSize: (pagination && pagination.pageSize) ||
              this.localPagination.pageSize
          });

          !r.totalCount && ['auto', false].includes(this.showPagination) && (this.localPagination = false)
          this.localDataSource = r.data; // 返回结果中的数组数据
          this.localLoading = false
        });
      }
    },
    initTotalList(columns) {
      const totalList = []
      columns && columns instanceof Array && columns.forEach(column => {
        if (column.needTotal) {
          totalList.push({
            ...column,
            total: 0
          })
        }
      })
      return totalList
    },
    updateSelect(selectedRowKeys, selectedRows) {
      this.selectedRowKeys = selectedRowKeys
      this.selectedRows = selectedRows
      let list = this.needTotalList
      this.needTotalList = list.map(item => {
        return {
          ...item,
          total: selectedRows.reduce((sum, val) => {
            let total = sum + get(val, item.dataIndex)
            return isNaN(total) ? 0 : total
          }, 0)
        }
      })
    },
    updateEdit() {
      this.selectedRows = []
    },
    onClearSelected() {
      this.selectedRowKeys = []
      this.selectedRows = []
      this.updateSelect([], [])
      this.$emit('emptyData', { selectedRowKeys: [], selectedRows: [] })
      this.$emit('onSelect', { selectedRowKeys: [], selectedRows: [] })
    },
    onDeleteSelected() {
      this.$emit('DeleteData')
    },
    handleRowClick(record) {
      const selectedRowKeys = [...this.selectedRowKeys];
      const selectedRows = [...this.selectedRows];

      const rowKey = typeof this.rowKey === 'function' ? this.rowKey(record) : record[this.rowKey];

      const rowIndex = selectedRowKeys.indexOf(rowKey);
      if (rowIndex >= 0) {
        selectedRowKeys.splice(rowIndex, 1);
        selectedRows.splice(rowIndex, 1);
      } else {
        selectedRowKeys.push(rowKey);
        selectedRows.push(record);
      }

      this.updateSelect(selectedRowKeys, selectedRows);
      this.$emit('onSelect', { selectedRowKeys, selectedRows });
    },
    renderMsg(h) {
      const _vm = this
      this.that = this
      let d = []

      return d
    },
    renderAlert(h) {
      return h('span', {
        slot: 'message'
      }, this.renderMsg(h))
    },
  },

  render(h) {
    const _vm = this

    let props = {},
      localKeys = Object.keys(this.$data);

    Object.keys(T.props).forEach(k => {
      let localKey = `local${k.substring(0, 1).toUpperCase()}${k.substring(1)}`;
      if (localKeys.includes(localKey)) {
        return props[k] = _vm[localKey];
      }
      return props[k] = _vm[k];
    })


    // 显示信息提示
    if (this.showAlertInfo) {

      props.rowSelection = {
        selectedRowKeys: this.selectedRowKeys,
        onChange: (selectedRowKeys, selectedRows) => {
          _vm.updateSelect(selectedRowKeys, selectedRows)
          _vm.$emit('onSelect', { selectedRowKeys: selectedRowKeys, selectedRows: selectedRows })
        }
      };

      props.customRow = (record) => ({
        on: {
          click: () => {
            _vm.handleRowClick(record);
          },
        },
      });

      return h('div', {}, [
        h("a-table", {
          tag: "component",
          attrs: props,
          on: {
            change: _vm.loadData
          },
          scopedSlots: this.$scopedSlots
        }, this.$slots.default)
      ]);

    }

    props.customRow = (record) => ({
      on: {
        click: () => {
          _vm.handleRowClick(record);
        },
      },
    });

    return h("a-table", {
      tag: "component",
      attrs: props,
      on: {
        change: _vm.loadData
      },
      scopedSlots: this.$scopedSlots
    }, this.$slots.default);

  },
};

使用

 <s-table
            ref="tableAssets"
            size="default"
            :rowKey="(record) => record.id"
            :columns="columns1"
            :data="loadDataListAssets"
            :showAlertInfo="true"
            @onSelect="onChangeAssetsList"
          ></s-table>




 loadDataListAssets: (parameter) => {
        return getUserPage(Object.assign(parameter, this.listAssetsParam)).then(
          (res) => {
            var mm = { data: [] };
            mm.size = res.data.size;
            mm.current = res.data.current;
            mm.totalCount = res.data.total;
            mm.totalPage = res.data.pages;
            mm.data = res.data.records;
            return mm;
          }
        );
      },


    onChangeAssetsList(row) {
      console.log(row);
      let self = this;
      self.personList = [];
      let arr = [...new Set([...row.selectedRows])];
      let AssetsListRow = [
        ...new Set([...self.AssetsListRow.concat(arr), ...arr]),
      ];
      self.AssetsListRow = AssetsListRow.filter((item) =>
        row.selectedRowKeys.includes(item.id)
      );
      self.personList = [...new Set([...self.AssetsListRow, ...arr])];
      // self.personList = [...new Set([...self.personList, ...arr])];
      // const strings = self.personList.map((item) => JSON.stringify(item));
      // const removeDupList = Array.from(new Set(strings));
      // const result = removeDupList.map((item) => JSON.parse(item));
      // self.personList = result;
    },

有slot使用

 <s-table ref="tableAssets2" size="default" :columns="columns2" :data="loadDataListAssets2">
              <span slot="action" slot-scope="text, record" class="flx-row-c-c">
                <div>
                  <a @click="handleDel(record)">删除</a>
                </div>
              </span>
</s-table> 
           

3.关于单选封装好的组件使用

    <j-select-supplier
                  v-decorator="['supplierId']"
                  :multiple="false"
                  @accountData="accountData2"
                ></j-select-supplier>



import JSelectSupplier from "@/components/jeecgbiz/JSelectSupplier";



    accountData2(e) {
      if (e.length > 0) {
        this.editform.supplierName = e[0].name;
        this.editform.supplierId = e[0].id;
      } else {
        this.editform.supplierName = "";
        this.editform.supplierId = "";
      }
      console.log(e);
    },
<template>
  <!-- 定义在这里的参数都是不可在外部覆盖的,防止出现问题 -->
  <j-select-biz-component-two
    :value="value"
    :ellipsisLength="25"
    :listUrl="url.list"
    :columns="columns"
    :multiple="false"
    v-on="$listeners"
    v-bind="attrs"
    @commitData="commitData"
  />
</template>

<script>
import JSelectBizComponentTwo from "./JSelectBizComponentTwo";

export default {
  name: "JSelectSupplier",
  components: { JSelectBizComponentTwo },
  props: ["value"],
  data() {
    return {
      url: { list: "/asset/supplierinfo/page" },
      columns: [
        { title: "供应商", align: "center", dataIndex: "name" },
        {
          title: "联系人",
          align: "center",

          dataIndex: "linkman",
        },
        {
          title: "联系电话",
          align: "center",

          dataIndex: "phone",
        },
      ],
      // 定义在这里的参数都是可以在外部传递覆盖的,可以更灵活的定制化使用的组件
      default: {
        name: "供应商",
        width: "80%",
        displayKey: "name",
        returnKeys: ["id", "name"],
        rowKey: "id",
        valueKey: "id",
        queryParamText: "供应商名称", //左侧搜索框名称
        queryParamCode: "name", //左侧搜索框字段名
      },
    };
  },
  computed: {
    attrs() {
      return Object.assign(this.default, this.$attrs);
    },
  },
  methods: {
    // 提交数据
    commitData(e) {
      console.log(e);
      this.$emit("accountData", e);
    },
  },
};
</script>

<style lang="less" scoped></style>

外层也就是index

<template>
  <a-row class="j-select-biz-component-box" type="flex" :gutter="8">
    <a-col class="left" :class="{'full': !buttons}">
      <slot name="left">
        <a-select
          mode="multiple"
          :placeholder="placeholder"
          v-model="selectValue"
          :options="selectOptions"
          allowClear
          :disabled="disabled"
          :open="selectOpen"
          style="width: 100%;"
          @dropdownVisibleChange="handleDropdownVisibleChange"
          @click.native="visible=(buttons?visible:true)"
        />
      </slot>
    </a-col>

    <a-col v-if="buttons" class="right">
      <a-button type="primary" icon="search" :disabled="disabled" @click="visible=true">{{selectButtonText}}</a-button>
    </a-col>

    <j-select-biz-component-modal
      v-model="selectValue"
      :visible.sync="visible"
      v-bind="modalProps"
      :multiple="multiple"
      @options="handleOptions"
      @commitData="commitData"
    />
  </a-row>
</template>

<script>
  import JSelectBizComponentModal from './JSelectBizComponentModal'

  export default {
    name: 'JSelectBizComponent',
    components: { JSelectBizComponentModal },
    props: {
      value: {
        type: String,
        default: ''
      },
      /** 是否返回 id,默认 false,返回 code */
      returnId: {
        type: Boolean,
        default: false
      },
      placeholder: {
        type: String,
        default: '请选择'
      },
      disabled: {
        type: Boolean,
        default: false
      },
      // 是否支持多选,默认 true
      multiple: {
        type: Boolean,
        default: true
      },
      // 是否显示按钮,默认 true
      buttons: {
        type: Boolean,
        default: true
      },
      // 显示的 Key
      displayKey: {
        type: String,
        default: null
      },
      // 返回的 key
      returnKeys: {
        type: Array,
        default: () => ['id', 'id']
      },
      // 选择按钮文字
      selectButtonText: {
        type: String,
        default: '选择'
      },

    },
    data() {
      return {
        selectValue: [],
        selectOptions: [],
        dataSourceMap: {},
        visible: false,
        selectOpen: false,
      }
    },
    computed: {
      valueKey() {
        return this.returnId ? this.returnKeys[0] : this.returnKeys[1]
      },
      modalProps() {
        return Object.assign({
          valueKey: this.valueKey,
          multiple: this.multiple,
          returnKeys: this.returnKeys,
          displayKey: this.displayKey || this.valueKey
        }, this.$attrs)
      },
    },
    watch: {
      value: {
        immediate: true,
        handler(val) {
          console.log('cake撒',val)
          if (val) {
            this.selectValue = val.split(',')
          } else {
            this.selectValue = []
          }
        }
      },
      selectValue: {
        deep: true,
        handler(val) {
          console.log(this.materialUseTime)
          let rows = val.map(key => this.dataSourceMap[key])
          this.$emit('select', rows)
          let data = val.join(',')
          this.$emit('input', data)
          this.$emit('change', data)
        }
      }
    },
    methods: {
      commitData(e) {
        this.$emit('commitData',e)
      },
      handleOptions(options, dataSourceMap) {
        this.selectOptions = options
        this.dataSourceMap = dataSourceMap
      },
      handleDropdownVisibleChange() {
        // 解决antdv自己的bug —— open 设置为 false 了,点击后还是添加了 open 样式,导致点击事件失效
        this.selectOpen = true
        this.$nextTick(() => {
          this.selectOpen = false
        })
      },
    }
  }
</script>

<style lang="less" scoped>
  .j-select-biz-component-box {

    @width: 82px;

    .left {
      width: calc(100% - @width - 8px);
    }

    .right {
      width: @width;
    }

    .full {
      width: 100%;
    }

    /deep/ .ant-select-search__field {
      display: none !important;
    }
  }
</style>

 内层

<template>
  <a-modal
    centered
    :title="name + '选择'"
    :width="width"
    :visible="visible"
    @ok="handleOk"
    @cancel="close"
    cancelText="关闭"
  >
    <a-row :gutter="18">
      <a-col :span="16">
        <!-- 查询区域 -->
        <div class="table-page-search-wrapper">
          <a-form layout="inline">
            <a-row :gutter="24">
              <a-col :span="14">
                <a-form-item :label="queryParamText || name">
                  <a-input
                    v-model="queryParam[queryParamCode || valueKey]"
                    :placeholder="'请输入' + (queryParamText || name)"
                    @pressEnter="searchQuery"
                  />
                </a-form-item>
              </a-col>
              <a-col :span="8">
                <span
                  style="float: left; overflow: hidden"
                  class="table-page-search-submitButtons"
                >
                  <a-button type="primary" @click="searchQuery" icon="search"
                    >查询</a-button
                  >
                  <a-button
                    type="primary"
                    @click="searchReset"
                    icon="reload"
                    style="margin-left: 8px"
                    >重置</a-button
                  >
                </span>
              </a-col>
            </a-row>
          </a-form>
        </div>

        <a-table
          size="small"
          bordered
          :rowKey="rowKey"
          :columns="innerColumns"
          :dataSource="dataSource"
          :pagination="ipagination"
          :loading="loading"
          :scroll="{ y: 240 }"
          :rowSelection="{
            selectedRowKeys,
            onChange: onSelectChange,
            type: multiple ? 'checkbox' : 'radio',
            width: '60px',
          }"
          :customRow="customRowFn"
          @change="handleTableChange"
        >
        </a-table>
      </a-col>
      <a-col :span="8">
        <a-card
          :title="'已选中的' + name"
          :bordered="false"
          :head-style="{ padding: 0 }"
          :body-style="{ padding: 0 }"
        >
          <a-table
            size="small"
            :rowKey="rowKey"
            bordered
            v-bind="selectedTable"
          >
            <span slot="action" slot-scope="text, record, index">
              <a @click="handleDeleteSelected(record, index)">删除</a>
            </span>
          </a-table>
        </a-card>
      </a-col>
    </a-row>
  </a-modal>
</template>

<script>
// import { getAction } from '@/api/manage'
import Ellipsis from "@/components/Ellipsis";
import { JeecgListMixin } from "@/mixins/JeecgListMixin";
import { cloneObject, pushIfNotExist } from "@/utils/util";

export default {
  name: "JSelectBizComponentModal",
  mixins: [JeecgListMixin],
  components: { Ellipsis },
  props: {
    value: {
      type: Array,
      default: () => [],
    },
    visible: {
      type: Boolean,
      default: false,
    },
    valueKey: {
      type: String,
      required: true,
    },
    multiple: {
      type: Boolean,
      default: true,
    },
    width: {
      type: [Number, String],
      default: "80%",
    },

    name: {
      type: String,
      default: "",
    },
    listUrl: {
      type: String,
      required: true,
      default: "",
    },
    // 根据 value 获取显示文本的地址,例如存的是 username,可以通过该地址获取到 realname
    valueUrl: {
      type: String,
      default: "",
    },
    displayKey: {
      type: String,
      default: null,
    },
    columns: {
      type: Array,
      required: true,
      default: () => [],
    },
    // 查询条件Code
    queryParamCode: {
      type: String,
      default: null,
    },
    // 查询条件文字
    queryParamText: {
      type: String,
      default: null,
    },
    rowKey: {
      type: String,
      default: "id",
    },
    // 过长裁剪长度,设置为 -1 代表不裁剪
    ellipsisLength: {
      type: Number,
      default: 12,
    },
  },
  data() {
    return {
      innerValue: [],
      // 已选择列表
      selectedTable: {
        pagination: false,
        scroll: { y: 240 },
        columns: [
          {
            ...this.columns[0],
            width: this.columns[0].widthRight || this.columns[0].width,
          },
          {
            ...this.columns[1],
            width: this.columns[1].widthRight || this.columns[1].width,
          },
          {
            title: "操作",
            dataIndex: "action",
            align: "center",
            width: 60,
            scopedSlots: { customRender: "action" },
          },
        ],
        dataSource: [],
      },
      renderEllipsis: (value) => (
        <ellipsis length={this.ellipsisLength}>{value}</ellipsis>
      ),
      url: { list: this.listUrl },
      /* 分页参数 */
      ipagination: {
        current: 1,
        pageSize: 5,
        pageSizeOptions: ["5", "10", "20", "30"],
        showTotal: (total, range) => {
          return range[0] + "-" + range[1] + " 共" + total + "条";
        },
        showQuickJumper: true,
        showSizeChanger: true,
        total: 0,
      },
      options: [],
      dataSourceMap: {},
    };
  },
  computed: {
    // 表头
    innerColumns() {
      let columns = cloneObject(this.columns);
      columns.forEach((column) => {
        // 给所有的列加上过长裁剪
        if (this.ellipsisLength !== -1) {
          column.customRender = (text) => this.renderEllipsis(text);
        }
      });
      return columns;
    },
  },
  watch: {
    value: {
      deep: true,
      immediate: true,
      handler(val) {
        console.log(val);
        this.innerValue = cloneObject(val);
        this.selectedRowKeys = [];
        this.valueWatchHandler(val);
        this.queryOptionsByValue(val);
      },
    },
    dataSource: {
      deep: true,
      handler(val) {
        // 重置之后key恢复
        this.emitOptions(val);
        this.valueWatchHandler(this.innerValue);
      },
    },
    selectedRowKeys: {
      immediate: true,
      deep: true,
      handler(val) {
        this.selectedTable.dataSource = val.map((key) => {
          for (let data of this.dataSource) {
            if (data[this.rowKey] === key) {
              pushIfNotExist(this.innerValue, data[this.valueKey]);
              return data;
            }
          }
          for (let data of this.selectedTable.dataSource) {
            if (data[this.rowKey] === key) {
              pushIfNotExist(this.innerValue, data[this.valueKey]);
              return data;
            }
          }
          console.warn("未找到选择的行信息,key:" + key);
          return {};
        });
      },
    },
  },

  methods: {
    /** 关闭弹窗 */
    close() {
      this.$emit("update:visible", false);
    },

    valueWatchHandler(val) {
      console.log(val);
      val.forEach((item) => {
        this.dataSource
          .concat(this.selectedTable.dataSource)
          .forEach((data) => {
            if (data[this.valueKey] === item) {
              pushIfNotExist(this.selectedRowKeys, data[this.rowKey]);
            }
          });
      });
    },

    queryOptionsByValue(value) {
      console.log(value);
      if (!value || value.length === 0) {
        return;
      }
      // 判断options是否存在value,如果已存在数据就不再请求后台了
      let notExist = false;
      for (let val of value) {
        let find = false;
        for (let option of this.options) {
          if (val === option.value) {
            find = true;
            break;
          }
        }
        if (!find) {
          notExist = true;
          break;
        }
      }
      if (!notExist) return;
      // listDepartUser( {
      //   // 这里最后加一个 , 的原因是因为无论如何都要使用 in 查询,防止后台进行了模糊匹配,导致查询结果不准确
      //   // [this.valueKey]: value.join(',') + ',',
      //   pageNo: 1,
      //   pageSize: value.length
      // }).then((res) => {
      //   if (res.success) {
      //     let dataSource = res.result
      //     if (!(dataSource instanceof Array)) {
      //       dataSource = res.result.records
      //     }
      //     this.emitOptions(dataSource, (data) => {
      //       pushIfNotExist(this.innerValue, data[this.valueKey])
      //       pushIfNotExist(this.selectedRowKeys, data[this.rowKey])
      //       pushIfNotExist(this.selectedTable.dataSource, data, this.rowKey)
      //     })
      //   }
      // })
    },

    emitOptions(dataSource, callback) {
      dataSource.forEach((data) => {
        let key = data[this.valueKey];
        this.dataSourceMap[key] = data;
        pushIfNotExist(
          this.options,
          { label: data[this.displayKey || this.valueKey], value: key },
          "value"
        );
        typeof callback === "function" ? callback(data) : "";
      });
      this.$emit("options", this.options, this.dataSourceMap);
    },

    /** 完成选择 */
    handleOk() {
      let value = this.selectedTable.dataSource.map(
        (data) => data[this.valueKey]
      );
      this.$emit("input", value);
      this.$emit("commitData", this.selectedTable.dataSource);
      this.close();
    },

    /** 删除已选择的 */
    handleDeleteSelected(record, index) {
      this.selectionRows.splice(
        this.selectedRowKeys.indexOf(record[this.rowKey]),
        1
      );
      this.selectedRowKeys.splice(
        this.selectedRowKeys.indexOf(record[this.rowKey]),
        1
      );
      this.selectedTable.dataSource.splice(index, 1);
      console.log(this.selectedRowKeys, this.selectionRows);
    },

    customRowFn(record) {
      return {
        on: {
          click: () => {
            let key = record[this.rowKey];
            if (!this.multiple) {
              this.selectedRowKeys = [key];
              this.selectedTable.dataSource = [record];
            } else {
              let index = this.selectedRowKeys.indexOf(key);
              if (index === -1) {
                this.selectedRowKeys.push(key);
                this.selectedTable.dataSource.push(record);
              } else {
                this.handleDeleteSelected(record, index);
              }
            }
          },
        },
      };
    },
  },
};
</script>
<style lang="less" scoped>
</style>

JeecgListMixin的方法

/**
 * 新增修改完成调用 modalFormOk方法 编辑弹框组件ref定义为modalForm
 * 高级查询按钮调用 superQuery方法  高级查询组件ref定义为superQueryModal
 * data中url定义 list为查询列表  delete为删除单条记录  deleteBatch为批量删除
 */
import { filterObj } from "@/utils/util";
import { deleteAction, getAction, downFile, getFileAccessHttpUrl } from "@/api/manage";

export const JeecgListMixin = {
  data() {
    return {
      /* 查询条件-请不要在queryParam中声明非字符串值的属性 */
      queryParam: {},
      /* 数据源 */
      dataSource: [],
      /* 分页参数 */
      ipagination: {
        current: 1,
        pageSize: 10,
        pageSizeOptions: ["10", "20", "30"],
        showTotal: (total, range) => {
          return range[0] + "-" + range[1] + " 共" + total + "条";
        },
        showQuickJumper: true,
        showSizeChanger: true,
        total: 0,
      },
      /* 排序参数 */
      isorter: {
        column: "createTime",
        order: "desc",
      },
      /* 筛选参数 */
      filters: {},
      /* table加载状态 */
      loading: false,
      /* table选中keys*/
      selectedRowKeys: [],
      /* table选中records*/
      selectionRows: [],
      /* 查询折叠 */
      toggleSearchStatus: false,
      /* 高级查询条件生效状态 */
      superQueryFlag: false,
      /* 高级查询条件 */
      superQueryParams: "",
      /** 高级查询拼接方式 */
      superQueryMatchType: "and",
    };
  },
  created() {
    if (!this.disableMixinCreated) {
      console.log(" -- mixin created -- ");
      this.loadData();
      //初始化字典配置 在自己页面定义
      this.initDictConfig();
    }
  },
  computed: {},
  methods: {
    loadData(arg) {
      if (!this.url.list) {
        this.$message.error("请设置url.list属性!");
        return;
      }
      //加载数据 若传入参数1则加载第一页的内容
      if (arg === 1) {
        this.ipagination.current = 1;
      }
      var params = this.getQueryParams(); //查询条件
      this.loading = true;
      getAction(this.url.list, params)
        .then((res) => {
          if (res.ok) {
            //update-begin---author:zhangyafei    Date:20201118  for:适配不分页的数据列表------------
            this.dataSource = res.data.records || res.data;
            if (res.data.total) {
              this.ipagination.total = res.data.total;
            } else {
              this.ipagination.total = 0;
            }
            //update-end---author:zhangyafei    Date:20201118  for:适配不分页的数据列表------------
          } else {
            this.$message.warning(res.msg);
          }
        })
        .finally(() => {
          this.loading = false;
        });
    },
    initDictConfig() {
      console.log("--这是一个假的方法!");
    },
    handleSuperQuery(params, matchType) {
      //高级查询方法
      if (!params) {
        this.superQueryParams = "";
        this.superQueryFlag = false;
      } else {
        this.superQueryFlag = true;
        this.superQueryParams = JSON.stringify(params);
        this.superQueryMatchType = matchType;
      }
      this.loadData(1);
    },
    getQueryParams() {
      //获取查询条件
      let sqp = {};
      if (this.superQueryParams) {
        sqp["superQueryParams"] = encodeURI(this.superQueryParams);
        sqp["superQueryMatchType"] = this.superQueryMatchType;
      }
      var param = Object.assign(sqp, this.queryParam, this.isorter, this.filters);
      // param.field = this.getQueryField();
      param.current = this.ipagination.current;
      param.size = this.ipagination.pageSize;
      return filterObj(param);
    },
    getQueryField() {
      //TODO 字段权限控制
      var str = "id,";
      this.columns.forEach(function (value) {
        str += "," + value.dataIndex;
      });
      return str;
    },
    onSelectChange(selectedRowKeys, selectionRows) {
      this.selectedRowKeys = selectedRowKeys;
      this.selectionRows = selectionRows;
      console.log(selectedRowKeys, selectionRows);
    },
    onClearSelected() {
      this.selectedRowKeys = [];
      this.selectionRows = [];
    },
    searchQuery() {
      this.loadData(1);
    },
    superQuery() {
      this.$refs.superQueryModal.show();
    },
    searchReset() {
      this.queryParam = {};
      this.loadData(1);
    },
    batchDel: function () {
      if (!this.url.deleteBatch) {
        this.$message.error("请设置url.deleteBatch属性!");
        return;
      }
      if (this.selectedRowKeys.length <= 0) {
        this.$message.warning("请选择一条记录!");
        return;
      } else {
        var ids = "";
        for (var a = 0; a < this.selectedRowKeys.length; a++) {
          ids += this.selectedRowKeys[a] + ",";
        }
        var that = this;
        this.$confirm({
          title: "确认删除",
          content: "是否删除选中数据?",
          onOk: function () {
            that.loading = true;
            deleteAction(that.url.deleteBatch, { ids: ids })
              .then((res) => {
                if (res.success) {
                  //重新计算分页问题
                  that.reCalculatePage(that.selectedRowKeys.length);
                  that.$message.success(res.message);
                  that.loadData();
                  that.onClearSelected();
                } else {
                  that.$message.warning(res.message);
                }
              })
              .finally(() => {
                that.loading = false;
              });
          },
        });
      }
    },
    handleDelete: function (id) {
      if (!this.url.delete) {
        this.$message.error("请设置url.delete属性!");
        return;
      }
      var that = this;
      deleteAction(`${that.url.delete}/${id}`, { id: id }).then((res) => {
        if (res.ok) {
          //重新计算分页问题
          that.reCalculatePage(1);
          that.$message.success("操作成功");
          that.loadData();
        } else {
          that.$message.warning(res.msg);
        }
      });
    },
    reCalculatePage(count) {
      //总数量-count
      let total = this.ipagination.total - count;
      //获取删除后的分页数
      let currentIndex = Math.ceil(total / this.ipagination.pageSize);
      //删除后的分页数<所在当前页
      if (currentIndex < this.ipagination.current) {
        this.ipagination.current = currentIndex;
      }
      console.log("currentIndex", currentIndex);
    },
    handleEdit: function (record) {
      this.$refs.modalForm.edit(record);
      this.$refs.modalForm.title = "编辑";
      this.$refs.modalForm.disableSubmit = false;
    },
    handleAdd: function () {
      this.$refs.modalForm.add();
      this.$refs.modalForm.title = "新增";
      this.$refs.modalForm.disableSubmit = false;
    },
    handleTableChange(pagination, filters, sorter) {
      //分页、排序、筛选变化时触发
      //TODO 筛选
      console.log(pagination);
      if (Object.keys(sorter).length > 0) {
        // this.isorter.column = sorter.field;
        this.isorter.order = "ascend" == sorter.order ? "asc" : "desc";
      }
      this.ipagination = pagination;
      this.loadData();
    },
    handleToggleSearch() {
      this.toggleSearchStatus = !this.toggleSearchStatus;
    },
    // 给popup查询使用(查询区域不支持回填多个字段,限制只返回一个字段)
    getPopupField(fields) {
      return fields.split(",")[0];
    },
    modalFormOk() {
      // 新增/修改 成功时,重载列表
      this.loadData();
      //清空列表选中
      this.onClearSelected();
    },
    handleDetail: function (record) {
      this.$refs.modalForm.edit(record);
      this.$refs.modalForm.title = "详情";
      this.$refs.modalForm.disableSubmit = true;
    },
    /* 导出 */
    handleExportXls2() {
      let paramsStr = encodeURI(JSON.stringify(this.getQueryParams()));
      let url = `${window._CONFIG["domianURL"]}/${this.url.exportXlsUrl}?paramsStr=${paramsStr}`;
      window.location.href = url;
    },
    handleExportXls(fileName) {
      if (!fileName || typeof fileName != "string") {
        fileName = "导出文件";
      }
      let param = this.getQueryParams();
      if (this.selectedRowKeys && this.selectedRowKeys.length > 0) {
        param["selections"] = this.selectedRowKeys.join(",");
      }
      console.log("导出参数", param);
      downFile(this.url.exportXlsUrl, param).then((data) => {
        if (!data) {
          this.$message.warning("文件下载失败");
          return;
        }
        if (typeof window.navigator.msSaveBlob !== "undefined") {
          window.navigator.msSaveBlob(new Blob([data], { type: "application/vnd.ms-excel" }), fileName + ".xls");
        } else {
          console.log(data);
          let url = window.URL.createObjectURL(new Blob([data.data], { type: "application/vnd.ms-excel" }));
          let link = document.createElement("a");
          link.style.display = "none";
          link.href = url;
          link.setAttribute("download", fileName + ".xls");
          document.body.appendChild(link);
          link.click();
          document.body.removeChild(link); //下载完成移除元素
          window.URL.revokeObjectURL(url); //释放掉blob对象
        }
      });
    },
    /* 图片预览 */
    getImgView(text) {
      if (text && text.indexOf(",") > 0) {
        text = text.substring(0, text.indexOf(","));
      }
      return getFileAccessHttpUrl(text);
    },
    /* 文件下载 */
    // update--autor:lvdandan-----date:20200630------for:修改下载文件方法名uploadFile改为downloadFile------
    downloadFile(text) {
      if (!text) {
        this.$message.warning("未知的文件");
        return;
      }
      if (text.indexOf(",") > 0) {
        text = text.substring(0, text.indexOf(","));
      }
      let url = getFileAccessHttpUrl(text);
      window.open(url);
    },
  },
};

 

Ellipsis的方法

import Ellipsis from './Ellipsis'

export default Ellipsis

Ellipsis.vue

<script>
  import { cutStrByFullLength, getStrFullLength } from '@/components/_util/StringUtil'

  export default {
    name: 'Ellipsis',
    props: {
      prefixCls: {
        type: String,
        default: 'ant-pro-ellipsis'
      },
      tooltip: {
        type: Boolean,
        default: true,
      },
      length: {
        type: Number,
        default: 25,
      },
      lines: {
        type: Number,
        default: 1
      },
      fullWidthRecognition: {
        type: Boolean,
        default: false
      }
    },
    methods: {},
    render() {
      const { tooltip, length } = this.$props
      let text = ''
      // 处理没有default插槽时的特殊情况
      if (this.$slots.default) {
        text = this.$slots.default.map(vNode => vNode.text).join('')
      }
      // 判断是否显示 tooltip
      if (tooltip && getStrFullLength(text) > length) {
        return (
          <a-tooltip>
            <template slot="title">{text}</template>
            <span>{cutStrByFullLength(text, this.length) + '…'}</span>
          </a-tooltip>
        )
      } else {
        return (<span>{text}</span>)
      }
    }
  }
</script>

4.关于封装好的复选表格

  <j-select-contract
                  :trigger-change="true"
                  v-decorator="['purchaseContractIds']"
                  customReturnField="purchaseContractIds"
                  @accountData="changeContract"
                  :multiple="true"
                  :status="2"
                ></j-select-contract>
import JSelectContract from "@/components/jeecgbiz/JSelectContract";

<template>
  <!-- 定义在这里的参数都是不可在外部覆盖的,防止出现问题 -->
  <j-select-biz-component
    :value="value"
    :ellipsisLength="25"
    :listUrl="url.list"
    :columns="columns"
    :multiple="multiple"
    v-on="$listeners"
    v-bind="attrs"
    @commitData="commitData"
  />
</template>

<script>
import JSelectBizComponent from "./JSelectBizComponent";

export default {
  name: "JSelectContract",
  components: { JSelectBizComponent },
  props: ["value", "multiple"],
  data() {
    return {
      url: { list: "/asset/purchasecontract/page?contractStatus=2&isAllTake=0" },
      columns: [
        { title: "合同单据号", align: "center", width: "25%", widthRight: "70%", dataIndex: "purchaseContractNo" },
        { title: "订购时间", align: "center", width: "25%", dataIndex: "orderDate" },
        { title: "采购员", align: "center", width: "20%", dataIndex: "purchasePersonName" },
        { title: "采购部门", align: "center", width: "20%", dataIndex: "organName" },
      ],
      // 定义在这里的参数都是可以在外部传递覆盖的,可以更灵活的定制化使用的组件
      default: {
        name: "采购合同",
        width: 1200,
        displayKey: "purchaseContractNo",
        returnKeys: ["id", "purchaseContractNo", "organName", "organId"],
        queryParamText: "合同单据号",
        queryParamCode: "purchaseContractNo",
      },
    };
  },
  computed: {
    attrs() {
      return Object.assign(this.default, this.$attrs);
    },
  },
  methods: {
    // 提交数据
    commitData(e) {
      this.$emit("accountData", e);
    },
  },
};
</script>

<style lang="less" scoped></style>

 index外层

<template>
  <a-row class="j-select-biz-component-box" type="flex" :gutter="8">
    <a-col class="left" :class="{'full': !buttons}">
      <slot name="left">
        <a-select
          mode="multiple"
          :placeholder="placeholder"
          v-model="selectValue"
          :options="selectOptions"
          allowClear
          :disabled="disabled"
          :open="selectOpen"
          style="width: 100%;"
          @dropdownVisibleChange="handleDropdownVisibleChange"
          @click.native="visible=(buttons?visible:true)"
        />
      </slot>
    </a-col>

    <a-col v-if="buttons" class="right">
      <a-button type="primary" icon="search" :disabled="disabled" @click="visible=true">{{selectButtonText}}</a-button>
    </a-col>

    <j-select-biz-component-modal
      v-model="selectValue"
      :visible.sync="visible"
      v-bind="modalProps"
      :multiple="multiple"
      @options="handleOptions"
      @commitData="commitData"
    />
  </a-row>
</template>

<script>
  import JSelectBizComponentModal from './JSelectBizComponentModal'

  export default {
    name: 'JSelectBizComponent',
    components: { JSelectBizComponentModal },
    props: {
      value: {
        type: String,
        default: ''
      },
      /** 是否返回 id,默认 false,返回 code */
      returnId: {
        type: Boolean,
        default: false
      },
      placeholder: {
        type: String,
        default: '请选择'
      },
      disabled: {
        type: Boolean,
        default: false
      },
      // 是否支持多选,默认 true
      multiple: {
        type: Boolean,
        default: true
      },
      // 是否显示按钮,默认 true
      buttons: {
        type: Boolean,
        default: true
      },
      // 显示的 Key
      displayKey: {
        type: String,
        default: null
      },
      // 返回的 key
      returnKeys: {
        type: Array,
        default: () => ['id', 'id']
      },
      // 选择按钮文字
      selectButtonText: {
        type: String,
        default: '选择'
      },

    },
    data() {
      return {
        selectValue: [],
        selectOptions: [],
        dataSourceMap: {},
        visible: false,
        selectOpen: false,
      }
    },
    computed: {
      valueKey() {
        return this.returnId ? this.returnKeys[0] : this.returnKeys[1]
      },
      modalProps() {
        return Object.assign({
          valueKey: this.valueKey,
          multiple: this.multiple,
          returnKeys: this.returnKeys,
          displayKey: this.displayKey || this.valueKey
        }, this.$attrs)
      },
    },
    watch: {
      value: {
        immediate: true,
        handler(val) {
          console.log('cake撒',val)
          if (val) {
            this.selectValue = val.split(',')
          } else {
            this.selectValue = []
          }
        }
      },
      selectValue: {
        deep: true,
        handler(val) {
          console.log(this.materialUseTime)
          let rows = val.map(key => this.dataSourceMap[key])
          this.$emit('select', rows)
          let data = val.join(',')
          this.$emit('input', data)
          this.$emit('change', data)
        }
      }
    },
    methods: {
      commitData(e) {
        this.$emit('commitData',e)
      },
      handleOptions(options, dataSourceMap) {
        this.selectOptions = options
        this.dataSourceMap = dataSourceMap
      },
      handleDropdownVisibleChange() {
        // 解决antdv自己的bug —— open 设置为 false 了,点击后还是添加了 open 样式,导致点击事件失效
        this.selectOpen = true
        this.$nextTick(() => {
          this.selectOpen = false
        })
      },
    }
  }
</script>

<style lang="less" scoped>
  .j-select-biz-component-box {

    @width: 82px;

    .left {
      width: calc(100% - @width - 8px);
    }

    .right {
      width: @width;
    }

    .full {
      width: 100%;
    }

    /deep/ .ant-select-search__field {
      display: none !important;
    }
  }
</style>

 内层

<template>
  <a-modal
    centered
    :title="name + '选择'"
    :width="width"
    :visible="visible"
    @ok="handleOk"
    @cancel="close"
    cancelText="关闭"
  >
    <a-row :gutter="18">
      <a-col :span="16">
        <!-- 查询区域 -->
        <div class="table-page-search-wrapper">
          <a-form :labelCol="{ span: 5 }" :wrapperCol="{ span: 18, offset: 1 }">
            <a-row :gutter="24">
              <a-col :span="14">
                <a-form-item :label="queryParamText || name">
                  <a-input
                    v-model="queryParam[queryParamCode || valueKey]"
                    :placeholder="'请输入' + (queryParamText || name)"
                    @pressEnter="searchQuery"
                  />
                </a-form-item>
              </a-col>
              <a-col :span="8">
                <span
                  style="float: left; overflow: hidden"
                  class="table-page-search-submitButtons"
                >
                  <a-button type="primary" @click="searchQuery" icon="search"
                    >查询</a-button
                  >
                  <a-button
                    type="primary"
                    @click="searchReset"
                    icon="reload"
                    style="margin-left: 8px"
                    >重置</a-button
                  >
                </span>
              </a-col>
            </a-row>
          </a-form>
        </div>

        <a-table
          size="small"
          bordered
          :rowKey="rowKey"
          :columns="innerColumns"
          :dataSource="dataSource"
          :pagination="ipagination"
          :loading="loading"
          :scroll="{ y: 240 }"
          :rowSelection="{
            selectedRowKeys,
            onChange: onSelectChange,
            type: multiple ? 'checkbox' : 'radio',
          }"
          :customRow="customRowFn"
          @change="handleTableChange"
        >
        </a-table>
      </a-col>
      <a-col :span="8">
        <a-card
          :title="'已选' + name"
          :bordered="false"
          :head-style="{ padding: 0 }"
          :body-style="{ padding: 0 }"
        >
          <a-table
            size="small"
            :rowKey="rowKey"
            bordered
            v-bind="selectedTable"
          >
            <span slot="action" slot-scope="text, record, index">
              <a @click="handleDeleteSelected(record, index)">删除</a>
            </span>
          </a-table>
        </a-card>
      </a-col>
    </a-row>
  </a-modal>
</template>

<script>
// import { getAction } from '@/api/manage'
import Ellipsis from "@/components/Ellipsis";
import { JeecgListMixin } from "@/mixins/JeecgListMixin";
import { cloneObject, pushIfNotExist } from "@/utils/util";
import { listDepartUser } from "@/api/apis";

export default {
  name: "JSelectBizComponentModal",
  mixins: [JeecgListMixin],
  components: { Ellipsis },
  props: {
    value: {
      type: Array,
      default: () => [],
    },
    visible: {
      type: Boolean,
      default: false,
    },
    valueKey: {
      type: String,
      required: true,
    },
    multiple: {
      type: Boolean,
      default: true,
    },
    width: {
      type: Number,
      default: 900,
    },

    name: {
      type: String,
      default: "",
    },
    listUrl: {
      type: String,
      required: true,
      default: "",
    },
    // 根据 value 获取显示文本的地址,例如存的是 username,可以通过该地址获取到 realname
    valueUrl: {
      type: String,
      default: "",
    },
    displayKey: {
      type: String,
      default: null,
    },
    columns: {
      type: Array,
      required: true,
      default: () => [],
    },
    // 查询条件Code
    queryParamCode: {
      type: String,
      default: null,
    },
    // 查询条件文字
    queryParamText: {
      type: String,
      default: null,
    },
    rowKey: {
      type: String,
      default: "id",
    },
    // 过长裁剪长度,设置为 -1 代表不裁剪
    ellipsisLength: {
      type: Number,
      default: 12,
    },
  },
  data() {
    return {
      innerValue: [],
      // 已选择列表
      selectedTable: {
        pagination: false,
        scroll: { y: 240 },
        columns: [
          {
            ...this.columns[0],
            width: this.columns[0].widthRight || this.columns[0].width,
          },
          {
            title: "操作",
            dataIndex: "action",
            align: "center",
            width: 60,
            scopedSlots: { customRender: "action" },
          },
        ],
        dataSource: [],
      },
      renderEllipsis: (value) => (
        <ellipsis length={this.ellipsisLength}>{value}</ellipsis>
      ),
      url: { list: this.listUrl },
      /* 分页参数 */
      ipagination: {
        current: 1,
        pageSize: 5,
        pageSizeOptions: ["5", "10", "20", "30"],
        showTotal: (total, range) => {
          return range[0] + "-" + range[1] + " 共" + total + "条";
        },
        showQuickJumper: true,
        showSizeChanger: true,
        total: 0,
      },
      options: [],
      dataSourceMap: {},
    };
  },
  computed: {
    // 表头
    innerColumns() {
      let columns = cloneObject(this.columns);
      columns.forEach((column) => {
        // 给所有的列加上过长裁剪
        if (this.ellipsisLength !== -1) {
          column.customRender = (text) => this.renderEllipsis(text);
        }
      });
      return columns;
    },
  },
  watch: {
    value: {
      deep: true,
      immediate: true,
      handler(val) {
        console.log(val);
        this.innerValue = cloneObject(val);
        this.selectedRowKeys = [];
        this.valueWatchHandler(val);
        this.queryOptionsByValue(val);
      },
    },
    dataSource: {
      deep: true,
      handler(val) {
        // 重置之后key恢复
        this.emitOptions(val);
        this.valueWatchHandler(this.innerValue);
      },
    },
    selectedRowKeys: {
      immediate: true,
      deep: true,
      handler(val) {
        this.selectedTable.dataSource = val.map((key) => {
          for (let data of this.dataSource) {
            if (data[this.rowKey] === key) {
              pushIfNotExist(this.innerValue, data[this.valueKey]);
              return data;
            }
          }
          for (let data of this.selectedTable.dataSource) {
            if (data[this.rowKey] === key) {
              pushIfNotExist(this.innerValue, data[this.valueKey]);
              return data;
            }
          }
          console.warn("未找到选择的行信息,key:" + key);
          return {};
        });
      },
    },
  },

  methods: {
    /** 关闭弹窗 */
    close() {
      this.$emit("update:visible", false);
    },

    valueWatchHandler(val) {
      console.log(val);
      val.forEach((item) => {
        this.dataSource
          .concat(this.selectedTable.dataSource)
          .forEach((data) => {
            if (data[this.valueKey] === item) {
              pushIfNotExist(this.selectedRowKeys, data[this.rowKey]);
            }
          });
      });
    },

    queryOptionsByValue(value) {
      console.log(value);
      if (!value || value.length === 0) {
        return;
      }
      // 判断options是否存在value,如果已存在数据就不再请求后台了
      let notExist = false;
      for (let val of value) {
        let find = false;
        for (let option of this.options) {
          if (val === option.value) {
            find = true;
            break;
          }
        }
        if (!find) {
          notExist = true;
          break;
        }
      }
      if (!notExist) return;
      // listDepartUser( {
      //   // 这里最后加一个 , 的原因是因为无论如何都要使用 in 查询,防止后台进行了模糊匹配,导致查询结果不准确
      //   // [this.valueKey]: value.join(',') + ',',
      //   pageNo: 1,
      //   pageSize: value.length
      // }).then((res) => {
      //   if (res.success) {
      //     let dataSource = res.result
      //     if (!(dataSource instanceof Array)) {
      //       dataSource = res.result.records
      //     }
      //     this.emitOptions(dataSource, (data) => {
      //       pushIfNotExist(this.innerValue, data[this.valueKey])
      //       pushIfNotExist(this.selectedRowKeys, data[this.rowKey])
      //       pushIfNotExist(this.selectedTable.dataSource, data, this.rowKey)
      //     })
      //   }
      // })
    },

    emitOptions(dataSource, callback) {
      dataSource.forEach((data) => {
        let key = data[this.valueKey];
        this.dataSourceMap[key] = data;
        pushIfNotExist(
          this.options,
          { label: data[this.displayKey || this.valueKey], value: key },
          "value"
        );
        typeof callback === "function" ? callback(data) : "";
      });
      this.$emit("options", this.options, this.dataSourceMap);
    },

    /** 完成选择 */
    handleOk() {
      let value = this.selectedTable.dataSource.map(
        (data) => data[this.valueKey]
      );
      this.$emit("input", value);
      console.log(this.selectedTable.dataSource);
      this.$emit("commitData", this.selectedTable.dataSource);
      this.close();
    },

    /** 删除已选择的 */
    handleDeleteSelected(record, index) {
      this.selectionRows.splice(
        this.selectedRowKeys.indexOf(record[this.rowKey]),
        1
      );
      this.selectedRowKeys.splice(
        this.selectedRowKeys.indexOf(record[this.rowKey]),
        1
      );
      this.selectedTable.dataSource.splice(index, 1);
      console.log(this.selectedRowKeys, this.selectionRows);
    },

    customRowFn(record) {
      return {
        on: {
          click: () => {
            let key = record[this.rowKey];
            if (!this.multiple) {
              this.selectedRowKeys = [key];
              this.selectedTable.dataSource = [record];
            } else {
              let index = this.selectedRowKeys.indexOf(key);
              if (index === -1) {
                this.selectedRowKeys.push(key);
                this.selectedTable.dataSource.push(record);
              } else {
                this.handleDeleteSelected(record, index);
              }
            }
          },
        },
      };
    },
  },
};
</script>
<style lang="less" scoped>
</style>

这边的方法通单选框是一样的

5.关于没有封装的单选框表格同时要实现点击行增加单选框选中效果

<a-table
            style="width: 100%; margin-top: 50px"
            :rowKey="(record) => record.id"
            :dataSource="tableData"
            :columns="columns"
            :row-selection="{
              type: 'radio',
              onChange: onSelectChange,
              selectedRowKeys: selectedRowKeys,
            }"
            :customRow="customRowFn"
            @change="handleTableChange"
            :pagination="ipagination"
            :loading="tableLoading"
            bordered
          >
          </a-table>
data(){
return{
      tableSelectRow: {},
      selectedRowKeys: [],
   /* 分页参数 */
      ipagination: {
        current: 1,
        pageSize: 10,
        total: 0,
      },
}
}




method:{
//控制单选框
    onSelectChange(val, row) {
      console.log("val", val, "row", row);
      this.tableSelectRow = row[0];
      this.selectedRowKeys = val;
    },
//控制行customRowFn属性
 customRowFn(record) {
      return {
        on: {
          click: () => {
            // console.log("record", record);
            this.tableSelectRow = record;
            this.selectedRowKeys = [record.id];
            // console.log("this.tableSelectRow", this.tableSelectRow);
            // console.log("this.selectedRowKeys", this.selectedRowKeys);
          },
        },
      };
    },
    handleTableChange(pagination) {
      //分页、排序、筛选变化时触发
      this.ipagination = pagination;
      this.getlistassetstandardmodel();
    },
}


  // 资产型号确定
    chosmodelok() {
      console.log(this.assetsData);
      console.log(this.tableSelectRow);
      this.form.setFieldsValue({
        assetName: this.tableSelectRow.standardName,
        categoryId: this.tableSelectRow.categoryId,
        assetModel: this.tableSelectRow.standardModel,
        assetMetering: this.tableSelectRow.standardMetering,
      });
      (this.assetsData.categoryName = this.tableSelectRow.categoryName),
        (this.chosmodel = false);
    },

6.关于没有封装的单选框表格同时要实现点击行增加多选框选中效果

 <a-table
        :columns="columns"
        :data-source="dataSource"
        size="small"
        rowKey="id"
        :loading="loading"
        :pagination="ipagination"
        bordered
        :rowSelection="{
          selectedRowKeys: selectedRowKeys,
          onChange: onChangeTableSelect,
        }"
        :customRow="customRowFn"
        @change="handleTableChange"
      >
   selectedRowKeys: [],
    
   selectionRows: [],
 methods: {
    customRowFn(record) {
      return {
        on: {
          click: () => {
            // console.log("record", record);
            // this.tableSelectRow = record;
            // this.selectedRowKeys = [record.id];
            // console.log("this.tableSelectRow", this.tableSelectRow);
            // console.log("this.selectedRowKeys", this.selectedRowKeys);

            let key = record.id;
            let index = this.selectedRowKeys.indexOf(key);
            // console.log("index", index);
            if (index === -1) {
              this.selectedRowKeys.push(key);
              this.selectionRows.push(record);
            } else {
              this.selectionRows.splice(
                this.selectionRows.indexOf(record.id),
                1
              );
              this.selectedRowKeys.splice(
                this.selectedRowKeys.indexOf(record.id),
                1
              );
            }
            console.log("this.selectionRows", this.selectionRows);
          },
        },
      };
    },

    onChangeTableSelect(selectedRowKeys, selectionRows) {
      this.selectedRowKeys = selectedRowKeys;
      let mRow = JSON.parse(JSON.stringify(this.selectionRows));
      selectionRows.forEach((item) => {
        pushIfNotExist(mRow, item, "id");
      });
      this.selectionRows = this.selectedRowKeys.map((item) => {
        let mObj = {};
        mRow.forEach((items) => {
          if (items.id == item) {
            mObj = items;
          }
        });
        console.log(mObj);
        return mObj;
      });
      console.log(this.selectionRows);
    },
    clickShowModal(rows) {
      let mRows = JSON.parse(JSON.stringify(rows));
      this.onClearSelected();
      this.selectedRowKeys = mRows.map((item) => item.id);
      this.selectionRows = mRows;
      this.visible = true;
      this.loadData(1);
    },
    handleOk() {
      this.visible = false;
      this.$emit(
        "select",
        JSON.parse(JSON.stringify(this.selectedRowKeys)),
        JSON.parse(JSON.stringify(this.selectionRows))
      );
    },
  },
};

 这边表格分页效果是来自JeecgListMixin这个组件或者看5那边有单独写出来分页

/**
 * 新增修改完成调用 modalFormOk方法 编辑弹框组件ref定义为modalForm
 * 高级查询按钮调用 superQuery方法  高级查询组件ref定义为superQueryModal
 * data中url定义 list为查询列表  delete为删除单条记录  deleteBatch为批量删除
 */
import { filterObj } from "@/utils/util";
import { deleteAction, getAction, downFile, getFileAccessHttpUrl } from "@/api/manage";

export const JeecgListMixin = {
  data() {
    return {
      /* 查询条件-请不要在queryParam中声明非字符串值的属性 */
      queryParam: {},
      /* 数据源 */
      dataSource: [],
      /* 分页参数 */
      ipagination: {
        current: 1,
        pageSize: 10,
        pageSizeOptions: ["10", "20", "30"],
        showTotal: (total, range) => {
          return range[0] + "-" + range[1] + " 共" + total + "条";
        },
        showQuickJumper: true,
        showSizeChanger: true,
        total: 0,
      },
      /* 排序参数 */
      isorter: {
        column: "createTime",
        order: "desc",
      },
      /* 筛选参数 */
      filters: {},
      /* table加载状态 */
      loading: false,
      /* table选中keys*/
      selectedRowKeys: [],
      /* table选中records*/
      selectionRows: [],
      /* 查询折叠 */
      toggleSearchStatus: false,
      /* 高级查询条件生效状态 */
      superQueryFlag: false,
      /* 高级查询条件 */
      superQueryParams: "",
      /** 高级查询拼接方式 */
      superQueryMatchType: "and",
    };
  },
  created() {
    if (!this.disableMixinCreated) {
      console.log(" -- mixin created -- ");
      this.loadData();
      //初始化字典配置 在自己页面定义
      this.initDictConfig();
    }
  },
  computed: {},
  methods: {
    loadData(arg) {
      if (!this.url.list) {
        this.$message.error("请设置url.list属性!");
        return;
      }
      //加载数据 若传入参数1则加载第一页的内容
      if (arg === 1) {
        this.ipagination.current = 1;
      }
      var params = this.getQueryParams(); //查询条件
      this.loading = true;
      getAction(this.url.list, params)
        .then((res) => {
          if (res.ok) {
            //update-begin---author:zhangyafei    Date:20201118  for:适配不分页的数据列表------------
            this.dataSource = res.data.records || res.data;
            if (res.data.total) {
              this.ipagination.total = res.data.total;
            } else {
              this.ipagination.total = 0;
            }
            //update-end---author:zhangyafei    Date:20201118  for:适配不分页的数据列表------------
          } else {
            this.$message.warning(res.msg);
          }
        })
        .finally(() => {
          this.loading = false;
        });
    },
    initDictConfig() {
      console.log("--这是一个假的方法!");
    },
    handleSuperQuery(params, matchType) {
      //高级查询方法
      if (!params) {
        this.superQueryParams = "";
        this.superQueryFlag = false;
      } else {
        this.superQueryFlag = true;
        this.superQueryParams = JSON.stringify(params);
        this.superQueryMatchType = matchType;
      }
      this.loadData(1);
    },
    getQueryParams() {
      //获取查询条件
      let sqp = {};
      if (this.superQueryParams) {
        sqp["superQueryParams"] = encodeURI(this.superQueryParams);
        sqp["superQueryMatchType"] = this.superQueryMatchType;
      }
      var param = Object.assign(sqp, this.queryParam, this.isorter, this.filters);
      // param.field = this.getQueryField();
      param.current = this.ipagination.current;
      param.size = this.ipagination.pageSize;
      return filterObj(param);
    },
    getQueryField() {
      //TODO 字段权限控制
      var str = "id,";
      this.columns.forEach(function (value) {
        str += "," + value.dataIndex;
      });
      return str;
    },
    onSelectChange(selectedRowKeys, selectionRows) {
      this.selectedRowKeys = selectedRowKeys;
      this.selectionRows = selectionRows;
      console.log(selectedRowKeys, selectionRows);
    },
    onClearSelected() {
      this.selectedRowKeys = [];
      this.selectionRows = [];
    },
    searchQuery() {
      this.loadData(1);
    },
    superQuery() {
      this.$refs.superQueryModal.show();
    },
    searchReset() {
      this.queryParam = {};
      this.loadData(1);
    },
    batchDel: function () {
      if (!this.url.deleteBatch) {
        this.$message.error("请设置url.deleteBatch属性!");
        return;
      }
      if (this.selectedRowKeys.length <= 0) {
        this.$message.warning("请选择一条记录!");
        return;
      } else {
        var ids = "";
        for (var a = 0; a < this.selectedRowKeys.length; a++) {
          ids += this.selectedRowKeys[a] + ",";
        }
        var that = this;
        this.$confirm({
          title: "确认删除",
          content: "是否删除选中数据?",
          onOk: function () {
            that.loading = true;
            deleteAction(that.url.deleteBatch, { ids: ids })
              .then((res) => {
                if (res.success) {
                  //重新计算分页问题
                  that.reCalculatePage(that.selectedRowKeys.length);
                  that.$message.success(res.message);
                  that.loadData();
                  that.onClearSelected();
                } else {
                  that.$message.warning(res.message);
                }
              })
              .finally(() => {
                that.loading = false;
              });
          },
        });
      }
    },
    handleDelete: function (id) {
      if (!this.url.delete) {
        this.$message.error("请设置url.delete属性!");
        return;
      }
      var that = this;
      deleteAction(`${that.url.delete}/${id}`, { id: id }).then((res) => {
        if (res.ok) {
          //重新计算分页问题
          that.reCalculatePage(1);
          that.$message.success("操作成功");
          that.loadData();
        } else {
          that.$message.warning(res.msg);
        }
      });
    },
    reCalculatePage(count) {
      //总数量-count
      let total = this.ipagination.total - count;
      //获取删除后的分页数
      let currentIndex = Math.ceil(total / this.ipagination.pageSize);
      //删除后的分页数<所在当前页
      if (currentIndex < this.ipagination.current) {
        this.ipagination.current = currentIndex;
      }
      console.log("currentIndex", currentIndex);
    },
    handleEdit: function (record) {
      this.$refs.modalForm.edit(record);
      this.$refs.modalForm.title = "编辑";
      this.$refs.modalForm.disableSubmit = false;
    },
    handleAdd: function () {
      this.$refs.modalForm.add();
      this.$refs.modalForm.title = "新增";
      this.$refs.modalForm.disableSubmit = false;
    },
    handleTableChange(pagination, filters, sorter) {
      //分页、排序、筛选变化时触发
      //TODO 筛选
      console.log(pagination);
      if (Object.keys(sorter).length > 0) {
        // this.isorter.column = sorter.field;
        this.isorter.order = "ascend" == sorter.order ? "asc" : "desc";
      }
      this.ipagination = pagination;
      this.loadData();
    },
    handleToggleSearch() {
      this.toggleSearchStatus = !this.toggleSearchStatus;
    },
    // 给popup查询使用(查询区域不支持回填多个字段,限制只返回一个字段)
    getPopupField(fields) {
      return fields.split(",")[0];
    },
    modalFormOk() {
      // 新增/修改 成功时,重载列表
      this.loadData();
      //清空列表选中
      this.onClearSelected();
    },
    handleDetail: function (record) {
      this.$refs.modalForm.edit(record);
      this.$refs.modalForm.title = "详情";
      this.$refs.modalForm.disableSubmit = true;
    },
    /* 导出 */
    handleExportXls2() {
      let paramsStr = encodeURI(JSON.stringify(this.getQueryParams()));
      let url = `${window._CONFIG["domianURL"]}/${this.url.exportXlsUrl}?paramsStr=${paramsStr}`;
      window.location.href = url;
    },
    handleExportXls(fileName) {
      if (!fileName || typeof fileName != "string") {
        fileName = "导出文件";
      }
      let param = this.getQueryParams();
      if (this.selectedRowKeys && this.selectedRowKeys.length > 0) {
        param["selections"] = this.selectedRowKeys.join(",");
      }
      console.log("导出参数", param);
      downFile(this.url.exportXlsUrl, param).then((data) => {
        if (!data) {
          this.$message.warning("文件下载失败");
          return;
        }
        if (typeof window.navigator.msSaveBlob !== "undefined") {
          window.navigator.msSaveBlob(new Blob([data], { type: "application/vnd.ms-excel" }), fileName + ".xls");
        } else {
          console.log(data);
          let url = window.URL.createObjectURL(new Blob([data.data], { type: "application/vnd.ms-excel" }));
          let link = document.createElement("a");
          link.style.display = "none";
          link.href = url;
          link.setAttribute("download", fileName + ".xls");
          document.body.appendChild(link);
          link.click();
          document.body.removeChild(link); //下载完成移除元素
          window.URL.revokeObjectURL(url); //释放掉blob对象
        }
      });
    },
    /* 图片预览 */
    getImgView(text) {
      if (text && text.indexOf(",") > 0) {
        text = text.substring(0, text.indexOf(","));
      }
      return getFileAccessHttpUrl(text);
    },
    /* 文件下载 */
    // update--autor:lvdandan-----date:20200630------for:修改下载文件方法名uploadFile改为downloadFile------
    downloadFile(text) {
      if (!text) {
        this.$message.warning("未知的文件");
        return;
      }
      if (text.indexOf(",") > 0) {
        text = text.substring(0, text.indexOf(","));
      }
      let url = getFileAccessHttpUrl(text);
      window.open(url);
    },
  },
};

7.打印和导出写法

// 打印资产标签列表
const printAssetList = (fileName, params) => downloadFile("/asset/warehousing/printAssetList", fileName, params, "pdf"); // 打印资产标签列表
//导出资产列表
const warehousingExport = (fileName, params) => downloadFile("/asset/assetsinfo/export", fileName, params, "get"); // 导出资产列表
  // 打印资产
    clickAssetsPrint() {
      this.assetsPrintLoading = true;
      var mm = {};
      mm.id = this.selectedRows.map((item) => {
        return item.materialCode;
      });
      printAssetList("资产标签", mm)
        .then((res) => {
          this.assetsPrintLoading = false;
        })
        .catch((err) => {
          this.assetsPrintLoading = false;
        });

      // this.$refs.barCode.transferData(this.selectedRows)
    },
    // 导出资产
    getWarehousingExport() {
      var mm = {};
      mm.id = this.selectedRows.map((item) => {
        return item.materialCode;
      });
      warehousingExport("资产列表", mm).then((res) => {
        // let execlName = "资产文件名称";
        // const buf = Buffer.from(res),
        //   blob = new Blob([buf], { type: "application/vnd.ms-excel" }),
        //   downloadElement = document.createElement('a'),
        //   href = window.URL.createObjectURL(blob); // 创建下载的链接
        // downloadElement.href = href;
        // downloadElement.download = `${execlName}.xls`; // 下载后文件名
        // document.body.appendChild(downloadElement);
        // downloadElement.click(); // 点击下载
        // window.URL.revokeObjectURL(href); // 释放掉blob对象
      });
    },

8.显示已删除的供应商


              <a-checkbox
                style="margin-left: 20px"
                @change="onChange"
                :value="yesOfno"
              >
                显示已删除的供应商
              </a-checkbox>
    onChange(e) {
      this.yesOfno = e.target.checked;
      this.$refs.table.refresh(this.queryParam);
    },
    <s-table
      ref="table"
      size="default"
      :columns="columns"
      :data="loadData"
      @onSelect="onChangeTableSelect"
    >
      <span slot="action" slot-scope="text, record">
        <a @click="handleEdit(record)">编辑</a>
        <a-divider type="vertical" />
        <a-popconfirm title="你确定要删除吗?" @confirm="deleteTable(record)">
          <a>删除</a>
        </a-popconfirm>
      </span>
    </s-table>
    refresh() {
      var mm = {
        current: 1,
        total: 0,
        size: this.pageSize,
      }
      this.loadData(mm);
    },

 同时也有关于loadData传参查询

   // 加载数据方法 必须为 Promise 对象
      loadData: (parameter) => {
        this.queryParam.delFlag = this.yesOfno ? 1 : "";
        return listSupplierinfo(Object.assign(parameter, this.queryParam)).then(
          (res) => {
            console.log(res);
            var mm = { data: [] };
            mm.size = res.data.size;
            mm.current = res.data.current;
            mm.totalCount = res.data.total;
            mm.totalPage = res.data.pages;
            mm.data = res.data.records;
            return mm;
          }
        );
      },

9.关于loadData传参查询

  loadData: (parameter) => {
        return allotapplyPage(Object.assign(parameter, this.queryParam)).then(
          (res) => {
            var mm = { data: [] };
            mm.size = res.data.size;
            mm.current = res.data.current;
            mm.totalCount = res.data.total;
            mm.totalPage = res.data.pages;
            mm.data = res.data.records;
            return mm;
          }
        );
      },

10.关于mixins传参功能

@mixin fontStyle($size,$weight,$color){
    font-size: $size;
    font-weight: $weight;
    color:$color;
    font-family: Source Han Sans CN-Regular, Source Han Sans CN;
}

使用

 .num {
              @include fontStyle(24px, bold, #1fc6ff);
            }

11.关于批量操作的样式

 <a-dropdown v-if="arrayId.length > 0">
        <a-menu slot="overlay">
          <a-menu-item key="1" @click="deleteModel">
            <a-icon type="delete" />删除
          </a-menu-item>
          <!-- lock | unlock -->
          <!-- <a-menu-item key="2"><a-icon type="lock" />锁定</a-menu-item> -->
        </a-menu>
        <a-button style="margin-left: 8px">
          批量操作
          <a-icon type="down" />
        </a-button>
      </a-dropdown>

12.树形查找

如果当前的层级id没有找到就会执行执行他的子对象中寻找匹配的id。

该函数首先尝试在当前层级的项目中通过item.id == id寻找匹配的id。如果当前层级没有匹配项,并且当前项目包含子项(即item.children存在),它会递归地调用自身this.findLabelById(id, item.children)去子对象中寻找匹配的id。这一过程会持续到找到匹配的id并返回其对应的标签,或者遍历完所有可能的子对象仍未找到匹配项时,最终返回null。

  findLabelById(id, deption) {
      for (const item of deption) {
        if (item.id == id) {
          return item.label;
        }
        if (item.children) {
          const label = this.findLabelById(id, item.children);
          if (label) {
            return label;
          }
        }
      }
      return null; // 如果没有找到匹配的id,返回null
    },

问题能否将这段代码改成else

  if (item.children) {

          const label = this.findLabelById(id, item.children);

          if (label) {

            return label;

          }

        }

不能如果改成else违背的最开始的逻辑 这是在没有顶级层的情况下去检查他的子项。

13.table里面带有输入框怎么写

 <div v-if="houseType == '1'">
                  <a-table
                    bordered
                    ref="tableSelect"
                    size="default"
                    rowKey="id"
                    :columns="columns"
                    :data-source="dataSource"
                  >
                    <div slot="assetRentAreas" slot-scope="text, record, index">
                      <a-input-number
                        v-model="dataSource[index].assetRentAreas"
                        :min="0"
                        @change="changedataSource"
                      />
                    </div>
                    <div slot="singlePrice" slot-scope="text, record, index">
                      <a-input-number
                        v-model="dataSource[index].singlePrice"
                        :min="0"
                        @change="changedataSource"
                      />
                    </div>
                    <span slot="action" slot-scope="text, record, index">
                      <a @click="deleteRecord(record, index)" style="color: red"
                        >删除</a
                      >
                    </span></a-table
                  >
                </div>
methods: {
    // 计算 资产租金
    changedataSource() {
      if (this.houseType == 1) {
        this.dataSource = this.dataSource.map((item) => {
          return {
            ...item,
            monthRentMoney:
              item.assetRentAreas > 0 && item.singlePrice > 0
                ? (item.assetRentAreas * item.singlePrice).toFixed(2)
                : 0,
            yearRentMoney:
              item.assetRentAreas > 0 && item.singlePrice > 0
                ? (item.assetRentAreas * item.singlePrice * 12).toFixed(2)
                : 0,
          };
        });
      } else {
        this.dataSource = this.dataSource.map((item) => {
          return {
            ...item,
            monthRentMoney:
              item.number > 0 && item.singlePrice > 0
                ? (item.number * item.singlePrice).toFixed(2)
                : 0,
            yearRentMoney:
              item.number > 0 && item.singlePrice > 0
                ? (item.number * item.singlePrice * 12).toFixed(2)
                : 0,
          };
        });
      }
    },

14.关于当有校验情况撑开布局,布局跳动情况

今天碰到了一种布局跳动的情况 我就放了一个row n个col 但是有校验的情况撑开了布局 有3种解决方式

第一种方法:假设一行2个 那么有5行 就放5个row,之前就一个row margin导致可以往下挤压。

第二种:找到对应的标签去掉margin

第三种:清除缓存。因为我电脑有问题,但是我同事电脑没问题。有可能是缓存的问题 

 15.碰到纯数字或者字母的时候比较长的时候会直接下一行

css中添加

word-break: break-all;

16.碰到mixins.scss传值写法

@mixin fontStyle($size,$weight,$color){
    font-size: $size;
    font-weight: $weight;
    color:$color;
    font-family: Source Han Sans CN-Regular, Source Han Sans CN;
}

传值

 @include fontStyle(12px, 400, rgba(255, 255, 255, 0.7));

17. v-decorator使用和校验

使用v-decorator就不能使用v-model了,而且她用于a-form-item

 <a-form
          :form="editForm"
          :labelCol="{ span: 6 }"
          :wrapperCol="{ span: 16 }"
        >
          <a-row>
            <a-col :span="12">
              <a-form-item label="小区名称:">
                <a-input
                  placeholder="请输入"
                  v-decorator="[
                    'name',
                    { rules: validatorRules.inputIf.rules },
                  ]"
                />
              </a-form-item>
 </a-col>

  </a-row>
        </a-form>

 表单验证规则

  validatorRules: {
        // 表单验证
        inputIf: { rules: [{ required: true, message: "此项不能为空" }] },
        timeIf: { rules: [{ required: true, message: "请选择时间" }] },
      },

同时  这说明了这个form一点要创建

  editForm: this.$form.createForm(this),

 表单验证validateFields

    handleOk() {
      this.editForm.validateFields((err, values) => {
        if (!err) {
          this.summit(values);
        }
      });
    },
    summit(values) {
      this.xqLoading = true;
      values.longitude = this.formData.longitude;
      values.latitude = this.formData.latitude;
      values.linkLand = this.formData.linkLand;
      values.landName = this.formData.landName;
      if (this.isAdd) {
        Adddistrict(Object.assign(values))
          .then((res) => {
            this.xqLoading = false;
            if (res.code == 0) {
              this.$message.success("添加成功");
              this.$emit("refresh");
              this.visible = false;
            } else {
              this.$message.error(res.data.msg);
            }
          })
          .catch((err) => {
            this.xqLoading = false;
          });
      } else {
        values.id = this.key;
        Updatedistrict(Object.assign(values))
          .then((res) => {
            this.xqLoading = false;
            if (res.code == 0) {
              this.$message.success("修改成功");
              this.$emit("refresh");
              this.visible = false;
            } else {
              this.$message.error(res.data.msg);
            }
          })
          .catch((err) => {
            this.xqLoading = false;
          });
      }
    },

表单清空

this.editForm.resetFields();

动态设置输入框的值写法setFieldsValue 

  this.editForm.setFieldsValue({ ["location"]: e.address });

该函数用于在Vue实例中,设置editForm对象中location属性的值为e.address。其中,setFieldsValue是Ant Design Vue库中Form组件的方法,用于设置表单域的值。通过使用索引语法["location"],可以动态地设置属性名。

18.v-html遇上富文本的时候就可以不用管html标签了

19.关于文件打开

 <a-descriptions-item label="附件">
                <div
                  v-for="(item, index) of fileList"
                  :key="index"
                  class="filename"
                  @click="perView(item)"
                >
                  {{ item.name }}
                </div>
              </a-descriptions-item>
  perView(item) {
      window.open(item.url, "_blank");
    },

20.文件上传组件

<template>
  <div class="upload-file">
    <a-upload
      v-if="!isUpload"
      name="file"
      :multiple="true"
      :action="uploadFileUrl"
      :headers="headers"
      @change="handleChange"
      :fileList="fileList"
    >
      <!-- 上传按钮 -->
      <a-button> <a-icon type="upload" />上传</a-button>
    </a-upload>
    <div
      class="upload-file-list el-upload-list el-upload-list--text"
      name="el-fade-in-linear"
      v-else
    >
      <div
        :key="file.url"
        class="el-upload-list__item ele-upload-list__item-content"
        style="padding: 0 4px"
        v-for="(file, index) in fileList"
      >
        <a :href="`${file.url}`" :underline="false" target="_blank">
          <span class="el-icon-document"> {{ getFileName(file.name) }} </span>
        </a>
      </div>
    </div>
  </div>
</template>

<script>
import Cookie from "js-cookie";

export default {
  name: "FileUpload",
  props: {
    // 值
    value: [String, Object, Array],

    // 大小限制(MB)
    fileSize: {
      type: Number,
      default: 5,
    },
    // 文件类型, 例如['png', 'jpg', 'jpeg']
    fileType: {
      type: Array | Boolean,
      // default: () => ["doc", "xls", "ppt", "txt", "pdf"],
      default: () => ["doc", "docx", "xls", "xlsx", "ppt", ".pptx", "pdf"],
    },
    // 是否显示文件列表
    isFileList: {
      type: Boolean,
      default: true,
    },
    dataIndex: {
      type: Number | String,
      default: 0,
    },
    // 是否禁用
    isUpload: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      number: 0,
      uploadList: [],
      baseUrl: process.env.VUE_APP_BASE_API,
      uploadFileUrl: `${process.env.VUE_APP_API_FATHER_URL}/upms/file/upload?fileType=image&dir=material/`, // 上传文件服务器地址
      headers: {
        // 请求头部
        Authorization: Cookie.get("Authorization"),
      },
      fileList: [],
    };
  },
  watch: {
    value: {
      async handler(val) {
        if (val) {
          console.log(111111);
          let temp = 1;
          // 首先将值转为数组
          let list = Array.isArray(val)
            ? val
            : val.split(",").map((item) => {
                const [url, name] = item.split(":");
                return { url, name };
              });
          // 然后将数组转为对象数组
          this.fileList = list.map((item) => {
            item = {
              name: item.name,
              url: item.url,
              status: "done",
            };
            item.uid = new Date().getTime() + temp++;
            return item;
          });
        } else {
          this.fileList = [];
          return [];
        }
      },
      deep: true,
      immediate: true,
    },
  },

  methods: {
    getFilenameFromUrl(url) {
      var match = url.match(/^.*\/(.*)$/);
      return match ? match[1] : null;
    },
    // 上传前校检格式和大小
    handleBeforeUpload(file) {
      // 校检文件类型
      if (this.fileType) {
        const fileName = file.name.split(".");
        const fileExt = fileName[fileName.length - 1];
        const isTypeOk = this.fileType.indexOf(fileExt) >= 0;
        if (!isTypeOk) {
          this.$message.info(
            `文件格式不正确, 请上传${this.fileType.join("/")}格式文件!`
          );
          return false;
        }
      }
      // 校检文件大小
      if (this.fileSize) {
        const isLt = file.size / 1024 / 1024 < this.fileSize;
        if (!isLt) {
          this.$message.info(`上传文件大小不能超过 ${this.fileSize} MB!`);
          return false;
        }
      }
      this.number++;
      return true;
    },

    // 上传失败
    handleUploadError(err) {
      this.$message.info("上传文件失败,请重试");
    },
    // 上传成功回调
    handleChange(info) {
      if (info.file.status !== "uploading") {
        console.log(info.file, info.fileList);
      }
      let fileList = [...info.fileList];
      fileList = fileList.map((file) => {
        if (file.response) {
          file.name = file.name;
          file.url = file.response.link;
        }
        return file;
      });
      this.fileList = fileList;
      if (info.file.status === "removed") {
        console.log("this.fileList1111", this.fileList);
        this.$emit("getFile", this.fileList);
        this.$emit("input", this.fileList);
        this.$emit("change", this.fileList);
      }
      if (info.file.status === "done") {
        // console.log(info.file);
        // this.$emit("getFile", this.listToString(this.fileList));
        this.$emit("getFile", this.fileList);
        this.$emit("input", this.fileList);
        this.$emit("change", this.fileList);
      }
      if (info.file.status === "error") {
        this.$message.error(`${info.file.name} file upload failed.`);
      }
    },

    // 获取文件名称
    getFileName(name) {
      // console.log("name", name);
      // 如果是url那么取最后的名字 如果不是直接返回
      if (name.lastIndexOf("/") > -1) {
        return name.slice(name.lastIndexOf("/") + 1);
      } else {
        return name;
      }
    },
    // 对象转成指定字符串分隔
    listToString(list, separator) {
      let strs = "";
      separator = separator || ",";
      for (let i in list) {
        strs += list[i].url + separator;
      }
      return strs != "" ? strs.substr(0, strs.length - 1) : "";
    },
  },
};
</script>

<style scoped lang="scss">
.upload-file-uploader {
  margin-bottom: 5px;
}
.upload-file-list .el-upload-list__item {
  line-height: 2;
  margin-bottom: 10px;
  position: relative;
}
.upload-file-list .ele-upload-list__item-content {
  display: flex;
  justify-content: space-between;
  align-items: center;
  color: inherit;
}
.ele-upload-list__item-content-action .el-link {
  margin-right: 10px;
}
</style>

使用

<template>
  <a-modal
    :title="title"
    width="30%"
    :visible="visible"
    @cancel="visible = false"
    @ok="handleOk"
    :loading="loading"
    :footer="disabled ? null : undefined"
  >
    <a-form-model
      ref="ruleForm"
      :model="form"
      :rules="rules"
      :label-col="labelCol"
      :wrapper-col="wrapperCol"
    >
      <a-form-model-item label="文档名称" prop="docName">
        <a-input v-model="form.docName" :disabled="disabled" />
      </a-form-model-item>
      <a-form-model-item label="附件">
        <FileUpload
          v-model="form.fileIDS"
          :fileType="false"
          @getFile="getFile"
          :disabled="disabled"
          :isUpload="isUpload"
        ></FileUpload>
      </a-form-model-item>
    </a-form-model>
  </a-modal>
</template>

<script>
import FileUpload from "@/components/FileUpload/index2";
import { maphelpcenterPost, maphelpcenterPut } from "@/api/myapi";
import { JeecgListMixin } from "@/mixins/JeecgListMixin";
export default {
  components: { FileUpload, JeecgListMixin },
  data() {
    return {
      loading: false,
      visible: false,
      title: "",

      spinning: false,

      form: {},
      rules: {
        docName: [{ required: true, message: "请输入", trigger: "blur" }],
      },
      labelCol: {
        span: 5,
      },
      wrapperCol: {
        span: 16,
      },
      record: {},
      disabled: false,
      isUpload: false,
      footer: "",
    };
  },
  methods: {
    clickShowModal(isadd, data, disabled) {
      console.log("data", data);
      this.visible = true;
      this.disabled = disabled;
      this.isUpload = false;
      if (isadd) {
        this.title = "添加文档";
        this.form = {};
        this.footer = "111";
      } else {
        if (disabled) {
          this.title = "查看文档";
          this.isUpload = true;
        } else {
          this.title = "编辑文档";
        }
        this.form = { ...data };
        this.form.fileIDS = this.mergeFiles(data.fileUrls, data.fileNames);
        console.log("this.form.fileIDS", this.form.fileIDS);
      }
    },
    maphelpcenterPost() {
      this.loading = true;
      console.log("this.form", this.form);
      maphelpcenterPost(this.form).then((res) => {
        this.loading = false;
        console.log("res", res);
        if (res.code == 0) {
          this.$message.success("添加成功");
          this.visible = false;
          this.$emit("searchQuery");
        }
      });
    },
    maphelpcenterPut() {
      this.loading = true;
      maphelpcenterPut(this.form).then((res) => {
        this.loading = false;
        if (res.code == 0) {
          this.$message.success("修改成功");
          this.visible = false;
          this.$emit("searchQuery");
        }
      });
    },
    handleOk() {
      this.$refs.ruleForm.validate((valid) => {
        if (valid) {
          if (!this.form.id) {
            this.maphelpcenterPost();
          } else {
            this.maphelpcenterPut();
          }
        } else {
          console.log("error submit!!");
          return false;
        }
      });
    },
    getFile(data) {
      console.log("我收到了值", data);
      this.form.fileUrls = data.map((item) => item.url).join(",");
      this.form.fileNames = data.map((item) => item.name).join(",");
      this.form.fileIDS = data.map((item) => item.uid).join(",");

      // console.log("this.form.fileUrls", this.form.fileUrls);
      // console.log("this.form.fileNames", this.form.fileNames);
    },
    mergeFiles(url, names) {
      const urlArray = url.split(",");
      const nameArray = names.split(",");
      // console.log("urlArray", urlArray);
      // console.log("nameArray", nameArray);
      const a = urlArray.map((item, index) => ({
        url: item,
        name: nameArray[index],
      }));
      return a;
    },
  },
};
</script>

21.这里使用了一个计算属性或插值表达式{{ [...] [item.type] }}来映射item.type的数值到具体的描述文本。

<tbody>
                    <tr v-for="(item, index) in todoList" :key="index">
                      <div @click="toAudit(item)" style="margin-bottom: 12px">
                        <td class="title">
                          <a-tag color="#23689a">
                            {{
                              [
                                "",
                                "固定性资产管理",
                                "经营性资产登记",
                                "经营性资产变更",
                              ][item.type]
                            }}
                          </a-tag>
                        </td>
                        <td class="content">
                          <span>{{ item.title }} </span>
                        </td>
                      </div>
                    </tr>
                  </tbody>

22.需求是 

 可以考虑实际收款不等于应收时候触发强制重新校验remark字段,可以考虑自定义校验

 <a-row :gutter="48">
        <a-col :span="6">
          <a-form-model-item label="实收款:">
            <a-input
              v-model="form.realReceiveMoney"
              :disabled="disabled"
              @change="handleRealReceiveMoneyChange"
            />
          </a-form-model-item>
        </a-col>
        <a-col :span="6">
          <a-form-model-item label="实收日期">
            <a-date-picker
              valueFormat="YYYY-MM-DD"
              style="width: 100%"
              v-model="form.realReceiveDate"
              :disabled="disabled"
            />
          </a-form-model-item>
        </a-col>
        <a-col :span="6">
          <a-form-model-item label="备注" prop="remark">
            <a-input v-model="form.remark" :disabled="disabled" />
          </a-form-model-item>
        </a-col>
        <a-col :span="6">
          <a-button
            type="primary"
            @click="assetbillpaylogtAdd"
            v-if="!disabled"
          >
            确认已缴费
          </a-button>

 实际收款不等于应收时候触发强制重新校验remark字段

   handleRealReceiveMoneyChange() {
      this.$refs.ruleForm.validateField("remark");
    },
  validateRemark(rule, value, callback) {
      if (this.form.realReceiveMoney != this.shouldPayMoney && !value) {
        callback(new Error("请输入备注"));
      } else {
        callback();
      }
    },
   //新增缴费
    assetbillpaylogtAdd() {
      this.confirmLoading = true;
      const meta = {
        ...this.form,
        billIds: this.form.id,
        contractId: this.form.rentContractId,
      };
      console.log("meta", meta);
      this.$refs.ruleForm.validate((valid) => {
        if (valid) {
          assetbillpaylogtAdd(meta).then((res) => {
            this.confirmLoading = false;
            if (res.code == 0) {
              this.$message.success("缴费成功");
              this.visible = false;
              this.$emit("getBillDetail");
            }
          });
        } else {
          console.log("校验不通过");
        }
      });
    },

23.单选的表格  

  <a-table
      ref="table"
      rowKey="id"
      :columns="columns"
      :dataSource="dataSource"
      :rowSelection="{
        selectedRowKeys: selectedRowKeys,
        onChange: onSelectChange,
        type: 'radio',
      }"
      :pagination="false"
      bordered
    >
      <span slot="action" slot-scope="text, record">
        <a v-if="record.payStatus == 1" @click="payment(record, false)">缴费</a>
        <a v-else @click="payment(record, true)">详情</a>
      </span>
    </a-table>
import { JeecgListMixin } from "@/mixins/JeecgListMixin";
    onSelectChange(selectedRowKeys, selectionRows) {
      // console.log("selectedRowKeys", selectedRowKeys);
      // console.log("selectionRows", selectionRows);
      this.selectedRowKeys = selectedRowKeys;
      this.selectionRows = selectionRows;
      // this.selectedRowKeys = row;
      this.billList(
        this.selectionRows[0].id,
        this.selectionRows[0].rentContractId
      );
    },

 

 

 JeecgListMixin的代码

/**
 * 新增修改完成调用 modalFormOk方法 编辑弹框组件ref定义为modalForm
 * 高级查询按钮调用 superQuery方法  高级查询组件ref定义为superQueryModal
 * data中url定义 list为查询列表  delete为删除单条记录  deleteBatch为批量删除
 */
import { filterObj } from "@/utils/util";
import { deleteAction, getAction, downFile, getFileAccessHttpUrl } from "@/api/manage";

export const JeecgListMixin = {
  data() {
    return {
      /* 查询条件-请不要在queryParam中声明非字符串值的属性 */
      queryParam: {},
      /* 数据源 */
      dataSource: [],
      /* 分页参数 */
      ipagination: {
        current: 1,
        pageSize: 10,
        pageSizeOptions: ["10", "20", "30"],
        showTotal: (total, range) => {
          return range[0] + "-" + range[1] + " 共" + total + "条";
        },
        showQuickJumper: true,
        showSizeChanger: true,
        total: 0,
      },
      /* 排序参数 */
      isorter: {
        column: "createTime",
        order: "desc",
      },
      /* 筛选参数 */
      filters: {},
      /* table加载状态 */
      loading: false,
      /* table选中keys*/
      selectedRowKeys: [],
      /* table选中records*/
      selectionRows: [],
      /* 查询折叠 */
      toggleSearchStatus: false,
      /* 高级查询条件生效状态 */
      superQueryFlag: false,
      /* 高级查询条件 */
      superQueryParams: "",
      /** 高级查询拼接方式 */
      superQueryMatchType: "and",
    };
  },
  created() {
    if (!this.disableMixinCreated) {
      console.log(" -- mixin created -- ");
      this.loadData();
      //初始化字典配置 在自己页面定义
      this.initDictConfig();
    }
  },
  computed: {},
  methods: {
    loadData(arg) {
      if (!this.url.list) {
        this.$message.error("请设置url.list属性!");
        return;
      }
      //加载数据 若传入参数1则加载第一页的内容
      if (arg === 1) {
        this.ipagination.current = 1;
      }
      var params = this.getQueryParams(); //查询条件
      this.loading = true;
      getAction(this.url.list, params)
        .then((res) => {
          if (res.ok) {
            console.log('res', res);
            //update-begin---author:zhangyafei    Date:20201118  for:适配不分页的数据列表------------
            this.dataSource = res.data.records || res.data.list || res.data;
            if (res.data.total) {
              this.ipagination.total = res.data.total;
            } else {
              this.ipagination.total = 0;
            }
            //update-end---author:zhangyafei    Date:20201118  for:适配不分页的数据列表------------
          } else {
            this.$message.warning(res.msg);
          }
        })
        .finally(() => {
          this.loading = false;
        });
    },
    initDictConfig() {
      console.log("--这是一个假的方法!");
    },
    handleSuperQuery(params, matchType) {
      //高级查询方法
      if (!params) {
        this.superQueryParams = "";
        this.superQueryFlag = false;
      } else {
        this.superQueryFlag = true;
        this.superQueryParams = JSON.stringify(params);
        this.superQueryMatchType = matchType;
      }
      this.loadData(1);
    },
    getQueryParams() {
      //获取查询条件
      let sqp = {};
      if (this.superQueryParams) {
        sqp["superQueryParams"] = encodeURI(this.superQueryParams);
        sqp["superQueryMatchType"] = this.superQueryMatchType;
      }
      var param = Object.assign(sqp, this.queryParam, this.isorter, this.filters);
      // param.field = this.getQueryField();
      param.current = this.ipagination.current;
      param.size = this.ipagination.pageSize;
      return filterObj(param);
    },
    getQueryField() {
      //TODO 字段权限控制
      var str = "id,";
      this.columns.forEach(function (value) {
        str += "," + value.dataIndex;
      });
      return str;
    },
    onSelectChange(selectedRowKeys, selectionRows) {
      this.selectedRowKeys = selectedRowKeys;
      this.selectionRows = selectionRows;
      console.log(selectedRowKeys, selectionRows);
    },
    onClearSelected() {
      this.selectedRowKeys = [];
      this.selectionRows = [];
    },
    searchQuery() {
      this.loadData(1);
    },
    superQuery() {
      this.$refs.superQueryModal.show();
    },
    searchReset() {
      this.queryParam = {};
      this.loadData(1);
    },
    batchDel: function () {
      if (!this.url.deleteBatch) {
        this.$message.error("请设置url.deleteBatch属性!");
        return;
      }
      if (this.selectedRowKeys.length <= 0) {
        this.$message.warning("请选择一条记录!");
        return;
      } else {
        var ids = "";
        for (var a = 0; a < this.selectedRowKeys.length; a++) {
          ids += this.selectedRowKeys[a] + ",";
        }
        var that = this;
        this.$confirm({
          title: "确认删除",
          content: "是否删除选中数据?",
          onOk: function () {
            that.loading = true;
            deleteAction(that.url.deleteBatch, { ids: ids })
              .then((res) => {
                if (res.success) {
                  //重新计算分页问题
                  that.reCalculatePage(that.selectedRowKeys.length);
                  that.$message.success(res.message);
                  that.loadData();
                  that.onClearSelected();
                } else {
                  that.$message.warning(res.message);
                }
              })
              .finally(() => {
                that.loading = false;
              });
          },
        });
      }
    },
    handleDelete: function (id) {
      if (!this.url.delete) {
        this.$message.error("请设置url.delete属性!");
        return;
      }
      var that = this;
      deleteAction(`${that.url.delete}/${id}`, { id: id }).then((res) => {
        if (res.ok) {
          //重新计算分页问题
          that.reCalculatePage(1);
          that.$message.success("操作成功");
          that.loadData();
        } else {
          that.$message.warning(res.msg);
        }
      });
    },
    reCalculatePage(count) {
      //总数量-count
      let total = this.ipagination.total - count;
      //获取删除后的分页数
      let currentIndex = Math.ceil(total / this.ipagination.pageSize);
      //删除后的分页数<所在当前页
      if (currentIndex < this.ipagination.current) {
        this.ipagination.current = currentIndex;
      }
      console.log("currentIndex", currentIndex);
    },
    handleEdit: function (record) {
      this.$refs.modalForm.edit(record);
      this.$refs.modalForm.title = "编辑";
      this.$refs.modalForm.disableSubmit = false;
    },
    handleAdd: function () {
      this.$refs.modalForm.add();
      this.$refs.modalForm.title = "新增";
      this.$refs.modalForm.disableSubmit = false;
    },
    handleTableChange(pagination, filters, sorter) {
      //分页、排序、筛选变化时触发
      //TODO 筛选
      console.log(pagination);
      if (Object.keys(sorter).length > 0) {
        // this.isorter.column = sorter.field;
        this.isorter.order = "ascend" == sorter.order ? "asc" : "desc";
      }
      this.ipagination = pagination;
      this.loadData();
    },
    handleToggleSearch() {
      this.toggleSearchStatus = !this.toggleSearchStatus;
    },
    // 给popup查询使用(查询区域不支持回填多个字段,限制只返回一个字段)
    getPopupField(fields) {
      return fields.split(",")[0];
    },
    modalFormOk() {
      // 新增/修改 成功时,重载列表
      this.loadData();
      //清空列表选中
      this.onClearSelected();
    },
    handleDetail: function (record) {
      this.$refs.modalForm.edit(record);
      this.$refs.modalForm.title = "详情";
      this.$refs.modalForm.disableSubmit = true;
    },
    /* 导出 */
    handleExportXls2() {
      let paramsStr = encodeURI(JSON.stringify(this.getQueryParams()));
      let url = `${window._CONFIG["domianURL"]}/${this.url.exportXlsUrl}?paramsStr=${paramsStr}`;
      window.location.href = url;
    },
    handleExportXls(fileName) {
      if (!fileName || typeof fileName != "string") {
        fileName = "导出文件";
      }
      let param = this.getQueryParams();
      if (this.selectedRowKeys && this.selectedRowKeys.length > 0) {
        param["selections"] = this.selectedRowKeys.join(",");
      }
      console.log("导出参数", param);
      downFile(this.url.exportXlsUrl, param).then((data) => {
        if (!data) {
          this.$message.warning("文件下载失败");
          return;
        }
        if (typeof window.navigator.msSaveBlob !== "undefined") {
          window.navigator.msSaveBlob(new Blob([data], { type: "application/vnd.ms-excel" }), fileName + ".xls");
        } else {
          console.log(data);
          let url = window.URL.createObjectURL(new Blob([data.data], { type: "application/vnd.ms-excel" }));
          let link = document.createElement("a");
          link.style.display = "none";
          link.href = url;
          link.setAttribute("download", fileName + ".xls");
          document.body.appendChild(link);
          link.click();
          document.body.removeChild(link); //下载完成移除元素
          window.URL.revokeObjectURL(url); //释放掉blob对象
        }
      });
    },
    /* 图片预览 */
    getImgView(text) {
      if (text && text.indexOf(",") > 0) {
        text = text.substring(0, text.indexOf(","));
      }
      return getFileAccessHttpUrl(text);
    },
    /* 文件下载 */
    // update--autor:lvdandan-----date:20200630------for:修改下载文件方法名uploadFile改为downloadFile------
    downloadFile(text) {
      if (!text) {
        this.$message.warning("未知的文件");
        return;
      }
      if (text.indexOf(",") > 0) {
        text = text.substring(0, text.indexOf(","));
      }
      let url = getFileAccessHttpUrl(text);
      window.open(url);
    },
    toggleAdvanced() {
      this.advanced = !this.advanced;
    },
  },
};

表格多选  这边handleTableChange是分页的 上边单选没有分页 如果需要就添加

 <a-table
        :columns="columns"
        :data-source="dataSource"
        size="small"
        rowKey="id"
        :loading="loading"
        :pagination="ipagination"
        bordered
        :rowSelection="{
          selectedRowKeys: selectedRowKeys,
          onChange: onChangeTableSelect,
        }"
        @change="handleTableChange"
      >
      </a-table>
import { JeecgListMixin } from "@/mixins/JeecgListMixin";
   onChangeTableSelect(selectedRowKeys, selectionRows) {
      this.selectedRowKeys = selectedRowKeys;
      let mRow = JSON.parse(JSON.stringify(this.selectionRows));
      selectionRows.forEach((item) => {
        pushIfNotExist(mRow, item, "id");
      });
      this.selectionRows = this.selectedRowKeys.map((item) => {
        let mObj = {};
        mRow.forEach((items) => {
          if (items.id == item) {
            mObj = items;
          }
        });
        return mObj;
      });
      console.log("11111", this.selectionRows);
    },

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
antd vue2 是一种基于 Vue2.x 的 UI 组件库,它有着良好的设计和开发体验,通过 antd vue2 搭建的前端项目可以很好地实现页面效果。 在使用 antd vue2 开发前端项目时,我们可能会遇到跨域的问题。跨域是因为浏览器同源策略的限制,不允许 JavaScript 脚本在一个源加载的文档或者脚本与另一种源加载的资源进行交互,这就导致我们在开发中需要请求其他域名下的数据时,会出现跨域问题。 为了解决跨域问题,需要设置服务端的 CORS(跨域资源共享,Cross-Origin Resource Sharing)。CORS 允许 Web 应用服务器进行跨域访问控制,从而使浏览器和服务器能够协作解决跨域问题,实现安全数据交互。 在使用 antd vue2 进行开发时,可以通过配置 Vue-CLI3.x 中的 proxyTable 属性和 devServer 中的 before 和 after 钩子函数来解决跨域问题。proxyTable 属性可以将前端请求发送到后端对应的 URL,before 和 after 钩子函数可以通过修改请求头信息来实现跨域访问。 此外,还可以使用 JSONP(JSON with Padding)方式来解决跨域问题。JSONP 是利用 script 标签没有跨域限制的漏洞来达到与其他域进行数据交互的方式。 总的来说,对于 antd vue2 的跨域问题,需要通过设置 CORS 或者使用 JSONP 等方式来解决。只有解决了跨域问题,我们才能在开发中顺利实现对其他域名下数据的请求和处理,提高开发效率和用户体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值