Vue表單快速上手
普通表單
我們先可以創(chuàng)建一個(gè)普通的表單,我們知道的是表單是相對(duì)比較復(fù)雜的,antv被我們?cè)嵅榫褪瞧浔韱?,這個(gè)設(shè)計(jì)出來(lái)的理念就是和別的組件庫(kù)不一樣,我們就在這篇文章分成四個(gè)部分來(lái)講述,現(xiàn)在我們的第一個(gè)部分,就是我們的普通的表單。
操作的步驟:先再main.js引入注冊(cè)Form和Input,在BasicForm拷貝剛才的表單布局,這個(gè)就是最基礎(chǔ)的表單。接下來(lái)就是需要添加一個(gè)錯(cuò)誤校驗(yàn),有對(duì)應(yīng)的屬性傳遞對(duì)應(yīng)的狀態(tài)等??截恦alidateStatus到item中加上對(duì)應(yīng)的help文本,如果想要?jiǎng)討B(tài)輸入的話也可以,給input雙向綁定fieldA和fieldB,在data里面注冊(cè)這兩個(gè)值,同時(shí)validateStatus也變成動(dòng)態(tài)的指向fieldAStatus,文本也是動(dòng)態(tài)指向fieldAHelp。通過(guò)監(jiān)聽(tīng)fieldA的長(zhǎng)度,如果小于5改變狀態(tài)和文本,否則就都置為空就行了。同樣的,給按鈕也綁定一個(gè)事件handleSubmit,拷貝剛才的監(jiān)聽(tīng)邏輯,如果通過(guò)就console.log輸出一下。

