基於vue3和element-plus封裝的curd組件,支持el-table和el-tree


基於vue3和element-plus封裝的curd組件,支持el-table和el-tree,類似avue-curd

本文連接:https://www.cnblogs.com/muphy/p/15826954.html

寫這個的主要目的還是為了學習vue3,為了快速學習,我從gitee找到了一個非常優秀的基於VUE3和element-plus的前端admin框架,地址:https://gitee.com/asaasa/vue3-element-admin,並進行了部分優化

對於前端快速發展,vue3.x的出現讓很多基於vue開發的UI框架失去了兼容性,特別是avue-curd這樣優秀的組件無法使用,而最新的技術肯定相對於老技術有一定的優勢,我本想查找一些現有的基於vue3.x的curd組件來直接使用,找了半天也不盡人意,於是自己寫一個類似avue-curd的組件,基本上兼容curd組件使用的element-plus的組件的所有屬性,如果哪里有疑問查詢element-plus對應組件api就行,這里主要以azi模塊介紹使用方法,組件源碼在最后面。

支持el-table和el-tree,綁定參數: crudType="tree"、默認值:“table”

有幫助的話給個關注,有問題的畫幫忙指出問題

安裝

npm i ve-curd
import VeCurd from "ve-curd";
app.use(VeCurd);

源碼下載

先看效果

  

分別點擊查看,新增、編輯和刪除:

 表格默認支持過濾,排序和分頁

 el-table和el-pagination所有特性基本上都可以使用,紅色圈內是新增的,其他還有什么盡管綁定即可,另外沖突的disabled需要分開

表單組件根據表格列對象配置的type值區分組合了:el-input、el-cascader、el-checkbox、el-data-picker,這些組件的屬性都通過表格列對象配置,也支持字典

 

增刪改查表單的label和value都可以被自定義,對應加上功能名稱,如列對象prop配置為username:那么自定義包括username、usernameValue、usernameLabel、usernameForm、usernameView、usernameEdit、usernameAdd等

表單本身也支持自定義:editForm、viewForm、addForm等

還有一些就不列舉了,哪里有問題直接改組件源碼

 

測試頁面:examples/components/HelloWorld.vue

<!--
 * @Author: ruphy若非
 * @Date: 2022-01-20 11:03:21
 * @Description: curd
-->
<template>
    <div style="width: 100%; height: 800px">
        <el-row :gutter="20">
            <el-col :span="4">
                <ve-curd
                    curd-type="tree"
                    :data="treeData"
                    :columns="tableColumns"
                    :props="{
                        label: 'realName',
                        children: 'children',
                    }"
                    @delete-sure="handleDelete"
                    @edit-sure="handleEdit"
                    @add-sure="handleAdd"
                ></ve-curd>
            </el-col>
            <el-col :span="20">
                <!-- 列表 -->
                <ve-curd
                    :model="form"
                    show-message
                    :data="tableData"
                    :columns="tableColumns"
                    :total="page.total"
                    v-model:page-size="page.pageSize"
                    v-model:current-page="page.currentPage"
                    v-model:ascs="page.ascs"
                    v-model:descs="page.descs"
                    v-model:filters="page.filters"
                    @sort-change="handleChange"
                    @size-change="handleChange"
                    @current-change="handleChange"
                    @filter-change="searchChange"
                    @search-change="searchChange"
                    @delete-sure="handleDelete"
                    @edit-sure="handleEdit"
                    @add-sure="handleAdd"
                >
                </ve-curd>
            </el-col>
        </el-row>
    </div>
</template>
<script>
export default {
    name: "HelloWorld",
    data: () => ({
        description: "用戶信息查詢與設置",
        menus: {
            search: { name: "查詢" },
            add: { name: "添加" },
            edit: { name: "編輯" },
            del: { name: "刪除" },
        },
    }),
};
</script>

<script setup>

import * as azi from "../api/user";

import { getCurrentInstance, reactive, ref, unref, onMounted } from "vue";
const { proxy } = getCurrentInstance(); //獲取上下文實例,ctx=vue2的this

const form = reactive({
    name: "",
});
const page = reactive({
    total: 0, // 總頁數
    currentPage: 1, // 當前頁數
    pageSize: 10, // 每頁顯示多少條
    ascs: [], //升序字段
    descs: [], //降序字段
    filters: [], //降序字段
});
const tableData = ref([]);

const tableColumns = ref([
    {
        type: "selection",
    },
    {
        label: "ID",
        prop: "id",
        search: true,
        sortable: "custom",
        addable: true,
        editable: true,
        viewable: true,
        filters: [
            { text: "第一個", value: "1" },
            { text: "第二個", value: "2" },
            { text: "第三個", value: "3" },
            { text: "第四個", value: "4" },
        ],
        filterMethod: (value, row, column) => {
            const property = column["property"];
            return row[property] === value;
        },
        rules: [
            {
                required: true,
                message: "請輸入ID",
                trigger: "blur",
            },
            {
                max: 32,
                message: "長度在不能超過32個字符",
            },
        ],
    },
    {
        label: "用戶賬號",
        prop: "username",
        hide: true,
        search: true,
        sortable: true,
        addable: true,
        editable: true,
        viewable: true,
        type: "url",
        rules: [
            {
                max: 32,
                message: "長度在不能超過32個字符",
            },
        ],
    },
    {
        label: "用戶名稱",
        prop: "realName",
        sortable: true,
        search: true,
        addable: true,
        editable: true,
        viewable: true,
        maxlength: 55,
        type: "textarea",
        rules: [
            {
                max: 32,
                message: "長度在不能超過32個字符",
            },
        ],
    },
    {
        label: "用戶密碼",
        prop: "password",
        type: "password",
        hide: true,
        search: true,
        sortable: true,
        addable: true,
        editable: true,
        viewable: true,
        rules: [
            {
                max: 32,
                message: "長度在不能超過32個字符",
            },
        ],
        resetField: (e) => {
            alert("dd" + e);
        },
    },
    {
        label: "角色ID",
        prop: "roleIds",
        search: true,
        sortable: true,
        addable: true,
        editable: true,
        viewable: true,
        type: "number",
        rules: [
            {
                max: 32,
                message: "長度在不能超過32個字符",
            },
        ],
    },
    {
        label: "狀態:0-禁用,1-啟用",
        prop: "status",
        search: true,
        sortable: true,
        addable: true,
        editable: true,
        viewable: true,
        type: "select",
        dict: {
            options: [
                { text: "禁用", label: "禁用", value: "0" },
                { text: "啟用", label: "啟用", value: "1" },
            ],
        },
    },
]);

