model
: 绑定整个表单model值
rules
: 整个表单校验规则
ref
:获取该表单form组件
prop
: 绑定每个表单的规则,写在el-form-item
上
validate
: 对整个表单进行校验的方法
valid
: 每个必填表单项都提交为true,否则为false
//使用element-ui 页面组件 <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm"> <el-form-item label="活动名称" prop="name"> <el-input v-model="ruleForm.name"></el-input> </el-form-item> <el-form-item label="活动区域" prop="region"> <el-select v-model="ruleForm.region" placeholder="请选择活动区域"> <el-option label="区域一" value="shanghai"></el-option> <el-option label="区域二" value="beijing"></el-option> </el-select> </el-form-item> </el-form> <el-form-item> <el-button type="primary" @click="submitForm('ruleForm')">立即创建</el-button> </el-form-item> //data中定义form表单中每项表单model值、和每个表单校验的规则 <script> export default { data() { return { ruleForm: { name: '', region: '', }, rules: { name: [ { required: true, message: '请输入活动名称', trigger: 'blur' }, { min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' } ], region: [ { required: true, message: '请选择活动区域', trigger: 'change' } ], }; }, //定义表单提交方法 methods: { submitForm(formName) { this.$refs[formName].validate((valid) => { if (valid) { alert('submit!'); } else { console.log('error submit!!'); return false; } }); }, } }
<el-form v-if="fromHtmlList.deviceInfo.sitsb.length" :model="fasj" :rules="rules" label-position="left" label-width="125px" ref='sitsb'> <el-form-item label-width="100%" > <div slot="label" class="titleInfo">局端设备</div> </el-form-item> <el-form-item v-for="(item, i) in fromHtmlList.deviceInfo.sitsb" :key="`F_key_${i}`" :label="`${item.label}:`" :class="item.class" :label-width="item.labelWidth" :prop="`${item.rule ? 'deviceInfo.sitsb.'+item.rule : ''}`"> <el-select v-if="item.el === 'slt'" v-model="fasj.deviceInfo.sitsb[item.model]" placeholder="请选择" style="width:200px;" clearable> <el-option v-for="(op, n) in options[item.option]" :key="`vop_key_${n}`" :label="op.label" :value="op.value"> </el-option> </el-select> <el-input v-if="item.el === 'ipt'" v-model="fasj.deviceInfo.sitsb[item.model]" @focus="()=>{ item.focus && handleFocus('sitsb', item.model)}" :placeholder="`${item.placeholder ? item.placeholder : '请输入'}`" style="width:200px;"></el-input> <span v-if="item.el === 'txt'">{{fasj.base[item.model]}}</span> </el-form-item> </el-form> <div class="btn-list"> <el-button type="primary" @click="checkRequired">提 交</el-button> </div> <script> export default { data() { return { fasj: { base: {}, // 基本信息 deviceInfo: {}, }, //定义 页面表单结构 fromHtmlList: { baseInfo: [], deviceInfo: { ywzsb: [], sitsb: [] } }, //定义 表单校验规则 rules: { 'deviceInfo.sitsb.IPType': [ { required: true, message: '请输入', trigger: 'blur' } ], 'deviceInfo.sitsb.IPAddr': [ { required: true, message: '请输入', trigger: 'blur' } ], 'deviceInfo.sitsb.netmask': [ { required: true, message: '请输入', trigger: 'blur' } ], 'deviceInfo.sitsb.vlanId': [ { required: true, message: '请输入', trigger: 'blur' } ], }, options: { IPType: [ {label: 'ipv4', value: 'ipv4'}, {label: 'ipv6', value: 'ipv6'} ], rmSite: [], room: [], }, } }, created(){ const orderType = '业务开通' ;//页面初始加载用到的变量值,可通过组件传值获取 //created中初始定义页面表单结构 this.fromHtmlList = { baseInfo: orderType === '业务开通' ? [ {label: '接入方式', labelWidth: '100px', rule: '' , model: 'serviceType', option: '', el: 'txt', class: 'w2'}, {label: '标准九级地址', labelWidth: '120px', rule: '', model: 'aendAdreesName', option: '', el: 'txt', class: 'w2'}, {label: '城乡类型', labelWidth: '100px', rule: 'cityType', model: 'cityType', option: 'cityType', el: 'slt', class: 'w2'}, {label: '方案设计附件', labelWidth: '120px', rule: '', model: 'fileId', option: '', el: 'btn', class: 'w2'}, ] : orderType === '移机' ? [ {label: '接入方式', labelWidth: '100px', rule: '' , model: 'serviceType', option: '', el: 'txt', class: 'w2'}, {label: '标准九级地址', labelWidth: '120px', rule: '', model: 'aendAdreesName', option: '', el: 'txt', class: 'w2'}, {label: '城乡类型', labelWidth: '100px', rule: 'cityType', model: 'cityType', option: 'cityType', el: 'slt', class: 'w2'}, {label: '方案设计附件', labelWidth: '120px', rule: '', model: 'fileId', option: '', el: 'btn', class: 'w2'}, {label: '移机场景', labelWidth: '100px', rule: 'moveScene', model: 'moveScene', option: 'moveScene', el: 'slt', class: 'w2'}, {label: '是否需要网络调整', labelWidth: '', rule: 'netChange', model: 'netChange', option: 'netChange', el: 'slt', class: 'w2'} ] : [ {label: '接入方式', labelWidth: '100px', rule: '' , model: 'serviceType', option: '', el: 'txt', class: 'w2'}, {label: '标准九级地址', labelWidth: '120px', rule: '', model: 'aendAdreesName', option: '', el: 'txt', class: 'w2'}, {label: '城乡类型', labelWidth: '100px', rule: 'cityType', model: 'cityType', option: 'cityType', el: 'slt', class: 'w2'}, {label: '方案设计附件', labelWidth: '120px', rule: '', model: 'fileId', option: '', el: 'btn', class: 'w2'}, {label: '是否需要网络调整', labelWidth: '', rule: 'netChange', model: 'netChange', option: 'netChange', el: 'slt', class: 'w2'}, {label: '是否更换末端设备', labelWidth: '', rule: 'devChange', model: 'devChange', option: 'devChange', el: 'slt', class: 'w2'} ], deviceInfo: { ywzsb: serviceType === 'PON' ? [ // 默认PON {label: '机房', labelWidth: '90px', rule: '' , model: 'siteRoom', option: '', el: 'ipt', class: 'w2', focus: true, placeholder: '点击查询'}, {label: '设备名称', labelWidth: '90px', rule: '', model: 'deviceName', option: '', el: 'ipt', class: 'w2', focus: true, placeholder: '点击查询'}, {label: '设备端口', labelWidth: '90px', rule: '', model: 'devicePort', option: '', el: 'ipt', class: 'w2', focus: true, placeholder: '点击查询'}, {label: '延伸设备', labelWidth: '90px', rule: '', model: 'deviceExtend', option: '', el: 'ipt', class: 'w2', focus: true, placeholder: '点击查询'} ] : [ // 裸光纤、传输下沉、传输延伸(ywzsb) {label: '机房', labelWidth: '', rule: '' , model: 'siteRoom', option: '', el: 'ipt', class: 'w2', focus: true, placeholder: '点击查询'}, {label: '站点', labelWidth: '', rule: '', model: 'site', option: '', el: 'ipt', class: 'w2'}, {label: '设备名称', labelWidth: '', rule: '', model: 'deviceName', option: '', el: 'ipt', class: 'w2', focus: true, placeholder: '点击查询'}, {label: '设备端口', labelWidth: '', rule: '', model: 'devicePort', option: '', el: 'ipt', class: 'w2', focus: true, placeholder: '点击查询'}, ], sitsb: serviceType === 'PON' ? [ {label: '机房名称', labelWidth: '', rule: '' , model: 'siteRoom', option: '', el: 'ipt', class: 'w2'}, {label: '站点名称', labelWidth: '', rule: '', model: 'site', option: '', el: 'ipt', class: 'w2'}, {label: '汇聚交换机', labelWidth: '', rule: '', model: 'switch', option: '', el: 'ipt', class: 'w2'}, {label: '汇聚交换机端口', labelWidth: '', rule: '', model: 'switchPort', option: '', el: 'ipt', class: 'w2'}, {label: 'SR/BARS', labelWidth: '', rule: '' , model: 'srbars', option: '', el: 'ipt', class: 'w2'}, {label: 'SR/BARS端口', labelWidth: '', rule: '', model: 'srbarsPort', option: '', el: 'ipt', class: 'w2'}, {label: 'IP地址类型', labelWidth: '', rule: 'IPType', model: 'IPType', option: 'IPType', el: 'slt', class: 'w2'}, {label: 'IP地址', labelWidth: '', rule: 'IPAddr', model: 'IPAddr', option: '', el: 'ipt', class: 'w2'}, {label: '子网掩码', labelWidth: '', rule: 'netmask', model: 'netmask', option: '', el: 'ipt', class: 'w2'}, {label: 'VLAN ID', labelWidth: '', rule: 'vlanId', model: 'vlanId', option: '', el: 'ipt', class: 'w2'} ] : serviceType === '裸光纤' ? [ // 裸光纤 {label: '机房名称', labelWidth: '', rule: '' , model: 'siteRoom', option: '', el: 'ipt', class: 'w2', focus: true, placeholder: '点击查询'}, {label: '站点名称', labelWidth: '', rule: '', model: 'site', option: '', el: 'ipt', class: 'w2'}, {label: 'SR', labelWidth: '', rule: '', model: 'SR', option: '', el: 'ipt', class: 'w2', focus: true, placeholder: '点击查询'}, {label: 'SR端口', labelWidth: '', rule: '', model: 'SRPort', option: '', el: 'ipt', class: 'w2', focus: true, placeholder: '点击查询'}, {label: 'BARS', labelWidth: '', rule: '' , model: 'BARS', option: '', el: 'ipt', class: 'w2', focus: true, placeholder: '点击查询'}, {label: 'BARS端口', labelWidth: '', rule: '', model: 'BARSPort', option: '', el: 'ipt', class: 'w2', focus: true, placeholder: '点击查询'}, ] : [ // 传输下沉、传输延伸 ] } } }, methods:{ async checkRequired() { let checkName = ['base','sitsb'];//表单校验定义ref let text; for(let key of checkName){ if(this.$refs[key]){ this.$refs[key].validate((valid) => { if(!valid){ text = '请检查必填项'; }else { return false; } }); } } if(text){ this.$message.warning(text); return false; } let _res_ = await this.saveFasjData('', true);//页面表单要保存后才能提交 if(!!_res_ && _res_.code === 200){ this.commit(_param, _url);//保存表单再提交 }else{ this.$message.error(_res_.msg) } }, async commit(param, url) { this.loadings.body = true; let _res = await postDataRequest(url, param); this.loadings.body = false; if (_res && _res.code === 200) { this.$message.success("提交成功"); this.$router.go(-1); } } } } </script>
分享此文一切功德,皆悉回向给文章原作者及众读者.
免责声明:蓝蓝设计尊重原作者,文章的版权归原作者。如涉及版权问题,请及时与我们取得联系,我们立即更正或删除。
蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 、平面设计服务、UI设计公司、界面设计公司、UI设计服务公司、数据可视化设计公司、UI交互设计公司、高端网站设计公司、UI咨询、用户体验公司、软件界面设计公司
Vite 是 vue 的作者尤雨溪在开发 vue3.0 的时候开发的一个 web 开发构建工具。由于其原生 ES 模块导入方式,可以实现闪电般的冷服务器启动。
Vite 优势:
Vite 劣势:
其他区别:
1. 打包原理的区别
2. 项目入口文件的区别
项目根目录的 index.html 是 Vite 项目的入口文件,而 webpack 的入口文件是 webpack 配置 entry 中指定的 js 文件。
Esbuild
是一款基于 Go
语言开发的 javascript
打包工具,最大的一个特征就是快。
通过官网提供的一张图,我们可以清晰的看到 Esbuild
的表现是多么优秀:
Esbuild
之所以能这么快,主要原因有两个:
Go
语言开发,可以多线程打包,代码直接编译成机器码;
Webpack
一直被人诟病构建速度慢,主要原因是在打包构建过程中,存在大量的 resolve
、load
、transform
、parse
操作(详见 为什么有人说 vite 快,有人却说 vite 慢?- 快速的冷启动 ),而这些操作通常是通过 javascript
代码来执行的。要知道,javascript
并不是什么高效的语言,在执行过程中要先编译后执行,还是单线程并且不能利用多核 cpu
优势,和 Go
语言相比,效率很低。
可充分利用多核 cpu
优势;
关键 API - transfrom & build
Esbuild
并不复杂,它对外提供了两个 API:
transform
和 build
,使用起来非常简单。
transfrom
,转换的意思,将 ts
、jsx
、tsx
等格式的内容转化为 js
。 transfrom
只负责文件内容转换,并不会生成一个新的文件。
build
,构建的意思,根据指定的单个或者多个入口,分析依赖,并使用 loader
将不同格式的内容转化为 js 内容,生成一个或多个 bundle
文件。
我们来看看Vite
是怎么利用 Esbuild
来做预构建和内容转换的。
预构建
为什么要做预构建?原因有两点:
将非 ESM
规范的代码转换为符合 ESM
规范的代码;
将第三方依赖内部的多个文件合并为一个,减少 http
请求数量;
middlewares 中内容转换
Vite
中源文件的转换是在 dev server
启动以后通过 middlewares
实现的。
当浏览器发起请求以后,dev sever
会通过相应的 middlewares
对请求做处理,然后将处理以后的内容返回给浏览器。
middlewares
对源文件的处理,分为 resolve
、load
、transform
、parser
四个过程:
resolve
- 解析 url
,找到源文件的绝对路径;
load
- 加载源文件。如果是第三方依赖,直接将预构建内容返回给浏览器;如果是业务代码,继续 transform
、parser
。
transfrom
- 对源文件内容做转换,即 ts
-> js
, less
-> css
等。转换完成的内容可以直接返回给浏览器了。
parser
- 对转换以后的内容做分析,找到依赖模块,对依赖模块做预转换 - pre transform
操作,即重复 1
- 4
。
pre transform
是 Vite
做的一个优化点。预转换的内容会先做缓存,等浏览器发起请求以后,如果已经完成转换,直接将缓存的内容返回给浏览器。
Vite
在处理步骤 3
时,是通过 esbuild.transform
实现的,对比 Webpack
使用各个 loader
处理源文件,那是非常简单、快捷的。
经验法则:对于应用使用 webpack,对于类库使用 Rollup。
如果你需要代码拆分(Code Splitting),或者你有很多静态资源需要处理,再或者你构建的项目需要引入很多CommonJS模块的依赖,那么 webpack 是个很不错的选择。
如果您的代码库是基于 ES2015 模块的,而且希望你写的代码能够被其他人直接使用,你需要的打包工具可能是 Rollup 。
分享此文一切功德,皆悉回向给文章原作者及众读者.
免责声明:蓝蓝设计尊重原作者,文章的版权归原作者。如涉及版权问题,请及时与我们取得联系,我们立即更正或删除。
蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 、平面设计服务、UI设计公司、界面设计公司、UI设计服务公司、数据可视化设计公司、UI交互设计公司、高端网站设计公司、UI咨询、用户体验公司、软件界面设计公司
蓝蓝设计的小编 http://www.lanlanwork.com