首页 > 其他分享 >element中的条件字段页面封装

element中的条件字段页面封装

时间:2025-01-15 13:45:54浏览次数:1  
标签:const filed value element item import 封装 true 页面

笔记:
页面搜索栏封装:

 

<tableQueryForm
ref="queryFormRef"
:form-select="QUERY_FORM_SELECT"
:model="queryForm"
>
<el-form-item :label="$swpT('page.swModulePlan.isSelf')" prop="orderCode">
<el-select v-model="queryForm.selfInnovateFlag">
<el-option label="是" value="Y">是</el-option>
<el-option label="否" value="N">否</el-option>
</el-select>
</el-form-item>
<el-form-item :label="$swpT('page.swModulePlan.isStandModules')" prop="orderCode">
<el-select v-model="queryForm.standardFlag">
<el-option label="是" value="Y">是</el-option>
<el-option label="否" value="N">否</el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-form-item>
<i class="fa-search"/>
<el-button icon="search" type="primary" @click="getTableData"
>{{ $swpT("common.search") }}
</el-button>
<el-button icon="refresh" @click="resetSearch()">{{ $swpT("common.reset") }}</el-button>
</el-form-item>
</el-form-item>
</tableQueryForm>

// 软件模块复用率
import TableQueryForm from "@/components/tableQueryForm.vue";
const queryForm = reactive<any>({});
const queryFormRef = ref<any>();

引用:
// 查询表单
const QUERY_FORM_SELECT = [
{
label: "ECU",
filed: "ecu",
remote: {
url: `${
import.meta.env.VITE_APP_SERVICE_BASE_PATH
}query/condition/ecu/list`,
method: "post"
},
prop: {
filterable: true,
multiple: true,
remote: true,
reserveKeyword: true,
remoteShowSuffix: true,
collapseTags: true
}
},
{
label: $swpT("page.swModulePlan.project"),
filed: "project",
remote: {
url: `${
import.meta.env.VITE_APP_SERVICE_BASE_PATH
}query/condition/softmodule/selection/project`,
method: "get"
},
prop: {
filterable: true,
multiple: true,
clearable: true,
collapseTags: true
}
},
{
label: $swpT("page.swModulePlan.softwareModules"),
filed: "moduleName",
remote: {
url: `${
import.meta.env.VITE_APP_SERVICE_BASE_PATH
}/query/condition/softmodule/reuse/moduleNames`,
method: "get"
},
prop: {
filterable: true,
multiple: true,
clearable: true,
collapseTags: true
}
},
{
label: $swpT("field.center"),
filed: "center",
remote: {
url: `${
import.meta.env.VITE_APP_SERVICE_BASE_PATH
}/query/condition/sys/config/querySpaceCenters`,
method: "get"
},
prop: {
filterable: true,
multiple: true,
clearable: true,
collapseTags: true
}
}

];

选择框封装页面:
<template>
<el-form ref="queryFormRef" class="search-panel" inline>
<el-form-item
v-for="item in props.formSelect"
:key="item.filed"
:label="item.label"
:prop="item.filed"
>
<el-select
v-model="($attrs as any)['model'][item.filed]"
:remote-method="(query:string)=>optionRemoteMethod({query,item})"
v-bind="item.prop"
@click="
item.prop.remote ? optionRemoteMethod({ query: ' ', item }) : ''
"
>
<el-option
v-for="(i, index) in queryOptions[item.filed]"
:key="index"
:label="i[item.optionsValueKey?.label || ''] ?? i"
:value="i[item.optionsValueKey?.value || ''] ?? i"
></el-option>
</el-select>
</el-form-item>
<slot></slot>
</el-form>
</template>

<script lang="ts" setup>
import {Res} from "@/types/global";
RES页面:
// 接口返回值
export type Res<T = any> = {
code: number | string;
msg: string;
biz_content: Nullable<T>;
bizContent: Nullable<T>;
};
import {http} from "@/utils";
import {defineExpose, defineProps, onMounted, reactive, ref, withDefaults} from "vue";