const handleDelete = (row) => {
    console.log("handleDelete", row);
    azi.delObj(row).then((res) => {
        if (res.success) {
            searchChange();
        } else {
            throw new Error(res.msg);
        }
    });
};

const handleEdit = (row) => {
    console.log("handleEdit", row);
    azi.putObj(row).then((res) => {
        if (res.success) {
            searchChange();
        } else {
            throw new Error(res.msg);
        }
    });
};

const handleAdd = (row) => {
    console.log("handleAdd", row);
    azi.addObj(row).then((res) => {
        if (res.success) {
            searchChange();
        } else {
            throw new Error(res.msg);
        }
    });
};

const searchChange = () => {
    let p = unref(page);
    p.total = 0;
    return handleChange();
};

const handleChange = () => {
    let p = unref(page);
    let params = Object.assign({}, p, form);
    console.log("handleChange", params);
    return azi.getPage(params).then((d) => {
        if (d.data.success) {
            p.total = d.data.data.total;
            tableData.value = d.data.data.records || [];
        }
    });
};

handleChange();

// tree
const treeData = ref([]);

const loadTreeData = () => {
    return azi.getList().then((d) => {
        if (d.data.success) {
            treeData.value = d.data.data || [];
        }
    });
};

loadTreeData();
onMounted(() => {
    console.log(proxy, proxy);
})
</script>

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

examples/api/user.js

export function getPage(query) {
    return Promise.resolve({ data: { success: true, data: { total: 58, records: [{"admin":true,"id":"1","lastTime":1642969720288,"password":"123456","realName":"超級管理員","roleIds":"1","status":"1","username":"admin"},{"admin":false,"id":"11","lastTime":1642969720288,"password":"440","realName":"jjj","roleIds":"2","status":"0","username":"qqq"},{"admin":false,"id":"13","lastTime":1642969720288,"password":"111111","realName":"寶寶","roleIds":"2","status":"0","username":"aaa"},{"admin":false,"id":"2","lastTime":1642969720288,"password":"123456","realName":"管理員","roleIds":"2","status":"1","username":"test"},{"admin":false,"id":"3","lastTime":1642969720288,"realName":"安安","roleIds":"","status":"0"},{"admin":false,"id":"4","lastTime":1642969720288,"realName":"靜靜","roleIds":"","status":"0","username":"靜靜"},{"admin":false,"id":"5","lastTime":1642969720288,"realName":"阿朱","roleIds":"","status":"0"},{"admin":false,"id":"6","lastTime":1642969720288,"realName":"武怡","roleIds":"","status":"0"},{"admin":false,"id":"7","lastTime":1642969720288,"password":"123","realName":"阿紫","roleIds":"2","status":"0","username":"azi"},{"admin":false,"id":"8","lastTime":1642969720288,"realName":"愛玲","roleIds":""}]}}});
    // return request({
    //     url: '/gw/user/page',
    //     method: 'get',
    //     params: query
    // })
}
export function getList(query) {
    return Promise.resolve({ data: { success: true, data: [{"admin":true,"id":"1","lastTime":1642969720288,"password":"123456","realName":"超級管理員","roleIds":"1","status":"1","username":"admin"},{"admin":false,"id":"11","lastTime":1642969720288,"password":"440","realName":"jjj","roleIds":"2","status":"0","username":"qqq"},{"admin":false,"id":"13","lastTime":1642969720288,"password":"111111","realName":"寶寶","roleIds":"2","status":"0","username":"aaa"},{"admin":false,"id":"2","lastTime":1642969720288,"password":"123456","realName":"管理員","roleIds":"2","status":"1","username":"test"},{"admin":false,"id":"3","lastTime":1642969720288,"realName":"安安","roleIds":"","status":"0"},{"admin":false,"id":"4","lastTime":1642969720288,"realName":"靜靜","roleIds":"","status":"0","username":"靜靜"},{"admin":false,"id":"5","lastTime":1642969720288,"realName":"阿朱","roleIds":"","status":"0"},{"admin":false,"id":"6","lastTime":1642969720288,"realName":"武怡","roleIds":"","status":"0"},{"admin":false,"id":"7","lastTime":1642969720288,"password":"123","realName":"阿紫","roleIds":"2","status":"0","username":"azi"},{"admin":false,"id":"8","lastTime":1642969720288,"realName":"愛玲","roleIds":""},{"admin":false,"id":"9","lastTime":1642969720288,"realName":"劍聖","roleIds":""}]}});
    // return request({
//     url: '/gw/user/list',
//     method: 'get',
//     params: query
// })
}

 

CURD組件可以使用全局注冊或者單獨import都可以,文件路徑和內容:packages/ve-curd/src/VeCurd.vue

<!--
 * @Author: ruphy若非
 * @Date: 2022-01-20 11:03:21
 * @Description: curd
