我的编程空间,编程开发者的网络收藏夹
学习永远不晚

解决Antd输入框卡顿问题以及Pubsub.js的使用方式

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

解决Antd输入框卡顿问题以及Pubsub.js的使用方式

项目场景

项目中通过表单来填写校验大量复杂数据

问题描述 

项目中使用的是Ant Design of Vue这个组件库,使用FormModel 表单,数据字段和校验较多时,表单操作卡顿;eg: a-input输入框,等你输入完字及,几秒后才慢慢出现你输入的字符

原因分析

vue在进行输入时,进行了多次的render刷新渲染操作,导致了input框输入时发生的卡顿现象

解决方案

官方给出的解决办法,将 Form 相关的业务独立到一个单独的组件中,减少组件渲染的消耗,如果有很多校验项,可把它们分别放在不同的Form中处理

eg :

一、组件封装

在这里插入图片描述

将大表单拆分成三个组件表单,数据校验等操作在其组件内部实现

二、formTable中的字段有部分与formTableTwo联动

这里使用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')
  }

三、使用Promise.all提交校验表单

子组件

    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 style="margin-left: 10px;" @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"
          style="width: 100%;"
        />
      </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"
        style="width: 100%;"
      />
    </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"
        style="width: 100%;"
      />
    </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>

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

解决Antd输入框卡顿问题以及Pubsub.js的使用方式

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

解决Antd输入框卡顿问题以及Pubsub.js的使用方式

这篇文章主要介绍了解决Antd输入框卡顿问题以及Pubsub.js的使用方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2023-05-17

浅析Node.js中使用依赖注入的相关问题及解决方法

最近,我转向使用依赖注入来帮助理解分离代码的简单途径,并有助测试。然而,Node.js中的模块依赖Node提供的系统API,这很难判断私有依赖被恰当的使用。一般的依赖注入很难在这种情况下使用,但现在不要放弃希望。 requireCauses
2022-06-04

使用C++开发嵌入式系统时的常见性能问题和解决方法

c++++ 嵌入式系统常见性能问题及其解决方法包括:内存泄漏:使用智能指针或引用计数管理内存。异常处理:避免异常或在单独线程中捕获它们。线程同步:使用细粒度的锁和无锁数据结构。避免死锁。i/o 操作:使用非阻塞或异步 i/o,利用 dma
使用C++开发嵌入式系统时的常见性能问题和解决方法
2024-05-12

深入学习Golang的打包实战指南: 探索使用Golang进行打包及解决常见问题的方法

Golang打包实战指南:利用golang进行打包并解决常见问题引言:Golang是一门流行的编程语言,其强大的并发性和高效的编译器使其成为很多开发者的首选。在开发过程中,我们经常需要将我们的代码打包成可执行文件或库,以便在其他环境中部署和
深入学习Golang的打包实战指南: 探索使用Golang进行打包及解决常见问题的方法
2023-12-29

MySQL中使用delete_at(时间戳)作为逻辑删除标记时如何使用MyBatis-Plus逻辑删除组件插入时间戳,以及如何解决自动填充失效的问题

背景 MySQL中使用delete_at(时间戳)作为逻辑删除标记 在业务中,使用逻辑删除是普遍做法,通常会使用一个名为deleted(0/1)的字段表示删除状态。 但是如果遇到有唯一约束,且可能反复删除和重新插入的表(如用户表,注销用户使
2023-08-30

编程热搜

目录