const queryOptions = reactive<any>({});
const props = withDefaults(defineProps<{ formSelect: any }>(), {
formSelect: []
});
const queryFormRef = ref();

onMounted(() => {
getEnum();
});


// 获取枚举筛选项
const getEnum = async() => {
props.formSelect.forEach(async(item: any) => {
const {method, url} = item.remote;
if (!item.prop.remote) {
const {code, biz_content} = await http[method as "get" | "post"]<Res>(
url,
{}
);
if (code == 10000) {
queryOptions[item.filed] = biz_content;
}
}
});
};

// 远程搜索
const optionRemoteMethod = async({query, item}: any) => {
const {remote, filed} = item;
if (query) {
item.prop.loading = true;
const {code, biz_content} = await http[
remote.method as "get" | "post"
]<Res>(remote.url, {
[filed]: query
});
item.prop.loading = false;
if (code == 10000) {
queryOptions[filed] = biz_content;
} else {
queryOptions[filed] = [];
}
}
};

// 重置
const resetFields = () => {
queryFormRef.value.resetFields();
};

defineExpose({resetFields});
</script>


htttp.ts

import {qiankunWindow} from "@/libs/viteQiankun/helper";
import {Lang} from "@/settings/base.ts";
import {useBaseStore} from "@/store";
import type {Axios, AxiosError, AxiosResponse, InternalAxiosRequestConfig} from "axios";
import axios from "axios";
import {ElMessage} from "element-plus";
import qs from "qs";

interface RequestConfig extends InternalAxiosRequestConfig {
silent?: boolean;
}

interface ResponseWrapper<T = object> {
code: number;
msg: string;
sub_msg: string;
success: boolean;
data: T;
value: string;
message: string;
}

interface ResponseError extends AxiosError, Omit<ResponseWrapper, "code"> {
}

const instance: Axios = axios.create({
baseURL: "",
timeout: 600_000,
withCredentials: false,
paramsSerializer: params => qs.stringify(params, {arrayFormat: "repeat"})
});

const requestInterceptor = (config: RequestConfig) => {
// 在组件内调用http方法,pinia已经注册,故可以取到值
// 此处直接解构,因为每次都是取最新的数据,故不需要监听响应式变更
const {token} = useBaseStore();

if (qiankunWindow.__POWERED_BY_QIANKUN__) {
const queryList = window.location.href.split("?");
if (queryList.length > 1) {
queryList[1].split("&").forEach(i => {
if (i.indexOf("space") > -1) {
config.headers["Cbs-Space-Id"] = i.split("=")[1];
}
});
}
} else {
// 本地测试用的空间ID
config.headers["Cbs-Space-Id"] = 1;
}

if (token) {
config.headers.Authorization = token;
config.headers["Cbs-Token"] = token;
config.headers["X-Auth-AppId "] = "1";
}

// 语言
if (Lang === "zh-CN") {
config.headers["Accept-Language"] = "zh-CN";
} else if (Lang === "en") {
config.headers["Accept-Language"] = "en-US";
}
return config;
};

const responseInterceptor = (response: AxiosResponse) => {
const {data, config, status, request} =
response as AxiosResponse<ResponseWrapper>;
if (request.responseType === "blob" && status == 200) {
return data;
} else {
if (data?.code == 10000) {
// 此处不可直接写成data.data,否则拦截器会报ts错误
return response.data;
} else {
// 判断接口401,则跳转到SSO登录页,其他逻辑在组件内处理
// eslint-disable-next-line no-empty
if (data.code === 401) {
} else if (!(config as RequestConfig).silent && data.code !== 302) {
// 判断silent属性,是否message提示http错误
ElMessage({message: data?.sub_msg || data?.msg, type: "error"});
return data || {};
}
return Promise.reject(response);
}
}
};