-->
<template>
    <div style="height: 100%; width: 100%; min-height: 500px">
        <div style="height: 100%; width: 100%" v-if="curdType === 'tree'">
            <el-input
                v-model="treeQuery"
                clearable
                :suffix-icon="Search"
                placeholder="請輸入..."
                @input="onTreeQueryChanged"
            >
                <template #append>
                    <el-button
                        :icon="Plus"
                        @click="handleTreeAdd(null, {})"
                    ></el-button>
                </template>
            </el-input>
            <el-tree
                ref="treeRef"
                :indent="10"
                empty-text="當前沒有數據"
                v-bind="$attrs"
                :data="data"
                :props="props"
                :filter-method="filterHandle"
            >
                <template #default="scope">
                    <slot :node="scope.node" :data="scope.data">
                        <div style="width: 100%; height: 100%">
                            <el-dropdown trigger="contextmenu">
                                <el-icon>
                                    <Folder v-if="!scope.node.isLeaf" />
                                    <Document v-else />
                                    <el-tooltip
                                        :content="scope.node.label"
                                        placement="bottom"
                                        :show-after="1000"
                                        effect="light"
                                    >
                                        <span>{{ scope.node.label }}</span>
                                    </el-tooltip>
                                </el-icon>
                                <template #dropdown>
                                    <el-dropdown-menu>
                                        <el-dropdown-item
                                            :icon="Plus"
                                            @click="
                                                handleTreeAdd(
                                                    scope.node,
                                                    scope.data
                                                )
                                            "
                                        >
                                            {{
                                                (permission &&
                                                    permission.add &&
                                                    permission.add.name) ||
                                                "新增"
                                            }}
                                        </el-dropdown-item>
                                        <el-dropdown-item
                                            :icon="Delete"
                                            @click="
                                                handleTreeDelete(
                                                    scope.node,
                                                    scope.data
                                                )
                                            "
                                        >
                                            {{
                                                (permission &&
                                                    permission.del &&
                                                    permission.del.name) ||
                                                "刪除"
                                            }}
                                        </el-dropdown-item>
                                        <el-dropdown-item
                                            :icon="Edit"
                                            @click="
                                                handleTreeEdit(
                                                    scope.node,
                                                    scope.data
                                                )
                                            "
                                        >
                                            {{
                                                (permission &&
                                                    permission.edit &&
                                                    permission.edit.name) ||
                                                "編輯"
                                            }}
                                        </el-dropdown-item>
                                        <el-dropdown-item
                                            :icon="View"
                                            @click="
                                                handleTreeView(
                                                    scope.node,
                                                    scope.data
                                                )
                                            "
                                        >
                                            查看
                                        </el-dropdown-item>
                                    </el-dropdown-menu>
                                </template>
                            </el-dropdown>
                        </div>
                    </slot>
                </template>
            </el-tree>
        </div>
        <div style="width: 100%; height: 100%" v-else>
            <el-card
                v-show="searchShow && searchColumns.length > 0"
                style="margin-bottom: 20px"
            >
                <el-form
                    ref="queryFormRef"
                    :model="$attrs.model"
                    :inline="inline"
                    :label-position="labelPosition"
                    :label-width="labelWidth"
                    :label-suffix="labelSuffix"
                    :hide-required-asterisk="hideRequiredAsterisk"
                    :show-message="showMessage"
                    :inline-message="inlineMessage"
                    :status-icon="statusIcon"
                    :validate-on-rule-change="validateOnRuleChange"
                    :size="size"
                    :disabled="formDisabled"
                    :validate="validate"
                    :validateField="validateField"
                    :resetFields="resetFields"
                    :scrollToField="scrollToField"
                    :clearValidate="clearValidate"
                    @validate="formValidate"
                >
                    <template #default>
                        <slot name="searchForm">
                            <template
                                v-for="(item, index) in searchColumns"
                                :key="index"
                            >
                                <el-form-item
                                    :prop="item.prop"
                                    :label="item.label"
                                    :label-width="item.labelWidth"
                                    :required="item.required"
                                    :error="item.error"
                                    :show-message="item.showMessage"
                                    :inline-message="item.inlineMessage"
                                    :size="item.size"
                                    :resetField="item.resetField"
                                    :clearValidate="item.clearValidate"
                                >
                                    <template #default>
                                        <!--    自定義列的內容slot改名為以屬性名稱命名的slot    -->
                                        <slot :name="item.prop + 'Search'">
                                            <el-date-picker
                                                v-if="item.type === 'daterange'"
                                                clearable
                                                v-model="
                                                    $attrs.model[item.prop]
                                                "
                                                type="daterange"
                                                range-separator="~"
                                                start-placeholder="開始日期"
                                                end-placeholder="結束日期"
                                                :value-format="
                                                    item.valueFormat ||
                                                    'YYYY-MM-DD'
                                                "
                                            >
                                            </el-date-picker>
                                            <el-date-picker
                                                v-else-if="
                                                    item.type ===
                                                    'datetimerange'
                                                "
                                                clearable
                                                v-model="
                                                    $attrs.model[item.prop]
                                                "
                                                type="datetimerange"
                                                range-separator="~"
                                                start-placeholder="開始時間"
                                                end-placeholder="結束時間"
                                                :value-format="
                                                    item.valueFormat ||
                                                    'YYYY-MM-DD hh:mm:ss'
                                                "
                                            >
                                            </el-date-picker>
                                            <el-checkbox
                                                v-else-if="
                                                    item.type === 'checkbox'
                                                "
                                                clearable
                                                v-model="
                                                    $attrs.model[item.prop]
                                                "
                                                :label="$attrs.model[item.prop]"
                                                style="width: 220px"
                                            ></el-checkbox>
                                            <el-cascader
                                                v-else-if="
                                                    item.type === 'select' ||
                                                    item.type ===
                                                        'multiselect' ||
                                                    item.type === 'cascader'
                                                "
                                                clearable
                                                filterable
                                                v-bind="item.dict"
                                                style="width: 220px"
                                                v-model="
                                                    $attrs.model[item.prop]
                                                "
                                            ></el-cascader>
                                            <el-input
                                                v-else
                                                clearable
                                                autosize
                                                placeholder="請輸入..."
                                                style="width: 220px"
                                                v-bind="item"
                                                :type="item.type || 'text'"
                                                :show-password="
                                                    item.type === 'password'
                                                "
                                                v-model="
                                                    $attrs.model[item.prop]
                                                "
                                            ></el-input>
                                        </slot>
                                    </template>
                                    <template #label="scope">
                                        <!--    自定義label的內容slot改名為以屬性名開頭的slot    -->
                                        <slot
                                            :name="item.prop + 'Label'"
                                            :key="scope.key"
                                            :label="scope.label"
                                        >
                                            {{ scope.label }}
                                        </slot>
                                    </template>
                                    <template #error="scope">
                                        <!--    自定義錯誤slot改名為以屬性名開頭的slot    -->
                                        <slot
                                            :name="item.prop + 'Error'"
                                            :error="scope.error"
                                        >
                                            <div class="el-form-item__error">
                                                {{ scope.error }}
                                            </div>
                                        </slot>
                                    </template>
                                </el-form-item>
                            </template>
                            <div style="text-align: right">
                                <el-form-item>
                                    <slot name="searchButton">
                                        <el-button
                                            type="primary"
                                            @click="handleSearch"
                                        >
                                            查詢
                                        </el-button>
                                    </slot>
                                    <slot name="resetButton">
                                        <el-button
                                            @click="resetForm"
                                            style="margin-left: 30px"
                                        >
                                            重置
                                        </el-button>
                                    </slot>
                                </el-form-item>
                            </div>
                        </slot>
                    </template>
                </el-form>
            </el-card>
            <el-card>
                <!-- 工具類 -->
                <div style="margin-top: 20px">
                    <el-row>
                        <el-col :span="20">
                            <slot name="addButton">
                                <el-button
                                    type="primary"
                                    :icon="Plus"
                                    @click="handleAdd"
                                >
                                    {{
                                        (permission &&
                                            permission.add &&
                                            permission.add.name) ||
                                        "新增"
                                    }}
                                </el-button>
                            </slot>
                            <slot name="toolbar"></slot>
                        </el-col>
                        <el-col :span="4" style="text-align: center">
                            <el-button
                                type="text"
                                :icon="Search"
                                @click="handleSearchShow"
                            ></el-button>
                            <el-button
                                type="text"
                                :icon="Expand"
                                @click="initDrawerColumnTree"
                            ></el-button>
                        </el-col>
                    </el-row>
                </div>
                <!-- 表格 -->
                <el-table
                    style="width: 100%"
                    v-bind="$attrs"
                    :data="data"
                    @sort-change="handleSortChange"
                    @filter-change="handleFilterChange"
                >
                    <template #append>
                        <slot name="append"></slot>
                    </template>
                    <!--       表格列         -->
                    <template
                        v-for="(item, index) in tableColumns"
                        :key="index"
                    >
                        <el-table-column
                            v-bind="item"
                            v-if="item.hide !== true"
                            :column-key="item.prop"
                        >
                            <template
                                #default="scope"
                                v-if="
                                    item.type !== 'selection' &&
                                    item.type !== 'index' &&
                                    item.type !== 'expand'
                                "
                            >
                                <!--    自定義列的內容slot改名為以屬性名稱命名的slot    -->
                                <slot
                                    :name="item.prop + 'Value'"
                                    :row="scope.row"
                                    :column="item"
                                    :$index="index"
                                >
                                    {{ getLabel(scope.row[item.prop], item) }}
                                </slot>
                            </template>
                            <template #header="scope">
                                <!--    自定義表頭的內容slot改名為以屬性名稱開頭的slot    -->
                                <slot
                                    :name="item.prop + 'Header'"
                                    :column="item"
                                    :$index="index"
                                >
                                    {{ scope.column.label }}
                                </slot>
                            </template>
                        </el-table-column>
                    </template>
                    <!-- 操作 -->
                    <el-table-column fixed="right" label="操作" width="180">
                        <template #default="scope">
                            <slot
                                name="viewButton"
                                :row="scope.row"
                                :$index="scope.$index"
                            >
                                <el-button
                                    size="small"
                                    type="text"
                                    :icon="View"
                                    @click="handleView(scope.row, scope.$index)"
                                >
                                    {{
                                        (permission &&
                                            permission.search &&
                                            permission.search.name) ||
                                        "查看"
                                    }}
                                </el-button>
                            </slot>
                            <slot
                                name="editButton"
                                :row="scope.row"
                                :$index="scope.$index"
                            >
                                <el-button
                                    size="small"
                                    type="text"
                                    :icon="Edit"
                                    @click="handleEdit(scope.row, scope.$index)"
                                >
                                    {{
                                        (permission &&
                                            permission.edit &&
                                            permission.edit.name) ||
                                        "編輯"
                                    }}
                                </el-button>
                            </slot>
                            <slot
                                name="delButton"
                                :row="scope.row"
                                :$index="scope.$index"
                            >
                                <el-button
                                    size="small"
                                    type="text"
                                    style="color: red"
                                    :icon="Delete"
                                    @click="
                                        handleDelete(scope.row, scope.$index)
                                    "
                                >
                                    {{
                                        (permission &&
                                            permission.del &&
                                            permission.del.name) ||
                                        "刪除"
                                    }}
                                </el-button>
                            </slot>
                            <slot
                                name="operate"
                                :$index="scope.$index"
                                :row="scope.row"
                            ></slot>
                        </template>
                    </el-table-column>
                </el-table>
                <!-- 分頁 -->
                <el-pagination
                    :small="small"
                    :background="background"
                    :total="total"
                    :page-count="pageCount"
                    :pager-count="pagerCount"
                    :page-sizes="pageSizes"
                    :popper-class="popperClass"
                    :prev-text="prevText"
                    :next-text="nextText"
                    :disabled="paginationDisabled"
                    :hide-on-single-page="hideOnSinglePage"
                    :default-current-page="defaultCurrentPage"
                    :layout="layout"
                    @size-change="handleSizeChange"
                    @current-change="handleCurrentChange"
                >
                </el-pagination>
            </el-card>
            <el-drawer
                v-model="drawerColumnShow"
                direction="rtl"
                title="自定義列顯示或隱藏"
            >
                <el-tree
                    ref="drawerColumnTree"
                    :data="tableColumns"
                    :props="{ label: 'label' }"
                    node-key="prop"
                    show-checkbox
                    @check-change="drawerTreeChange"
                />
            </el-drawer>
        </div>
        <!-- 查看 -->
        <el-dialog
            v-model="dialogViewFormVisible"
            :title="viewTitle"
            @open="handleViewOpen"
            @opened="handleViewOpened"
            @close="handleViewClose"
            @closed="handleViewClosed"
        >
            <template #title>
                <el-icon><View /></el-icon>
                <span>{{ viewTitle }}</span>
            </template>
            <el-form
                ref="viewFormRef"
                :model="form"
                :inline="inline"
                :label-position="labelPosition"
                :label-width="labelWidth"
                :label-suffix="labelSuffix"
                :status-icon="statusIcon"
                :size="size"
                :disabled="true"
            >
                <template #default>
                    <slot name="editForm" :form="form">
                        <template
                            v-for="(item, index) in viewColumns"
                            :key="index"
                        >
                            <el-form-item
                                v-if="item.viewable !== false"
                                :prop="item.prop"
                                :label="item.label"
                                :label-width="item.labelWidth"
                                :size="item.size"
                            >
                                <template #default>
                                    <!--    自定義列的內容slot改名為以屬性名稱命名的slot    -->
                                    <slot :name="item.prop + 'View'">
                                        <el-date-picker
                                            v-if="item.type === 'daterange'"
                                            v-model="form[item.prop]"
                                            type="daterange"
                                            range-separator="~"
                                            start-placeholder="開始日期"
                                            end-placeholder="結束日期"
                                            disabled
                                            :value-format="
                                                item.valueFormat || 'YYYY-MM-DD'
                                            "
                                        >
                                        </el-date-picker>
                                        <el-date-picker
                                            v-else-if="
                                                item.type === 'datetimerange'
                                            "
                                            disabled
                                            v-model="form[item.prop]"
                                            type="datetimerange"
                                            range-separator="~"
                                            start-placeholder="開始時間"
                                            end-placeholder="結束時間"
                                            :value-format="
                                                item.valueFormat ||
                                                'YYYY-MM-DD hh:mm:ss'
                                            "
                                        >
                                        </el-date-picker>
                                        <el-checkbox
                                            v-else-if="item.type === 'checkbox'"
                                            v-model="form[item.prop]"
                                            :label="form[item.prop]"
                                            style="width: 220px"
                                            disabled
                                        ></el-checkbox>
                                        <el-cascader
                                            v-else-if="
                                                item.type === 'select' ||
                                                item.type === 'multiselect' ||
                                                item.type === 'cascader'
                                            "
                                            v-bind="item.dict"
                                            v-model="form[item.prop]"
                                            style="width: 220px"
                                            disabled
                                        ></el-cascader>
                                        <el-input
                                            v-else
                                            clearable
                                            autosize
                                            placeholder="請輸入..."
                                            style="width: 220px"
                                            v-bind="item"
                                            :type="item.type || 'text'"
                                            :show-password="
                                                item.type === 'password'
                                            "
                                            v-model="form[item.prop]"
                                            disabled
                                        ></el-input>
                                    </slot>
                                </template>
                                <template #label="scope">
                                    <!--    自定義label的內容slot改名為以屬性名開頭的slot    -->
                                    <slot
                                        :name="item.prop + 'Label'"
                                        :key="scope.key"
                                        :label="scope.label"
                                    >
                                        {{ scope.label }}
                                    </slot>
                                </template>
                            </el-form-item>
                        </template>
                    </slot>
                </template>
            </el-form>
            <template #footer>
                <span class="dialog-footer">
                    <el-button @click="dialogViewFormVisible = false">
                        關閉
                    </el-button>
                </span>
            </template>
        </el-dialog>
        <!-- 編輯 -->
        <el-dialog
            v-model="dialogEditFormVisible"
            :title="editTitle"
            @open="handleEditOpen"
            @opened="handleEditOpened"
            @close="handleEditClose"
            @closed="handleEditClosed"
        >
            <template #title>
                <el-icon><Edit /></el-icon>
                <span>{{ editTitle }}</span>
            </template>
            <el-form
                ref="editFormRef"
                :model="form"
                :rules="rules"
                :inline="inline"
                :label-position="labelPosition"
                :label-width="labelWidth"
                :label-suffix="labelSuffix"
                :hide-required-asterisk="hideRequiredAsterisk"
                :show-message="showMessage"
                :inline-message="inlineMessage"
                :status-icon="statusIcon"
                :validate-on-rule-change="validateOnRuleChange"
                :size="size"
                :disabled="formDisabled"
                :validate="validate"
                :validateField="validateField"
                :resetFields="resetFields"
                :scrollToField="scrollToField"
                :clearValidate="clearValidate"
                @validate="formValidate"
            >
                <template #default>
                    <slot name="editForm">
                        <template
                            v-for="(item, index) in editColumns"
                            :key="index"
                        >
                            <el-form-item
                                v-if="item.editable"
                                :prop="item.prop"
                                :label="item.label"
                                :label-width="item.labelWidth"
                                :required="item.required"
                                :rules="item.rules"
                                :error="item.error"
                                :show-message="item.showMessage"
                                :inline-message="item.inlineMessage"
                                :size="item.size"
                                :resetField="item.resetField"
                                :clearValidate="item.clearValidate"
                            >
                                <template #default>
                                    <!--    自定義列的內容slot改名為以屬性名稱命名的slot    -->
                                    <slot :name="item.prop + 'Edit'">
                                        <el-date-picker
                                            v-if="item.type === 'daterange'"
                                            clearable
                                            v-model="form[item.prop]"
                                            type="daterange"
                                            range-separator="~"
                                            start-placeholder="開始日期"
                                            end-placeholder="結束日期"
                                            :value-format="
                                                item.valueFormat || 'YYYY-MM-DD'
                                            "
                                        >
                                        </el-date-picker>
                                        <el-date-picker
                                            v-else-if="
                                                item.type === 'datetimerange'
                                            "
                                            clearable
                                            v-model="form[item.prop]"
                                            type="datetimerange"
                                            range-separator="~"
                                            start-placeholder="開始時間"
                                            end-placeholder="結束時間"
                                            :value-format="
                                                item.valueFormat ||
                                                'YYYY-MM-DD hh:mm:ss'
                                            "
                                        >
                                        </el-date-picker>
                                        <el-checkbox
                                            v-else-if="item.type === 'checkbox'"
                                            clearable
                                            v-model="form[item.prop]"
                                            :label="form[item.prop]"
                                            style="width: 220px"
                                        ></el-checkbox>
                                        <el-cascader
                                            v-else-if="
                                                item.type === 'select' ||
                                                item.type === 'multiselect' ||
                                                item.type === 'cascader'
                                            "
                                            clearable
                                            filterable
                                            v-bind="item.dict"
                                            style="width: 220px"
                                            v-model="form[item.prop]"
                                        ></el-cascader>
                                        <el-input
                                            v-else
                                            clearable
                                            autosize
                                            placeholder="請輸入..."
                                            style="width: 220px"
                                            v-bind="item"
                                            :type="item.type || 'text'"
                                            :show-password="
                                                item.type === 'password'
                                            "
                                            v-model="form[item.prop]"
                                        ></el-input>
                                    </slot>
                                </template>
                                <template #label="scope">
                                    <!--    自定義label的內容slot改名為以屬性名開頭的slot    -->
                                    <slot
                                        :name="item.prop + 'Label'"
                                        :key="scope.key"
                                        :label="scope.label"
                                    >
                                        {{ scope.label }}
                                    </slot>
                                </template>
                                <template #error="scope">
                                    <!--    自定義錯誤slot改名為以屬性名開頭的slot    -->
                                    <slot
                                        :name="item.prop + 'Error'"
                                        :error="scope.error"
                                    >
                                        <div class="el-form-item__error">
                                            {{ scope.error }}
                                        </div>
                                    </slot>
                                </template>
                            </el-form-item>
                        </template>
                    </slot>
                </template>
            </el-form>
            <template #footer>
                <span class="dialog-footer">
                    <el-button type="primary" @click="handleEditSure">
                        確認
                    </el-button>
                    <el-button @click="dialogEditFormVisible = false">
                        取消
                    </el-button>
                </span>
            </template>
        </el-dialog>
        <!-- 新增 -->
        <el-dialog
            v-model="dialogAddFormVisible"
            :title="addTitle"
            @open="handleAddOpen"
            @opened="handleAddOpened"
            @close="handleAddClose"
            @closed="handleAddClosed"
        >
            <template #title>
                <el-icon><Plus /></el-icon>
                <span>{{ addTitle }}</span>
            </template>
            <el-form
                ref="addFormRef"
                :model="form"
                :rules="rules"
                :inline="inline"
                :label-position="labelPosition"
                :label-width="labelWidth"
                :label-suffix="labelSuffix"
                :hide-required-asterisk="hideRequiredAsterisk"
                :show-message="showMessage"
                :inline-message="inlineMessage"
                :status-icon="statusIcon"
                :validate-on-rule-change="validateOnRuleChange"
                :size="size"
                :disabled="formDisabled"
                :validate="validate"
                :validateField="validateField"
                :resetFields="resetFields"
                :scrollToField="scrollToField"
                :clearValidate="clearValidate"
                @validate="formValidate"
            >
                <template #default>
                    <slot name="addForm">
                        <template
                            v-for="(item, index) in addColumns"
                            :key="index"
                        >
                            <el-form-item
                                v-if="item.addable"
                                :prop="item.prop"
                                :label="item.label"
                                :label-width="item.labelWidth"
                                :required="item.required"
                                :rules="item.rules"
                                :error="item.error"
                                :show-message="item.showMessage"
                                :inline-message="item.inlineMessage"
                                :size="item.size"
                                :resetField="item.resetField"
                                :clearValidate="item.clearValidate"
                            >
                                <template #default>
                                    <!--    自定義列的內容slot改名為以屬性名稱命名的slot    -->
                                    <slot :name="item.prop + 'Add'">
                                        <el-date-picker
                                            v-if="item.type === 'daterange'"
                                            v-model="form[item.prop]"
                                            type="daterange"
                                            range-separator="~"
                                            start-placeholder="開始日期"
                                            end-placeholder="結束日期"
                                            :value-format="
                                                item.valueFormat || 'YYYY-MM-DD'
                                            "
                                            clearable
                                        >
                                        </el-date-picker>
                                        <el-date-picker
                                            v-else-if="
                                                item.type === 'datetimerange'
                                            "
                                            v-model="form[item.prop]"
                                            type="datetimerange"
                                            range-separator="~"
                                            start-placeholder="開始時間"
                                            end-placeholder="結束時間"
                                            :value-format="
                                                item.valueFormat ||
                                                'YYYY-MM-DD hh:mm:ss'
                                            "
                                            clearable
                                        >
                                        </el-date-picker>
                                        <el-checkbox
                                            v-else-if="item.type === 'checkbox'"
                                            v-model="form[item.prop]"
                                            :label="form[item.prop]"
                                            style="width: 220px"
                                            clearable
                                        ></el-checkbox>
                                        <el-cascader
                                            v-else-if="
                                                item.type === 'select' ||
                                                item.type === 'multiselect' ||
                                                item.type === 'cascader'
                                            "
                                            clearable
                                            filterable
                                            style="width: 220px"
                                            v-bind="item.dict"
                                            v-model="form[item.prop]"
                                        ></el-cascader>
                                        <el-input
                                            v-else
                                            clearable
                                            autosize
                                            placeholder="請輸入..."
                                            style="width: 220px"
                                            v-bind="item"
                                            :type="item.type || 'text'"
                                            :show-password="
                                                item.type === 'password'
                                            "
                                            v-model="form[item.prop]"
                                        ></el-input>
                                    </slot>
                                </template>
                                <template #label="scope">
                                    <!--    自定義label的內容slot改名為以屬性名開頭的slot    -->
                                    <slot
                                        :name="item.prop + 'Label'"
                                        :key="scope.key"
                                        :label="scope.label"
                                    >
                                        {{ scope.label }}
                                    </slot>
                                </template>
                                <template #error="scope">
                                    <!--    自定義錯誤slot改名為以屬性名開頭的slot    -->
                                    <slot
                                        :name="item.prop + 'Error'"
                                        :error="scope.error"
                                    >
                                        <div class="el-form-item__error">
                                            {{ scope.error }}
                                        </div>
                                    </slot>
                                </template>
                            </el-form-item>
                        </template>
                    </slot>
                </template>
            </el-form>
            <template #footer>
                <span class="dialog-footer">
                    <el-button type="primary" @click="handleAddSure">
                        確認
                    </el-button>
                    <el-button @click="dialogAddFormVisible = false">
                        取消
                    </el-button>
                </span>
            </template>
        </el-dialog>
        <!-- 刪除 -->
        <el-dialog
            v-model="dialogDeleteVisible"
            :title="deleteTitle"
            width="30%"
        >
            <template #title>
                <el-icon><Delete /></el-icon>
                <span>{{ deleteTitle }}</span>
            </template>
            <span>確認刪除嗎?</span>
            <template #footer>
                <span class="dialog-footer">
                    <el-button type="primary" @click="handleDeleteSure">
                        確認
                    </el-button>
                    <el-button @click="dialogDeleteVisible = false">
                        取消
                    </el-button>
                </span>
            </template>
        </el-dialog>
    </div>
