vue之動態表單(優化)

代碼資源在這兒 ↑

vue之動態表單優化

  • vue2+js動態表單優化
  • vue3+ts動態表單優化

vue2+js動態表單優化

效果圖
在這里插入圖片描述

目錄結構
在這里插入圖片描述
五個文件的完整代碼:

以下是App.vue

<template><div><router-view></router-view><Formpage /></div>
</template><script>
import Formpage from './views/FormPage.vue';export default {components: {Formpage},
}
</script>

以下是FormPage.vue

<template><div class="container"><FormItemComp :formState="root"></FormItemComp></div>
</template><script>
import FormItemComp from '../components/FormItemComp.vue';
import root from './FormPageDatas';export default {components: {FormItemComp},data() {return {root: root}}
}
</script><style scoped>
.container {width: 80%;margin: 1em auto;
}
</style>

以下是FormItemComp.vue

<template><el-form><template v-if="formState"><el-form-item :label="formState.payload.label"><template v-if="formState.type === 'input'"><el-input v-model="formState.payload.value"/></template><template v-else-if="formState.type === 'checkbox'"><el-checkbox-group v-model="formState.payload.value"><el-checkbox v-for="option in formState.payload.options" :key="option.value" :label="option.value">{{ option.label }}</el-checkbox></el-checkbox-group></template><template v-else-if="formState.type === 'radio'"><el-radio-group v-model="formState.payload.value"><el-radio v-for="option in formState.payload.options" :key="option.value" :label="option.value">{{ option.label }}</el-radio></el-radio-group></template><template v-else-if="formState.type === 'select'"><el-select v-model="formState.payload.value"><el-option v-for="option in formState.payload.options" :key="option.value" :label="option.label" :value="option.value"/></el-select></template></el-form-item><FormItemComp :form-state="getNext()"/></template></el-form>
</template><script>
export default {name: 'FormItemComp',props: {formState: {type: Object,default: null}},methods: {getNext() {let current = this.formState;if (!current) {return null;}const ancestors = [];ancestors.unshift(current);while ((current = current.parent)) {ancestors.unshift(current);}return this.formState.next(this.formState, ancestors);}}
}
</script><style scoped>
.el-form-item__label {padding-right: 10px !important;
}
</style>

以下是FormItem.js

import Vue from 'vue';/*** 創建表單項* @param formItemType string 表單項的類型* @param payload object 表單項的label、options、value* @param next function 當前選擇的值* @param parent 上一個表當項* @return {{next: ((function(*=, *=): (null|null))|*), parent: null, payload, type}}*/
export function createFormItem(formItemType, payload, next, parent) {if (!next) {next = () => null;}if (!parent) {parent = null;}const nextFunc = function(current, acients) {let nextItem = next(current, acients);if (!nextItem) {return null;}nextItem.parent = current;if (!Vue.observable(nextItem)) {nextItem = Vue.observable(nextItem);}return nextItem;};return Vue.observable({type: formItemType,payload: payload,next: nextFunc,parent: parent,});
}

以下是FormPageDatas.js

import {createFormItem} from '@/FormItem';const item1 = createFormItem('select',{label: 'test1',options: [{label: 'test1-1', value: 'test1-1'},{label: 'test1-2', value: 'test1-2'},{label: 'test1-3', value: 'test1-3'},],value: 'test1-1',},(current) => {if (current.payload.value === 'test1-2') {return item2;} else if (current.payload.value === 'test1-3') {return item4;} else {return null;}}
);const item2 = createFormItem('input', {label: 'test2',value: 'test'
}, (current) => (current.payload.value === 'test2' ? item3 : null));const item3 = createFormItem('checkbox',{label: 'test3',options: [{label: 'test3-1', value: 'test3-1'},{label: 'test3-2', value: 'test3-2'},{label: 'test3-3', value: 'test3-3'},],value: ['test3-2', 'test3-3'],},(current) => (current.payload.value.includes('test3-1') ? item4 : null)
);const item4 = createFormItem('radio', {label: 'test4',options: [{label: 'test4-1', value: 'test4-1'},{label: 'test4-2', value: 'test4-2'},{label: 'test4-3', value: 'test4-3'},{label: 'test4-4', value: 'test4-4'},],value: 'test4-4',
});export default item1;