const responseErrorHandler = (error: ResponseError) => {
const {response}: any = error as ResponseError;
ElMessage({
message: response
? `${response.status}:${
response.data.message || response.data || response.statusText
}${response.data.data || ""}`
: `${error.config?.url}:${error.message}`,
type: "error",
grouping: true
});
return {};
};

instance.interceptors.request.use(requestInterceptor);
instance.interceptors.response.use(responseInterceptor, responseErrorHandler);

// InternalAxiosRequestConfig 的 headers为必填,为避免ts报异常,故使用Partial取部分字段,则可不用必填headers,以下相同
export const get = async <T>(
url: string,
params?: object,
config?: Partial<RequestConfig>
): Promise<T> => {
return await instance.get(url, {
params,
...(config ?? {})
});
};

export const post = async <T>(
url: string,
data?: object,
config?: Partial<RequestConfig>
): Promise<T> => {
return await instance.post(url, data, config);
};

 


选择器联动封装:
<el-form class="search-panel" inline>
<searchMultiCondition
ref="queryFormRef"
:form-select="QUERY_FORM_SELECT"
:model="queryForm"
:remote-method="remoteMethod"
>
<el-form-item :label="$swpT('page.swModuleDetailPlan.packageName')" prop="codeRepoName">
<el-input
v-model="queryForm.codeRepoName"
:placeholder="$swpT('common.pleaseInput')"
@keyup.enter="getTableData"
></el-input>
</el-form-item>
<el-form-item
><i class="fa-search"/>
<el-button icon="search" type="primary" @click="getTableData">{{ $swpT('common.search') }}</el-button>
<el-button icon="refresh" @click="resetSearch()">{{ $swpT('common.reset') }}</el-button>
</el-form-item>
</searchMultiCondition>
</el-form>


联动封装vue页面:
<template>
<el-form ref="queryFormRef" class="search-panel" inline>
<el-form-item
v-for="item in props.formSelect"
:key="item.filed"
:label="item.label"
:prop="item.filed"
>
<el-select
v-model="attrs['model'][item.filed]"
:filter-method="(value) => filterChangeData(value, item.filed)"
v-bind="item.prop"
@change="getAllSelectOptions"
>
<el-option
v-for="(i, index) in queryOptions[item.filed]"
:key="index"
:label="i[item.optionsValueKey?.label || ''] ?? i"
:value="i[item.optionsValueKey?.value || ''] ?? i"
></el-option>
</el-select>
</el-form-item>
<slot></slot>
</el-form>
</template>

<script lang="ts" setup>
import {Res} from "@/types/global";
import {http} from "@/utils";
import {defineExpose, defineProps, onMounted, ref, useAttrs, withDefaults} from "vue";

const attrs = useAttrs(); // 使用 useAttrs 钩子获取 $attrs
const queryOptions = ref<any>({});
const props = withDefaults(defineProps<{ formSelect: any, remoteMethod: any }>(), {
formSelect: [],
remoteMethod: {}
});
const queryFormRef = ref();

onMounted(() => {
getAllSelectOptions();
});

const getAllSelectOptions = async(value: any, type: any, remote: boolean) => {
const {method, url} = props.remoteMethod;
const params = remote ? {
projectSearch: type === "project" ? value : "",
ecuSearch: type === "ecu" ? value : "",
nodeSearch: type === "node" ? value : "",
baselineSearch: type === "baseline" ? value : ""
} : {
...attrs["model"]
};
const {code, biz_content} = await http[method as "get" | "post"]<Res>(
url,
params
);
if (code == 10000) {
queryOptions.value = biz_content;
}
};

// 筛选filter值
const filterChangeData = async(value: any, type: any) => {
if (value) {
await getAllSelectOptions(value, type, true);
}
};

// 重置
const resetFields = () => {
queryFormRef.value.resetFields();
getAllSelectOptions();
};