</template>

<script>
export default {
    name: "ve-curd",
    emits: [
        "update:currentPage",
        "update:pageSize",
        "update:ascs",
        "update:descs",
        "update:filters",
        "searchChange",
        "sizeChange",
        "currentChange",
        "sortChange",
        "filterChange",
        "viewOpen",
        "viewOpened",
        "viewClose",
        "viewClosed",
        "addOpen",
        "addOpened",
        "addClose",
        "addClosed",
        "addSure",
        "editOpen",
        "editOpened",
        "editClose",
        "editClosed",
        "editSure",
        "deleteSure",
    ],
    props: {
        curdType: {
            type: String,
            default: "table", // tree
},
        props: Object,
        // 表格數據
data: Array,
        // 編輯表單
editTitle: {
            type: String,
            default: "編輯",
        },
        // 新增表單
addTitle: {
            type: String,
            default: "新增",
        },
        // 查看表單
viewTitle: {
            type: String,
            default: "查看",
        },
        // 查看表單
deleteTitle: {
            type: String,
            default: "刪除",
        },
        // 詳情表單
detailTitle: {
            type: String,
            default: "詳情",
        },
        // 查詢表單相關
rules: Object, // el-form的rules
inline: {
            type: Boolean,
            default: true,
        },
        formDisabled: Boolean,
        labelPosition: String,
        labelWidth: {
            type: [String, Number],
            default: "160px",
        },
        labelSuffix: String,
        hideRequiredAsterisk: Boolean,
        showMessage: {
            type: Boolean,
            default: true,
        },
        inlineMessage: Boolean,
        statusIcon: Boolean,
        validateOnRuleChange: Boolean,
        size: String,
        validate: Function,
        validateField: Function,
        resetFields: Function,
        scrollToField: Function,
        clearValidate: Function,
        // 表屬性全部支持el-table的原始屬性、方法、事件和插槽  只是將 el改為ve 直接通過 v-bind="$attr" 傳給el-table組件
permission: {
            type: Object,
            default: () => {},
        },
        // 表列屬性 在ve-table上通過:columns 綁定 el-table-column的所有支持的屬性、方法和插槽等,也新增了一些crud相關的屬性
columns: {
            type: Array,
            default: () => [],
        },
        // 分頁 和原始el-pagination屬性使用沒什么改變,只是全部綁定在ve-table上面
pageSizes: {
            type: Array,
            default: () => [10, 20, 50, 100, 200, 500],
        },
        hideOnSinglePage: {
            type: Boolean,
            default: true,
        },
        small: Boolean,
        background: Boolean,
        total: Number,
        pageCount: Number,
        pagerCount: Number,
        // pageSize: {
//     type: Number,
//     default: 10,
// },
// currentPage: {
//     type: Number,
//     default: 1,
// },
popperClass: String,
        prevText: String,
        nextText: String,
        paginationDisabled: Boolean,
        defaultCurrentPage: {
            type: Number,
            default: 1,
        },
        defaultPageSize: Number,
        layout: {
            type: String,
            default: "total, sizes, prev, pager, next, jumper",
        },
    },
};
</script>