vue3+ts動態表單優化

效果圖
在這里插入圖片描述

目錄結構
在這里插入圖片描述

五個文件的完整代碼:

以下是App.vue

<template><div><Formpage /></div>
</template><script setup lang="ts">
import Formpage from './views/Formpage.vue';
</script>

以下是FormPage.vue

<template><div class="container"><FormItemComp :form-state="root"></FormItemComp></div>
</template><script setup lang="ts">
import FormItemComp from '../components/FormItemComp.vue';
import root from './FormPageDatas';
</script><style scoped>
.container {width: 80%;margin: 1em auto;
}
</style>

以下是FormItemComp.vue

<template><template v-if="formState"><a-form-item :label="formState.payload.label"><template v-if="formState.type === 'input'"><a-input v-model:value="formState.payload.value" /></template><template v-else-if="formState.type === 'checkbox'"><a-checkbox-group v-model:value="formState.payload.value"><a-checkbox v-for="option in formState.payload.options" :value="option.value">{{ option.label }}</a-checkbox></a-checkbox-group></template><template v-else-if="formState.type === 'radio'"><a-radio-group v-model:value="formState.payload.value"><a-radio v-for="option in formState.payload.options" :value="option.value">{{ option.label }}</a-radio></a-radio-group></template><template v-else-if="formState.type === 'select'"><a-select v-model:value="formState.payload.value"><a-select-option v-for="option in formState.payload.options" :value="option.value">{{ option.label }}</a-select-option></a-select></template></a-form-item><FormItemComp :form-state="getNext()"></FormItemComp></template>
</template><script setup lang="ts">
import { FormItem } from '../FormItem';const props = defineProps<{formState: FormItem | null;
}>();function getNext(): FormItem | null {let current: FormItem | null = props.formState;if (!current) {return null;}const acients = [];acients.unshift(current);while ((current = current.parent)) {acients.unshift(current);}return props.formState!.next(props.formState!, acients);
}
</script><style>
.ant-form-item-label {padding-right: 10px !important;
}
</style>

以下是FormItem.ts

import { isReactive, reactive } from 'vue';export type FormItemType = 'input' | 'select' | 'checkbox' | 'radio';export interface FormItem {type: FormItemType;payload: any;next: (current: FormItem, acients: FormItem[]) => FormItem | null;parent: FormItem | null;
}export function createFormItem(formItemType: FormItem['type'],payload: FormItem['payload'],next?: FormItem['next'],parent?: FormItem['parent']
): FormItem {if (!next) {next = () => null;}if (!parent) {parent = null;}const nextFunc: FormItem['next'] = (current, acients) => {let nextItem = next!(current, acients);if (!nextItem) {return null;}nextItem.parent = current;if (!isReactive(nextItem)) {nextItem = reactive(nextItem);}return nextItem;};const formItem: FormItem = reactive({type: formItemType,payload,next: nextFunc,parent,});return formItem;
}

以下是FormPageDatas.ts

import { createFormItem } from '../FormItem';const item1 = createFormItem('select',{label: 'test1',options: [{ label: 'test1-1', value: 'test1-1' },{ label: 'test1-2', value: 'test1-2' },{ label: 'test1-3', value: 'test1-3' },],value: 'test1-1',},(current) => {if (current.payload.value === 'test1-2') {return item2;} else if (current.payload.value === 'test1-3') {return item4;} else {return null;}}
);const item2 = createFormItem('input',{ label: 'test2', value: 'test' },(current) => (current.payload.value === 'test2' ? item3 : null)
);const item3 = createFormItem('checkbox',{label: 'test3',options: [{ label: 'test3-1', value: 'test3-1' },{ label: 'test3-2', value: 'test3-2' },{ label: 'test3-3', value: 'test3-3' },],value: ['test3-2', 'test3-3'],},(current) => (current.payload.value.includes('test3-1') ? item4 : null)
);const item4 = createFormItem('radio', {label: 'test4',options: [{ label: 'test4-1', value: 'test4-1' },{ label: 'test4-2', value: 'test4-2' },{ label: 'test4-3', value: 'test4-3' },{ label: 'test4-4', value: 'test4-4' },],value: 'test4-4',
});export default item1;

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/41263.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/41263.shtml
英文地址,請注明出處:http://en.pswp.cn/news/41263.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【LeetCode】647.回文子串