defineExpose({
resetFields
});
</script>


标签:const,filed,value,element,item,import,封装,true,页面
From: https://www.cnblogs.com/nwy2012/p/18672431

相关文章

  • 封装按钮信息与按钮数量动态显示与提示信息并进行触发按钮组件
    标题:封装弹框并点击动态按钮组件进行触发功能:封装按钮信息与按钮数量动态显示组件页面:按钮信息与按钮数量动态显示,提示信息不固定封装组件页面: <template><el-dialogv-model="dialogVisible"class="stepCustom-dialogcustom-dialog-center"destroy-on-closeheight=......
  • 图表封装组件
    图表封装: 图表封装使用:<template><!--软件模块复用率图表--><chart-and-tableref="chartAndTableRef":chart-desc="chartDesc":chart-loading="chartLoading":columns="columns":list="list":......
  • 网站内容更新后,首页静态页面无法自动刷新
    您好,关于您提到的网站内容更新后,首页静态页面无法自动刷新的问题,我们将为您提供详细的解决方案。静态页面生成是许多内容管理系统(CMS)中常见的功能,确保每次更新内容后,首页能够及时反映最新的信息。以下是针对您使用织梦CMS的具体指导。分析问题原因缓存机制:您的服务器或浏览......
  • 微信小程序实现个人中心页面
    文章目录1.官方文档教程2.编写静态页面3.关于作者其它项目视频教程介绍1.官方文档教程https://developers.weixin.qq.com/miniprogram/dev/framework/2.编写静态页面mine.wxml布局文件<!--index.wxml--><navigation-bartitle="个人中心"back="{{false}}"......
  • PDF Automation文档页面自动化工具
    PDFAutomation是我用VB6开发的一个PDF文档页面自动化工具。电脑必须安装了AdobeAcrobat才能使用该工具。软件的主要功能包括:文档的拆分文档的合并页面的删除页面的移动页面的插入等。软件界面正中央的区域是文档列表,也就是多个PDF文档,最右侧是页面列表,显示当前所选文......
  • 封装,继承,多态
    在Java中,封装、继承和多态是面向对象编程(OOP)的三大核心特性。它们共同构成了面向对象编程的基础,帮助开发者编写出模块化、可重用和可扩展的代码。以下是它们的详细讲解:1. 封装(Encapsulation)定义封装是指将对象的属性和行为(方法)包装在一起,并对外隐藏内部实现细节,只暴露必......
  • 解除 网课失去焦点/离开页面 就自动暂停 的限制
    h5如果视频是video元素,可以写个定时器,每秒钟设置一下播放状态F12打开开发者工具,切换到console面板,输入下面代码并回车setInterval(function(){varcurrent_video=document.getElementsByTagName('video')[0]current_video.play()},1000)flash如果是flash视频,......
  • 解除 网课失去焦点/离开页面 就自动暂停 的限制
    h5如果视频是video元素,可以写个定时器,每秒钟设置一下播放状态F12打开开发者工具,切换到console面板,输入下面代码并回车setInterval(function(){varcurrent_video=document.getElementsByTagName('video')[0]current_video.play()},1000)flash如果是flash视......
  • 深度剖析RabbitMQ:从基础组件到管理页面详解
    文章目录一、简介二、Overview2.1Overview->Totals2.2Overview->Nodesbroker的属性2.3Overview->Churnstatistics2.4Overview->Portsandcontexts2.5Overview->Exportdefinitions2.6Overview->Importdefinitions三、Connections连接的属性四、Channels通道的......
  • 探秘 RabbitMQ 管理页面:关键板块与核心功能全解析
    文章目录一、简介二、Overview2.1Overview->Totals2.2Overview->Nodes2.3Overview->Churnstatistics2.4Overview->Portsandcontexts2.5Overview->Exportdefinitions2.6Overview->Importdefinitions三、Connections四、Channels五、Exchanges六、Queues七、Ad......