<script setup>
import {
    getCurrentInstance,
    onMounted,
    reactive,
    ref,
    unref,
    watch,
} from "vue";
import {
    Search,
    Plus,
    Delete,
    View,
    Edit,
    Expand,
    Folder,
    Document,
} from "@element-plus/icons-vue";

const { proxy } = getCurrentInstance(); //獲取上下文實例,ctx=vue2的this
const form = ref({});
const queryFormRef = ref();
const addFormRef = ref();
const editFormRef = ref();
const dialogDeleteVisible = ref(false);
const dialogViewFormVisible = ref(false);
const dialogEditFormVisible = ref(false);
const dialogAddFormVisible = ref(false);
const searchShow = ref(true);
const drawerColumnShow = ref(false);
const drawerColumnTree = ref(null);

const treeQuery = ref("");
// eslint-disable-next-line no-undef
const treeRef = ref();

const onTreeQueryChanged = (treeQuery) => {
    if (treeRef.value && treeRef.value.filter) {
        treeRef.value.filter(treeQuery);
    }
};

const filterHandle = (treeQuery, node) => {
    if (!treeQuery) {
        return true;
    }
    let label = node[proxy.props["label"] || "label"];
    if (typeof proxy.filterMethod === "function") {
        return proxy.filterMethod(treeQuery, node);
    }
    if (label) {
        return label.indexOf(treeQuery) !== -1;
    }
    return false;
};