如此就完成了一個(gè)最簡(jiǎn)單的表單校驗(yàn),像這種手動(dòng)添加錯(cuò)誤校驗(yàn)信息是最靈活簡(jiǎn)單但是不夠漸變,最好是組件內(nèi)部自動(dòng)校驗(yàn)。
<!--登錄表單區(qū)域-->
<el-form ref="loginFormRef" :model="loginForm" :rules="loginFormRules" label-width="0px" class="login_form">
<!--用戶(hù)名-->
<el-form-item prop="username">
<el-input v-model="loginForm.username" prefix-icon="el-icon-user"></el-input>
</el-form-item>
<!--密碼-->
<el-form-item prop="password">
<el-input v-model="loginForm.password" prefix-icon="el-icon-lock" type="password"></el-input>
<!--type="password使得密碼隱藏"-->
</el-form-item>
<!--按鈕區(qū)域-->
<el-form-item class="btns">
<el-button type="primary" @click="login">mua</el-button>
<el-button type="info" @click="resetLoginForm">重置</el-button>
</el-form-item>
</el-form><script>
export default {
data () {
return {
// 這里是登錄表單數(shù)據(jù)
loginForm: {
username: 'admin',
password: '991130'
},
// 表單的驗(yàn)證規(guī)則對(duì)象
loginFormRules: {
username: [
{ required: true, message: '請(qǐng)輸入登錄名稱(chēng)', trigger: 'blur' },
{ min: 3, max: 10, message: '長(zhǎng)度在 3 到 10 個(gè)字符', trigger: 'blur' }
],
password: [
{ required: true, message: '請(qǐng)輸入登錄密碼', trigger: 'blur' },
{ min: 6, max: 15, message: '長(zhǎng)度在 6 到 15 個(gè)字符', trigger: 'blur' }
]
}
}
},
// 點(diǎn)擊重置按鈕,重置登錄表單
methods: {
resetLoginForm () {
// console.log(this)
this.$refs.loginFormRef.resetFields()
},
login () {
this.$refs.loginFormRef.validate(async valid => {
if (!valid) return
const { data: res } = await this.$http.post('login', this.loginForm)
if (res.meta.status !== 200) return this.$message.error('登錄失?。?)
this.$message.success('登錄成功')
// 1.將登陸成功之后的token,保存到客戶(hù)端的sessionstorage中
// 1.1項(xiàng)目中除了登錄之外的其他api接口,必須在登陸之后才能訪問(wèn)
// 1.2token只應(yīng)在當(dāng)前網(wǎng)站打開(kāi)期間生效,所以將token保存在sessionstorage中
window.sessionStorage.setItem('token', res.data.token)
// 2.通過(guò)編程式導(dǎo)航跳轉(zhuǎn)到后臺(tái)主頁(yè),路由地址為/home
this.$router.push('home')
})
}
}
}
</script>初始數(shù)據(jù)與自動(dòng)校驗(yàn)與動(dòng)態(tài)賦值
目前表單方案主要有兩種,一種是基于雙向綁定的表單校驗(yàn)(iviewelement)另一種就是ant。數(shù)據(jù)加規(guī)則映射到表單視圖,通過(guò)雙向綁定在表單變化的時(shí)候繼續(xù)同步到數(shù)據(jù)中對(duì)比規(guī)則,這個(gè)是理想情況。但是很經(jīng)常是多個(gè)地方使用一個(gè)數(shù)據(jù),使用雙向綁定的話可以實(shí)現(xiàn)表單與其它數(shù)據(jù)一起修改,這可能是想要的,但是也有可能是我們希望表單數(shù)據(jù)提交后經(jīng)過(guò)后臺(tái)等等最后返回出來(lái)的數(shù)據(jù)再進(jìn)行展示,對(duì)這種情況我們就需要復(fù)制或者深復(fù)制一份數(shù)據(jù),這個(gè)就是雙向綁定的模型。Ant選擇把所有數(shù)據(jù)放到表單,data只是提供一個(gè)初始化,后面表單就是一個(gè)黑盒,里面處理的不會(huì)影響外面的數(shù)據(jù),后續(xù)數(shù)據(jù)如果需要同步到data就可以通過(guò)API來(lái)同步到data和其它組件等等。




回到form,在data里面實(shí)例化一個(gè)from(因?yàn)閙ain中有use自動(dòng)把$from掛載到vue實(shí)例上,所以就可以訪問(wèn)到),同時(shí)把this進(jìn)去(用于組件底層內(nèi)部,數(shù)據(jù)改變時(shí)調(diào)用這個(gè)this來(lái)更新當(dāng)前組件也就是basicForm)。把這個(gè)實(shí)例傳遞到最外層那,如此就不需要手動(dòng)監(jiān)聽(tīng)、雙向綁定和watch監(jiān)聽(tīng)了。給input綁定一個(gè)v-decorator,接收數(shù)組,第一個(gè)是字段名稱(chēng)、第二個(gè)是配對(duì)的規(guī)則(required是否必須,min最小長(zhǎng)度,message報(bào)錯(cuò)信息)、第三個(gè)是初始值的字段。v-decorator的源碼如下,可以看到什么都沒(méi)做,僅僅是提供一個(gè)標(biāo)志位,也就是當(dāng)我們渲染我們的item時(shí),會(huì)查找子組件,如果帶有這個(gè)標(biāo)志位就會(huì)劫持然后交由我們的from去控制
export function antDecorator(Vue) {
return Vue.directive('decorator',{});
}
export default {
//
install: Vue =>{
antDecorator(Vue);
}
}按鈕的點(diǎn)擊事件也要改一下,通過(guò)form的validateFields,接收err錯(cuò)誤信息和values接收到的值,如果沒(méi)有err說(shuō)明校驗(yàn)通過(guò)。如此就實(shí)現(xiàn)了自動(dòng)校驗(yàn)。接下來(lái)我們想要數(shù)據(jù)改變后同步給data里面的fieldA和fieldB(即后臺(tái)校驗(yàn)通過(guò)后),我們當(dāng)然可以一個(gè)個(gè)賦值,也可以通過(guò)Object.assign往this上賦值即可。如果想通過(guò)接口動(dòng)態(tài)改變表單的值也可以通過(guò)form的setFieldsValueAPI來(lái)動(dòng)態(tài)改變其值,值得注意的是初始化的數(shù)據(jù)只是在第一次生效,后續(xù)改變都要通過(guò)這個(gè)API。
handleSubmit(){
this.form.validateFields((err,value)=> {
if(!err) {
console.log(values);
object.assign(this,values)//全部賦值
}
}
}data() {
this.form = this.$form.createForm(this)//初始化一個(gè)表單
return {
formLauout:'horizontal',
fieldA:'hello',
fieldB:''
};
}
mounted () {
setTimeout(() = >{ //定時(shí)改變一次舒適化改變
this.form.setFieldsValue({ fieldA:'byebye'})
},3000)
},發(fā)布表單
結(jié)合vuex和vue-router,建一個(gè)store文件夾在其下面建modules文件夾,下面再建一個(gè)form.js,導(dǎo)入router、request,定義一個(gè)state對(duì)象,下包含step對(duì)象里面只有payAccount即可。定義一個(gè)actions對(duì)象,下面一個(gè)異步的submitStepForm接收{(diào)commit}和{payload},調(diào)用request請(qǐng)求,url是‘/api/form’,方式是post,數(shù)據(jù)是payload,返回請(qǐng)求后我們commit一個(gè)mutation,命名為saveStepFormData,把payload傳過(guò)去,然后路由跳轉(zhuǎn)到‘formep-form/result’結(jié)果頁(yè)。
定義一個(gè)mutations對(duì)象,saveStepFormData接收state和{payload},我們要在里面改變state里面的step值(拓展運(yùn)算符攤開(kāi)step和payload,因?yàn)槔碚撋鲜怯泻芏嗟臄?shù)據(jù))。最后是暴露出這三個(gè)對(duì)象(同時(shí)開(kāi)啟命名空間?。┰趕tore下面再建一個(gè)文件index.js,導(dǎo)入剛才的form.js,在實(shí)例化中加一個(gè)modules對(duì)象,里面丟個(gè)form,如此就完成了store,不過(guò)需要注意的是外面還有一個(gè)store.js(無(wú)用可以刪),而之前的mian.js默認(rèn)是找到這個(gè)store.js(原本是找到剛才新建的index,被外面這個(gè)攔住了),可能會(huì)報(bào)錯(cuò),重啟工程或者指明更清楚的路徑就行。
既然定義了API就往mock里面加多一個(gè)form.js,修改方法為POST,返回?cái)?shù)據(jù)為message即可。接下來(lái)就是正式寫(xiě)表單了,首先是第一個(gè)表單Step1,手寫(xiě)
一個(gè)a-form指定為horizontal,item的label為付款賬戶(hù)。往data里面丟一個(gè)布局配置formItemLayout對(duì)象,里面設(shè)置labelCol和wrapperCol,當(dāng)然我們還需要在外面創(chuàng)建一個(gè)form實(shí)例指向當(dāng)前的form,item的labelCol也指向?qū)ο蟮膌abelCol,wrapperCol也指定一下。再加一個(gè)a-input,指定decorator,名稱(chēng)為payAccount,初始化值需要從vuex中?。梢岳糜?jì)算屬性拿到),規(guī)則是必填否則報(bào)錯(cuò)誤提示。再來(lái)一個(gè)item,里面放button,type為primary,觸發(fā)點(diǎn)擊事件handleSubmit,在方法中定義,先從this中拿到form、$router、$store就不用一個(gè)個(gè)this.,再調(diào)用form的validateFields校驗(yàn)一下,無(wú)錯(cuò)則提交給vuex的store,直接commit而不是dispatch,因?yàn)榈谝徊綗o(wú)需異步,只是儲(chǔ)存數(shù)據(jù)到step字段,給個(gè)type和payload(傳遞values字段),完成后router跳轉(zhuǎn)到第二步(/formep-form-confirm),如此就完成了第一步的表單。接下來(lái)開(kāi)發(fā)這個(gè)第二步的表單,復(fù)制第一步的,把input刪除了,這一步就是要顯示這個(gè)付款賬戶(hù)的{{step.payAccount}},再來(lái)個(gè)item,里面放input用來(lái)輸入密碼,type改為password,下一個(gè)item中加多一個(gè)button為提交,另一個(gè)改為上一步,分別綁定handleSubmit和onPrev兩個(gè)事件,上一步的按鈕給個(gè)樣式(margin-left讓它們兩個(gè)有點(diǎn)距離)。onPrev的話是
將路由跳轉(zhuǎn)到‘/formep-form/info’,提交事件的話就是通過(guò)dispatch,來(lái)調(diào)vuex中的actions中的submit最后由其commit來(lái)修改store中的值。注意這里傳值的時(shí)候記得多傳遞一個(gè)第一步的信息(...step、...values),完成之后無(wú)需跳轉(zhuǎn)(因?yàn)閏ommit完就在那里執(zhí)行了跳轉(zhuǎn)的邏輯,不用重復(fù)寫(xiě))。表單三的話給個(gè)小提示就行


