您好,登錄后才能下訂單哦!
這篇文章主要介紹“Antd輸入框卡頓及Pubsub.js使用問題怎么解決”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“Antd輸入框卡頓及Pubsub.js使用問題怎么解決”文章能幫助大家解決問題。
項目中通過表單來填寫校驗大量復雜數據
項目中使用的是Ant Design of Vue這個組件庫,使用FormModel 表單,數據字段和校驗較多時,表單操作卡頓;eg: a-input輸入框,等你輸入完字及,幾秒后才慢慢出現你輸入的字符
vue在進行輸入時,進行了多次的render刷新渲染操作,導致了input框輸入時發生的卡頓現象
官方給出的解決辦法,將 Form 相關的業務獨立到一個單獨的組件中,減少組件渲染的消耗,如果有很多校驗項,可把它們分別放在不同的Form中處理
eg :
將大表單拆分成三個組件表單,數據校驗等操作在其組件內部實現
這里使用PubSub.js進行兄弟組件傳值
PubSub.js的使用
1.首先安裝pubsub-js
npm install --save pubsub-js
2.簡單使用
導入
import PubSub from 'pubsub-js'
發送消息:PubSub.publish(名稱,參數)
訂閱消息:PubSub.subscrib(名稱,函數)
取消訂閱:PubSub.unsubscrib(名稱)
在formTableTwo中使用PubSub.publish(名稱,參數)發送信息,formTableOne中使用PubSub.subscrib(名稱,函數)接收信息。
注意:
1.PubSub.subscrib(名稱,函數)接收信息的所傳名稱要與PubSub.publish(名稱,參數)
發送信息的名稱一致
2.PubSub.subscrib(名稱,函數)接收信息可能會被觸發多次,可以在PubSub.subscrib(名稱,函數)
前使用 PubSub.unsubscribe
可以解決
created () { // console.log('form1', this.form) // 解決PubSub多次調用 PubSub.unsubscribe('send'); // 訂閱消息(接收消息) PubSub.subscribe('send', (name, value) => { console.log('name', name) console.log('value', value) }) // 訂閱組件二的消息 PubSub.subscribe('sendTwo', (name, val) => { console.log('sendTwo', name) console.log('我是接受到的值', val) this.isShow = val }) console.log('this.form', this.form) },
3.記得發布了消息 要在vue beforedestory
中銷毀取消訂閱 ,發布的次數多了,會造成訂閱一次觸發多次的情況;
beforeDestroy () { PubSub.unsubscribe('send') PubSub.unsubscribe('sendTwo') }
子組件
onSubmit () { return new Promise((resolve, reject) => { this.$refs.ruleForm.validate(valid => { if (valid) { console.log('表單1通過') this.outgoingInfo() resolve(valid) } else { console.log('error submit!!') reject(valid) return false } }) }) },
父組件
// 表單校驗 submitForm () { console.log('this.$refs.FormTableOne.form', this.$refs.FormTableOne.form) const rules1 = this.$refs.FormTableOne.onSubmit() const rules2 = this.$refs.FormTableTwo.onSubmit() const rules3 = this.$refs.FormTableThree.onSubmit() Promise.all([rules1,rules2, rules3]).then(() => { console.log('校驗通過') }) },
完整demo
formGroup
<template> <div> <div> <FormTableOne ref="FormTableOne" :formInfo="form" @outgoingInfo="outgoingInfo"/> <FormTableTwo ref="FormTableTwo" /> <FormTableThree ref="FormTableThree" /> </div> <a-button type="primary" @click="submitForm"> submit </a-button> <a-button @click="resetForm"> Reset </a-button> </div> </template> <script> import FormTableOne from './components/formTableOne' import FormTableTwo from './components/formTableTwo' import FormTableThree from './components/formTableThree' import PubSub from 'pubsub-js' export default { components: { FormTableOne, FormTableTwo, FormTableThree }, data () { return { form: {} } }, created() { this.sendMessages() setTimeout(() => { this.form = { name1: '123456', region1: undefined, date1: undefined, delivery1: false, type1: [], resource1: '123', desc1: '123', name2: '', region2: undefined, date2: undefined, delivery2: false, type2: [], resource2: '', desc2: '', name3: '', region3: undefined, date3: undefined, delivery3: false, type3: [], resource3: '', desc3: '' } }, 2000) }, methods: { // 表單校驗 submitForm () { console.log('this.$refs.FormTableOne.form', this.$refs.FormTableOne.form) const rules1 = this.$refs.FormTableOne.onSubmit() const rules2 = this.$refs.FormTableTwo.onSubmit() const rules3 = this.$refs.FormTableThree.onSubmit() Promise.all([rules1,rules2, rules3]).then(() => { console.log('校驗通過') }) }, outgoingInfo (val) { console.log('組件一傳出的值', val) Object.assign(this.form, val) console.log('主組件的值', this.form) }, resetForm () { this.sendMessages() this.form = { name1: '', region1: undefined, date1: undefined, delivery1: false, type1: [], resource1: '', desc1: '', name2: '', region2: undefined, date2: undefined, delivery2: false, type2: [], resource2: '', desc2: '', name3: '', region3: undefined, date3: undefined, delivery3: false, type3: [], resource3: '', desc3: '' } console.log('this.form', this.form) }, sendMessages () { console.log('發送') PubSub.publish('send', { name: '張三', age: 18 }) } } } </script> <style></style>
formTableOne
<template> <div> <a-form-model ref="ruleForm" :model="form" :rules="rules" :label-col="labelCol" :wrapper-col="wrapperCol" > <a-form-model-item ref="name1" label="組件一: name" prop="name1" v-if="isShow"> <a-input v-model="form.name1" @blur=" () => { $refs.name1.onFieldBlur() } " /> </a-form-model-item> <a-form-model-item label="組件一: zone" prop="region1"> <a-select v-model="form.region1" placeholder="please select your zone"> <a-select-option value="shanghai"> Zone one </a-select-option> <a-select-option value="beijing"> Zone two </a-select-option> </a-select> </a-form-model-item> <a-form-model-item label="組件一: time" required prop="date1"> <a-date-picker v-model="form.date1" show-time type="date" placeholder="Pick a date" /> </a-form-model-item> <a-form-model-item label="組件一: delivery1" prop="delivery1"> <a-switch v-model="form.delivery1" /> </a-form-model-item> <a-form-model-item label="組件一: type1" prop="type1"> <a-checkbox-group v-model="form.type1"> <a-checkbox value="1" name="type1"> Online </a-checkbox> <a-checkbox value="2" name="type1"> Promotion </a-checkbox> <a-checkbox value="3" name="type1"> Offline </a-checkbox> </a-checkbox-group> </a-form-model-item> <a-form-model-item label="組件一:Resource1s" prop="resource1"> <a-radio-group v-model="form.resource1"> <a-radio value="1"> Sponsor </a-radio> <a-radio value="2"> Venue </a-radio> </a-radio-group> </a-form-model-item> <a-form-model-item label="組件一: form" prop="desc1"> <a-input v-model="form.desc1" type="textarea" /> </a-form-model-item> <a-form-model-item :wrapper-col="{ span: 14, offset: 4 }"> </a-form-model-item> </a-form-model> <a-button type="primary" @click="outgoingInfo"> Create </a-button> </div> </template> <script> import PubSub from 'pubsub-js' const list = [ '', 'name1', 'region1', 'date1', 'delivery1', 'type1', 'resource1', 'desc1' ] export default { name: 'FormTableOne', props: { formInfo: { type: Object, default: () => { return { name1: '', region1: undefined, date1: undefined, delivery1: false, type1: [], resource1: '', desc1: '' } } } }, created () { // console.log('form1', this.form) // 解決PubSub多次調用 PubSub.unsubscribe('send'); // 訂閱消息(接收消息) PubSub.subscribe('send', (name, value) => { console.log('name', name) console.log('value', value) }) // 訂閱組件二的消息 PubSub.subscribe('sendTwo', (name, val) => { console.log('sendTwo', name) console.log('我是接受到的值', val) this.isShow = val }) console.log('this.form', this.form) }, data () { return { isShow: true, labelCol: { span: 4 }, wrapperCol: { span: 14 }, other: '', form: { name1: '', region1: undefined, date1: undefined, delivery1: false, type1: [], resource1: '', desc1: '' }, rules: { region1: [ { required: true, message: 'Please select Activity zone', trigger: 'change' } ], date1: [ { required: true, message: 'Please pick a date', trigger: 'change' } ], resource1: [ { required: true, message: 'Please select activity resource1', trigger: 'change' } ], desc1: [ { required: true, message: 'Please input activity form', trigger: 'blur' } ] } } }, watch: { // 過濾一些不屬于這個組件屬性 formInfo () { let obj = JSON.parse(JSON.stringify(this.formInfo, (key, value) => { if (list.includes(key)) { return value } else { return undefined } })) this.form = Object.assign(this.form, obj) }, deep: true }, computed: { }, methods: { onSubmit () { return new Promise((resolve, reject) => { this.$refs.ruleForm.validate(valid => { if (valid) { console.log('表單1通過') this.outgoingInfo() resolve(valid) } else { console.log('error submit!!') reject(valid) return false } }) }) }, resetForm () { this.$refs.ruleForm.resetFields() }, // 將組件的值傳出去 outgoingInfo () { this.$emit('outgoingInfo', this.form) } }, beforeDestroy () { PubSub.unsubscribe('send') PubSub.unsubscribe('sendTwo') } } </script>
formTabeTwo
<template> <a-form-model ref="ruleForm" :model="form" :rules="rules" :label-col="labelCol" :wrapper-col="wrapperCol" > <a-form-model-item ref="name2" label="組件二: name" prop="name2"> <a-input v-model="form.name2" @blur=" () => { $refs.name2.onFieldBlur() } " /> </a-form-model-item> <a-form-model-item label="組件二: zone" prop="region2"> <a-select v-model="form.region2" placeholder="please select your zone"> <a-select-option value="shanghai"> Zone one </a-select-option> <a-select-option value="beijing"> Zone two </a-select-option> </a-select> </a-form-model-item> <a-form-model-item label="組件二: time" required prop="date2"> <a-date-picker v-model="form.date2" show-time type="date" placeholder="Pick a date" /> </a-form-model-item> <a-form-model-item label="組件二: delivery2" prop="delivery2"> <a-switch v-model="form.delivery2" @change="checkChange"/> </a-form-model-item> <a-form-model-item label="組件二: type2" prop="type2"> <a-checkbox-group v-model="form.type"> <a-checkbox value="1" name="type2"> Online </a-checkbox> <a-checkbox value="2" name="type2"> Promotion </a-checkbox> <a-checkbox value="3" name="type2"> Offline </a-checkbox> </a-checkbox-group> </a-form-model-item> <a-form-model-item label="組件二:resource2s" prop="resource2"> <a-radio-group v-model="form.resource2"> <a-radio value="1"> Sponsor </a-radio> <a-radio value="2"> Venue </a-radio> </a-radio-group> </a-form-model-item> <a-form-model-item label="組件二: form" prop="desc2"> <a-input v-model="form.desc2" type="textarea" /> </a-form-model-item> <a-form-model-item :wrapper-col="{ span: 14, offset: 4 }"> </a-form-model-item> </a-form-model> </template> <script> import PubSub from 'pubsub-js' export default { name: 'FormTableOne', data () { return { labelCol: { span: 4 }, wrapperCol: { span: 14 }, other: '', form: { name2: '', region2: undefined, date2: undefined, delivery2: false, type2: [], resource2: '', desc2: '' }, rules: { region2: [ { required: true, message: 'Please select Activity zone', trigger: 'change' } ], date2: [ { required: true, message: 'Please pick a date', trigger: 'change' } ], resource2: [ { required: true, message: 'Please select activity resource2', trigger: 'change' } ], desc2: [ { required: true, message: 'Please input activity form', trigger: 'blur' } ] } } }, created() { }, methods: { onSubmit () { return new Promise((resolve, reject) => { this.$refs.ruleForm.validate(valid => { if (valid) { console.log('表單2通過') resolve(valid) } else { console.log('error submit!!') reject(valid) return false } }) }) }, checkChange() { // 發布消息 PubSub.publish('sendTwo', false) }, resetForm () { this.$refs.ruleForm.resetFields() } } } </script>
formTableThree
<template> <a-form-model ref="ruleForm" :model="form" :rules="rules" :label-col="labelCol" :wrapper-col="wrapperCol" > <a-form-model-item ref="name3" label="組件三: name3" prop="name3"> <a-input v-model="form.name3" @blur=" () => { $refs.name3.onFieldBlur() } " /> </a-form-model-item> <a-form-model-item label="組件三: zone" prop="region3"> <a-select v-model="form.region3" placeholder="please select your zone"> <a-select-option value="shanghai"> Zone one </a-select-option> <a-select-option value="beijing"> Zone two </a-select-option> </a-select> </a-form-model-item> <a-form-model-item label="組件三: time" required prop="date3"> <a-date-picker v-model="form.date3" show-time type="date" placeholder="Pick a date" /> </a-form-model-item> <a-form-model-item label="組件三: delivery3" prop="delivery3"> <a-switch v-model="form.delivery3" /> </a-form-model-item> <a-form-model-item label="組件三: type3" prop="type3"> <a-checkbox-group v-model="form.type"> <a-checkbox value="1" name="type3"> Online </a-checkbox> <a-checkbox value="2" name="type3"> Promotion </a-checkbox> <a-checkbox value="3" name="type3"> Offline </a-checkbox> </a-checkbox-group> </a-form-model-item> <a-form-model-item label="組件三:Resource3s" prop="resource3"> <a-radio-group v-model="form.resource3"> <a-radio value="1"> Sponsor </a-radio> <a-radio value="2"> Venue </a-radio> </a-radio-group> </a-form-model-item> <a-form-model-item label="組件三: form" prop="desc3"> <a-input v-model="form.desc3" type="textarea" /> </a-form-model-item> <a-form-model-item :wrapper-col="{ span: 14, offset: 4 }"> </a-form-model-item> </a-form-model> </template> <script> export default { name: 'FormTableOne', data () { return { labelCol: { span: 4 }, wrapperCol: { span: 14 }, other: '', form: { name3: '', region3: undefined, date3: undefined, delivery3: false, type3: [], resource3: '', desc3: '' }, rules: { region3: [ { required: true, message: 'Please select Activity zone', trigger: 'change' } ], date3: [ { required: true, message: 'Please pick a date', trigger: 'change' } ], resource3: [ { required: true, message: 'Please select activity resource3', trigger: 'change' } ], desc3: [ { required: true, message: 'Please input activity form', trigger: 'blur' } ] } } }, methods: { onSubmit () { return new Promise((resolve, reject) => { this.$refs.ruleForm.validate(valid => { if (valid) { console.log('表單3通過') resolve(valid) } else { console.log('error submit!!') reject(valid) return false } }) }) }, resetForm () { this.$refs.ruleForm.resetFields() } } } </script>
關于“Antd輸入框卡頓及Pubsub.js使用問題怎么解決”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。