const handleSearchShow = () => {
    searchShow.value = !searchShow.value;
};

const drawerTreeChange = (val, node) => {
    val.hide = !node;
};

const handleSizeChange = (val) => {
    // this.$attr.onSizeChange(val) // OK
proxy.$emit("update:pageSize", val); // OK
proxy.$emit("sizeChange", val); // OK
};
const handleCurrentChange = (val) => {
    proxy.$emit("update:currentPage", val); // OK
proxy.$emit("currentChange", val); // OK
};
const formValidate = (prop) => {
    proxy.$emit("validate", prop);
};

const tableColumns = ref(
    proxy.columns.map((column) => {
        let col = {};
        for (const k in column) {
            col[k] = column[k];
        }
        if (
            col.type !== "selection" &&
            col.type !== "index" &&
            col.type !== "expand"
        ) {
            col.rawFilters = !!col.filters;
            col.filterMethod =
                col.filterMethod ||
                function (value, row, column) {
                    const property = column["property"] || column["prop"];
                    return row[property] === value;
                };
        }
        return col;
    })
);

const formColumns = (columns = [], res = []) => {
    return columns.reduce((cols, col) => {
        if (col.children instanceof Array) {
            formColumns(col.children, cols);
        }
        col.showMessage = !!col.showMessage;
        cols.push(col);
        return cols;
    }, res);
};
const searchColumns = reactive(
    formColumns(proxy.columns).filter((col) => col.search === true)
);
const viewColumns = reactive(
    formColumns(proxy.columns).filter((col) => col.viewable === true)
);
const editColumns = reactive(
    formColumns(proxy.columns).filter((col) => col.editable === true)
);
const addColumns = reactive(
    formColumns(proxy.columns).filter((col) => col.addable === true)
);

