欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Vue表單快速上手

 更新時(shí)間:2022年09月13日 08:53:42   作者:丘比特懲罰陸  
工作中vue表單使用的最多的莫過(guò)于input、textarea、select等,原生js的基礎(chǔ)上vue通過(guò)雙向數(shù)據(jù)綁定等,實(shí)現(xiàn)了自己獨(dú)有的一套指令,這是react中沒(méi)有的部分,也算是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)等。拷貝validateStatus到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">
          <!--用戶名-->
  <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)輸入登錄名稱', 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,保存到客戶端的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è)是字段名稱、第二個(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為付款賬戶。往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,名稱為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è)付款賬戶的{{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="商品名稱"
         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)文章

最新評(píng)論