<template>
<div>
<!--面包屑導(dǎo)航區(qū)-->
<el-breadcrumb separator-class="el-icon-arrow-right">
<el-breadcrumb-item :to="{ path: '/home' }">首頁(yè)</el-breadcrumb-item>
<el-breadcrumb-item>商品管理</el-breadcrumb-item>
<el-breadcrumb-item>商品列表</el-breadcrumb-item>
</el-breadcrumb>
<!-- 卡片視圖區(qū)域 -->
<el-card>
<el-row :gutter="20">
<el-col :span="8">
<el-input placeholder="請(qǐng)輸入內(nèi)容" v-model="queryInfo.query" clearable>
<el-button slot="append" icon="el-icon-search" @click="getGoodsList"></el-button>
</el-input>
</el-col>
<el-col :span="4">
<el-button type="primary" @click="goAddpage">添加商品</el-button>
</el-col>
</el-row>
<!-- table表格區(qū)域 -->
<el-table :data="goodslist" border stripe>
<el-table-column type="index">
</el-table-column>
<el-table-column label="商品名稱(chēng)"
prop="goods_name"></el-table-column>
<el-table-column label="商品價(jià)格(元)"
prop="goods_price" width="95px"></el-table-column>
<el-table-column label="商品重量"
prop="goods_weight" width="70px"></el-table-column>
<el-table-column label="創(chuàng)建時(shí)間" prop="add_time" width="140px">
<template slot-scope="scope">{{scope.row.add_time | dateFormat}}</template>
</el-table-column>
<el-table-column label="操作" width="130px">
<template slot-scope="scope">
<el-button size="mini" type="primary" icon="el-icon-edit">編輯</el-button>
<el-button size="mini" type="danger" icon="el-icon-delete" @click="removeById(scope.row.goods_id)">刪除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分頁(yè)區(qū)域 -->
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="queryInfo.pagenum"
:page-sizes="[5, 10, 15, 20]"
:page-size="queryInfo.pagesize"
layout="total, sizes, prev, pager, next, jumper"
:total="total" background>
</el-pagination>
</el-card>
</div>
</template>
<script>
export default {
data () {
return {
queryInfo: {
query: '',
pagenum: 1,
pagesize: 10
},
// 商品列表
goodslist: [],
// 總書(shū)記條數(shù)
total: 0
}
},
created () {
this.getGoodsList()
},
methods: {
// 根據(jù)分頁(yè)獲取對(duì)應(yīng)的商品列表
async getGoodsList () {
const { data: res } = await this.$http.get('goods', { params: this.queryInfo })
if (res.meta.status !== 200) {
return this.$message.error('獲取商品列表失?。?)
}
this.$message.success('獲取商品列表成功!')
console.log = res.data
this.goodslist = res.data.goodslist
this.total = res.data.total
},
handleSizeChange (newSize) {
this.queryInfo.pagesize = newSize
this.getGoodsList()
},
handleCurrentChange (newPage) {
this.queryInfo.pagenum = newPage
this.getGoodsList()
},
async removeById (id) {
const confirmResult = await this.$confirm('此操作將永久刪除該商品, 是否繼續(xù)?', '提示', {
confirmButtonText: '確定',
cancelButtonText: '取消',
type: 'warning'
}).catch(err => err)
if (confirmResult !== 'confirm') {
return this.$message.info('已取消刪除!')
}
// eslint-disable-next-line no-undef
const { data: res } = await this.$http.delete(`goods/${id}`)
if (res.meta.status !== 200) {
return this.$message.error('刪除失??!')
}
this.$message.success('刪除成功!')
this.getGoodsList()
},
goAddpage () {
this.$router.push('/goods/add')
}
}
}
</script>
<style lang="less" scoped>
</style>到此這篇關(guān)于Vue表單快速上手的文章就介紹到這了,更多相關(guān)Vue表單內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue渲染器設(shè)計(jì)實(shí)現(xiàn)流程詳細(xì)講解
在瀏覽器平臺(tái)上,用它來(lái)渲染其中的真實(shí)DOM元素。渲染器不僅能夠渲染真實(shí)的DOM元素,它還是框架跨平臺(tái)能力的關(guān)鍵。所以在設(shè)計(jì)渲染器的時(shí)候一定要考慮好自定義的能力2023-01-01
如何在vue3+ts項(xiàng)目中使用query和params傳參
Vue3中的路由傳參有兩種方式:query和params,下面這篇文章主要給大家介紹了關(guān)于如何在vue3+ts項(xiàng)目中使用query和params傳參的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-04-04
Vue中的echarts圖表如何實(shí)現(xiàn)loading效果
這篇文章主要介紹了Vue中的echarts圖表如何實(shí)現(xiàn)loading效果,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08
vue實(shí)現(xiàn)把接口單獨(dú)存放在一個(gè)文件方式
這篇文章主要介紹了vue實(shí)現(xiàn)把接口單獨(dú)存放在一個(gè)文件方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-08-08
vue實(shí)現(xiàn)簡(jiǎn)單的跑馬燈效果
這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)簡(jiǎn)單的跑馬燈效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10
vue2 mint-ui loadmore實(shí)現(xiàn)下拉刷新,上拉更多功能
這篇文章主要介紹了vue2 mint-ui loadmore實(shí)現(xiàn)下拉刷新,上拉更多功能,需要的朋友可以參考下2018-03-03
Vue3不支持Filters過(guò)濾器的問(wèn)題
這篇文章主要介紹了Vue3不支持Filters過(guò)濾器的問(wèn)題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09
vue3+koa實(shí)現(xiàn)文件上傳功能的全過(guò)程記錄
開(kāi)發(fā)項(xiàng)目的時(shí)候,用到文件上傳的功能很常見(jiàn),包括單文件上傳和多文件上傳,下面這篇文章主要給大家介紹了關(guān)于vue3+koa實(shí)現(xiàn)文件上傳功能的相關(guān)資料,需要的朋友可以參考下2023-01-01