const handleSearch = async function () {
    const form = unref(queryFormRef);
    if (!form) {
        return;
    }
    try {
        let valid = await form.validate();
        if (valid) {
            searchChange();
        }
    } catch (err) {
        console.log("err", err);
    }
};

const resetForm = function () {
    const form = unref(queryFormRef);
    form.resetFields();
};

const ascs = ref([]);
const descs = ref([]);
const handleSortChange = ({ column, prop, order }) => {
    let idx = ascs.value.indexOf(prop);
    if (idx > -1) {
        ascs.value.splice(idx, 1);
    }
    idx = descs.value.indexOf(prop);
    if (idx > -1) {
        descs.value.splice(idx, 1);
    }
    if ("ascending" === order) {
        ascs.value.push(prop);
    } else if ("descending" === order) {
        descs.value.push(prop);
    }
    proxy.$emit("update:ascs", ascs.value);
    proxy.$emit("update:descs", descs.value);
    proxy.$emit("sortChange", { column, prop, order });
};

const handleFilterChange = (filters) => {
    proxy.$emit("update:filters", filters);
    proxy.$emit("filterChange", filters);
};

const searchChange = () => {
    proxy.$emit("searchChange"); // OK
};

// 查看
const handleTreeView = (node, data) => {
    dialogViewFormVisible.value = true;
    form.value = JSON.parse(JSON.stringify(data));
};
const handleView = (row, index) => {
    dialogViewFormVisible.value = true;
    form.value = row;
};
const handleViewOpen = () => {
    proxy.$emit("viewOpen", form.value); // OK
};
const handleViewOpened = () => {
    proxy.$emit("viewOpened", form.value); // OK
};
const handleViewClose = () => {
    proxy.$emit("viewClose", form.value); // OK
};
const handleViewClosed = () => {
    proxy.$emit("viewClosed", form.value); // OK
};