題目 給你一個字符串 s &#xff0c;請你統計并返回這個字符串中 回文子串 的數目。 回文字符串 是正著讀和倒過來讀一樣的字符串。 子字符串 是字符串中的由連續字符組成的一個序列。 具有不同開始位置或結束位置的子串&#xff0c;即使是由相同的字符組成&#xff0c;也會…

web連接桌面打開gptmap

一&#xff1a;環境配置 需要的材料&#xff1a; python-3.10.4 我使用的是這個版本的&#xff0c;3.8.10 該版本和以下版本組件組合&#xff0c;驗證過能正常運行&#xff08;python 3.6.8測試異常&#xff09; websockify 該項目有python版本和node js版本 noVNC 形式的app…

Qt Designer設計的界面如何顯示、即運行顯示窗口界面

首先利用Qt Designer設計.ui文件&#xff0c;然后采用Tools->External Tools->PyUIC轉換成.py文件。這個.py文件是.ui文件編譯而來的&#xff0c;將這種文件由.ui文件編譯而來的.py文件稱之為界面文件。由于界面文件每次編譯時候都會初始化&#xff0c;所以需要新建一個.…

Android 13 添加自定義分區,恢復出廠設置不被清除

需求: 客戶有些文件或數據,需要做得恢復出廠設置還存在,故需新增一個分區存儲客戶數據。 要求: a) 分區大小為50M b) 應用層可讀可寫 c) 恢復出廠設置后不會被清除 d) 不需要打包.img e) 不影響OTA升級 缺點: 1).通過代碼在分區創建目錄和文件,會涉及到SeLinux權限的修…

● 123.買賣股票的最佳時機III ● 188.買賣股票的最佳時機IV

123.買賣股票的最佳時機III class Solution { public:int maxProfit(vector<int>& prices) {vector<vector<int>>dp(prices.size(),vector<int>(5));int lenprices.size();if(len0)return 0;dp[0][0]0;dp[0][1]-prices[0];dp[0][2]0;dp[0][3]-pr…

LeetCode150道面試經典題-- 環形鏈表(簡單)

1.題目 給你一個鏈表的頭節點 head &#xff0c;判斷鏈表中是否有環。 如果鏈表中有某個節點&#xff0c;可以通過連續跟蹤 next 指針再次到達&#xff0c;則鏈表中存在環。 為了表示給定鏈表中的環&#xff0c;評測系統內部使用整數 pos 來表示鏈表尾連接到鏈表中的位置&…

Java設計模式 (一) 模板方法設計模式

什么是模板方法設計模式? 模板方法設計模式是一種行為型設計模式&#xff0c;它定義了一個算法的骨架&#xff0c;并將一些步驟的具體實現延遲到子類中。模板方法模式可以幫助確保在算法的不同部分中保持一致性&#xff0c;同時也允許子類根據需要進行具體實現。 模板方法模式…

分布式光伏運維平臺在公益場館屋頂光伏發電系統的應用分析

摘要&#xff1a;2021年9月&#xff0c;國家發改委印發烷善能源消費強度和總量雙控制度方案》&#xff0c;提出鼓勵可再生能源的使用&#xff0c;支持可再生能源發展。在這樣的政策推動下&#xff0c;光伏發電市場無疑將迎來高質量發展的新機遇。現結合山東博物館光伏電站日常管…

系統架構設計師---計算機基礎知識之數據庫系統結構與規范化

目錄 一、基本概念 二、 數據庫的結構 三、常用的數據模型 概念數據模型

git add 用法

git add 是 Git 的一個命令&#xff0c;用于將更改的文件加入到暫存區&#xff08;staging area&#xff09;&#xff0c;準備提交這些更改。以下是該命令的常見用法&#xff1a; 添加單個文件 git add 文件名添加多個文件 git add 文件名1 文件名2 ...添加所有當前目錄下的更改…

面試攻略,Java 基礎面試 100 問(十八)

JAVA IO 包 JAVA NIO NIO 主要有三大核心部分&#xff1a;Channel(通道)&#xff0c;Buffer(緩沖區), Selector。 傳統 IO 基于字節流和字 符流進行操作&#xff0c;而 NIO 基于 Channel 和 Buffer(緩沖區)進行操作&#xff0c;數據總是從通道讀取到緩沖區 中&#xff0c;或者…

Linux命令(70)之bzip2

linux命令之bzip2 1.bzip2介紹 linux命令bzip2是用來壓縮或解壓縮文件名后綴為".bz2"的文件 2.bzip2用法 bzip2 [參數] filename bzip2常用參數 參數說明-d解壓縮文件-t測試壓縮文件是否正確-k壓縮后&#xff0c;保留源文件-z強制壓縮-f強制覆蓋已存在的文件-v顯…

TRT8系列—— 版本差異注意事項

TRT8 一個大版本&#xff0c;8.4-、 8.5、 8.6&#xff08;包含預覽功能&#xff09;卻有很多變動&#xff0c;一不注意就發現很混亂&#xff0c;特備注此貼。建議具體case可以參考這個合集&#xff0c;真心安利&#xff1a;https://github.com/NVIDIA/trt-samples-for-hackath…

Go語言GIN框架安裝與入門

Go語言GIN框架安裝與入門 文章目錄 Go語言GIN框架安裝與入門1. 創建配置環境2. 配置環境3. 下載最新版本Gin4. 編寫第一個接口5. 靜態頁面和資源文件加載6. 各種傳參方式6.1 URL傳參6.2 路由形式傳參6.3 前端給后端傳遞JSON格式6.4 表單形式傳參 7. 路由和路由組8. 項目代碼mai…

GaussDB 實驗篇+openGauss的4種1級分區案例

? 范圍分區/range分區 -- 創建表 drop table if exists zzt.par_range; create table if not exists zzt.par_range (empno integer,ename char(10),job char(9),mgr integer(4),hiredate date,sal numeric(7,2),comm numeric(7,2),deptno integer,constraint pk_par_emp pri…

除自身以外數組的乘積(c語言詳解)

題目&#xff1a;除自身外數組的乘積 給你一個整數數組 nums&#xff0c;返回 數組 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘積 。 題目數據保證數組 nums之中任意元素的全部前綴元素和后綴的乘積都在 32 位 整數范圍內。 請不要使用除…

Android Studio實現解析HTML獲取圖片URL,將URL存到list,進行瀑布流展示

目錄 效果展示build.gradle(app)添加的依賴(用不上的可以不加)AndroidManifest.xml錯誤代碼activity_main.xmlitem_image.xmlMainActivityImage適配器ImageModel 接收圖片URL效果展示 build.gradle(app)添加的依賴(用不上的可以不加) dependencies {implementation co…

Android 13 像Settings一樣開啟關閉深色模式

一.背景 由于客戶定制的Settings需要開啟關閉深色模式,所以需要自己調用開啟關閉深色模式 二.前提條件 首先應用肯定要是系統應用,并且導入framework.jar包,具體可以參考: Android 應用自動開啟輔助(無障礙)功能并使用輔助(無障礙)功能_android 自動開啟無障礙服務_龔禮鵬…

Java版電子招投標管理系統源碼-電子招投標認證服務平臺-權威認證 tbms

? 功能描述 1、門戶管理&#xff1a;所有用戶可在門戶頁面查看所有的公告信息及相關的通知信息。主要板塊包含&#xff1a;招標公告、非招標公告、系統通知、政策法規。 2、立項管理&#xff1a;企業用戶可對需要采購的項目進行立項申請&#xff0c;并提交審批&#xff0c;…

Neo4j之CREATE基礎

在 Neo4j 中&#xff0c;CREATE 語句用于創建節點、關系以及節點屬性。 創建節點&#xff1a; CREATE (p:Person {name: John, age: 30});這個查詢會創建一個具有 "Person" 標簽的節點&#xff0c;節點屬性包括 "name" 和 "age"。 創建帶有關…