// 編輯
const handleTreeEdit = (node, data) => {
    dialogEditFormVisible.value = true;
    form.value = JSON.parse(JSON.stringify(data));
};
const handleEdit = (row, index) => {
    dialogEditFormVisible.value = true;
    form.value = JSON.parse(JSON.stringify(row));
};
const handleEditSure = async () => {
    const ef = unref(editFormRef);
    if (!ef) {
        return;
    }
    try {
        let valid = await ef.validate();
        if (valid) {
            let value = form.value;
            let find = false;
            for (const k in value) {
                if (value[k] instanceof Array) {
                    let columns = formColumns(proxy.columns);
                    for (let col of columns) {
                        if (col.type === "select") {
                            value[k] = value[k][0];
                            find = true;
                            break;
                        }
                        if (col.type === "multiselect") {
                            value[k] = value[k].join();
                            find = true;
                            break;
                        }
                    }
                    if (find) {
                        break;
                    }
                }
            }
            proxy.$emit("editSure", value); // OK
dialogEditFormVisible.value = false;
        }
    } catch (err) {
        console.log("err", err);
    }
};
const handleEditOpen = () => {
    proxy.$emit("editOpen", form.value); // OK
};
const handleEditOpened = () => {
    proxy.$emit("editOpened", form.value); // OK
};
const handleEditClose = () => {
    proxy.$emit("editClose", form.value); // OK
};
const handleEditClosed = () => {
    proxy.$emit("editClosed", form.value); // OK
};
// 新增
const handleTreeAdd = (node, data = {}) => {
    dialogAddFormVisible.value = true;
    form.value = JSON.parse(JSON.stringify(data));
};
const handleAdd = () => {
    dialogAddFormVisible.value = true;
    form.value = {};
};
const handleAddSure = async () => {
    const ef = unref(addFormRef);
    if (!ef) {
        return;
    }
    try {
        let valid = await ef.validate();
        if (valid) {
            let value = form.value;
            let find = false;
            for (const k in value) {
                if (value[k] instanceof Array) {
                    let columns = formColumns(proxy.columns);
                    for (let col of columns) {
                        if (col.type === "select") {
                            value[k] = value[k][0];
                            find = true;
                            break;
                        }
                        if (col.type === "multiselect") {
                            value[k] = value[k].join();
                            find = true;
                            break;
                        }
                    }
                    if (find) {
                        break;
                    }
                }
            }
            proxy.$emit("addSure", value); // OK
dialogAddFormVisible.value = false;
        }
    } catch (err) {
        console.log("err", err);
    }
};
const handleAddOpen = () => {
    proxy.$emit("addOpen", form.value); // OK
};
const handleAddOpened = () => {
    proxy.$emit("addOpened", form.value); // OK
};
const handleAddClose = () => {
    proxy.$emit("addClose", form.value); // OK
};
const handleAddClosed = () => {
    proxy.$emit("addClosed", form.value); // OK
};
//刪除
const handleTreeDelete = (node, data) => {
    dialogDeleteVisible.value = true;
    form.value = JSON.parse(JSON.stringify(data));
};
const handleDelete = (row, index) => {
    dialogDeleteVisible.value = true;
    form.value = row;
};
const handleDeleteSure = () => {
    proxy.$emit("deleteSure", form.value); // OK
dialogDeleteVisible.value = false;
};

watch(
    () => proxy.data,
    (n) => {
        //直接監聽
let cols = tableColumns.value;
        for (let i = 0; i < cols.length; i++) {
            let col = cols[i];
            col.dict = col.dict || {};
            col.dict.props = Object.assign(
                {
                    label: "label",
                    value: "value",
                },
                col.dict.props
            );
            if (col.rawFilters) {
                col.filters = col.filters.map((v) => {
                    return {
                        text: v.text || v.label,
                        label: v.label || v.text,
                        value: v.value,
                    };
                });
                col.dict.options = col.dict.options || col.filters;
                continue;
            }
            if (col.type === "select") {
                if (col.dict instanceof Array) {
                    col.dict.forEach((v, i, a) => {
                        if (
                            typeof v === "number" ||
                            typeof v === "string" ||
                            typeof v === "number" ||
                            v instanceof Date
                        ) {
                            a[i] = { text: v, label: v, value: v };
                        }
                    });
                    col.filters = col.dict;
                    col.dict = { options: col.dict };
                } else if (typeof col.dict === "object") {
                    let method = col.dict.method || "get";
                    if (col.dict.options instanceof Array) {
                        col.filters = col.dict.options.map((v) => {
                            return {
                                text: v[col.dict.props.label],
                                label: v[col.dict.props.label],
                                value: v[col.dict.props.value],
                            };
                        });
                        tableColumns.value = cols;
                    } else if (col.dict.url) {
                        proxy.$axios[method](col.dict.url, {}).then((res) => {
                            let data = res.data;
                            if (
                                !(data instanceof Array) &&
                                data.data instanceof Array
                            ) {
                                data = data.data;
                            } else {
                                data = [];
                            }
                            data = data.map((v) => {
                                if (
                                    typeof v === "number" ||
                                    typeof v === "string" ||
                                    typeof v === "number" ||
                                    v instanceof Date
                                ) {
                                    return { text: v, label: v, value: v };
                                }
                                return {
                                    text: v[col.dict.props.label],
                                    label: v[col.dict.props.label],
                                    value: v[col.dict.props.value],
                                };
                            });
                            col.dict.options = data;
                            col.filters = data;
                            tableColumns.value = cols;
                        });
                    }
                }
            } else {
                col.filters = n.reduce(
                    (a, v) => {
                        if (!a.k[v[col.prop]]) {
                            a.k[v[col.prop]] = true;
                            a.a.push({
                                text: v[col.prop],
                                label: v[col.prop],
                                value: v[col.prop],
                            });
                        }
                        return a;
                    },
                    { k: {}, a: [] }
                ).a;
                col.dict.options = col.filters;
            }
        }
        tableColumns.value = cols;
    }
);

const initDrawerColumnTree = () => {
    drawerColumnShow.value = true;
    setTimeout(() => {
        if (drawerColumnTree.value) {
            tableColumns.value.forEach((c) => {
                drawerColumnTree.value.setChecked(c, c.hide !== true, false); //反選
});
        }
    }, 0);
};

const getLabel = (value, column) => {
    if (!column) {
        return value;
    }
    if (column.dict && column.dict.options instanceof Array) {
        for (let opt of column.dict.options) {
            if (opt.value === value) {
                return opt.label || opt.text || value;
            }
        }
    }
    return value;
};

onMounted(() => {
    console.log("proxy", proxy);
});
</script>

<style scoped>
.el-tree {
    margin-top: 10px;
}
.el-tree-node {
    font-size: 34px;
}
.el-tree-node__content {
    margin: 5px 0;
}
</style>
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM