vue2组件封装

1.组件封装之v-model

在vue文档中,有关于v-model的仔细说明。其中关键一点:
v-model其实是隐藏了:value 和@input 的,特别是后者,在自定义组件中,
子组件需要往外触发事件进而改变父组件的值时,尤其关键!
image.png
对于子组件来说,必须要有这个$emit !!!

2.组件封装之render函数

以下是 iview框架下,给表格加单选框的一个功能;需要用到render函数进行扩展。
image.png
那么这里,应该得到启发。我封装一个组件,我除了提供slot给外面,是否可以像这样,外面可以通过配置属性,进而传一个render函数到我的这个自定义组件中;以及,如何处理这个传进来的render函数。接下来不妨先练习一下render函数的使用,再来说如何在组件封装中使用render函数这件事。
先学习一下iview框架封装的table-header,它可以用props–>render来接收外部的一个函数。
image.png
这里是一个普通的js文件,导出了一个 {…} 对象;
image.png
在vue文件中可以导入这个 {…} 对象;并注册到当前组件中。js文件当组件用,这点是可以学习一下的。

3.js文件可以在vue项目中当组件用

export default {
    name: 'xdcTest',
    functional: false,
    props: {},
    render: (h, ctx) => {
        return h('div','hello xudechuan')
    }
}

image.png

4.组件封装之api式调用

如 this. m e s s a g e . x x x x , t h i s . message.xxxx,this. message.xxxx,this.prompt.xxx这种组件。

5.组件封装之–兄弟组件通信

a. 多个vue文件(4,5个甚至10来个)需要共用一套业务逻辑,那么兄弟组件通信 适合用vuex来做。
b. 一些字典查询类型的数据,需要多个子孙节点共用;那么适合用 provide/inject 来做。
c. 一些相对比较固定的组件(比如 商品卡片),适合用props传参进来,保持独立性,而不是参和vuex。

6.组件封装之–大表单拆装
/** 点击提交按钮 */
async submit() {

  const formCopy = uni.$u.deepClone(this.orderForm);
  this.formClone = formCopy;

  // 验证1 格式
  const valid1 = await this.validateFormCustom(formCopy).catch((err) => {
    if (err) {
      this.formClone = null
      this.$refs.uToast.show({
        message: err,
      })
    }
  })
  if (!valid1) return;

  // 验证2 异步验证
  this.btnLoading = true;
  const valid2 = await this.validateProduct(formCopy).catch((err) => {
    if (err) {
      this.formClone = null
      this.$refs.uToast.show({
        message: err,
      })
    }
  })
  this.btnLoading = false;
  if (!valid2) return;

  /** 验证3 */
  if (this.isConfirm && this.orderType != 1) {
    this.btnLoading = true;
    const valid3 = await this.validateMoney(formCopy).catch((err) => {
      if (err) {
        this.moneyShow = true
      }
    })
    this.btnLoading = false;
    if (!valid3) return;
  }

  /** 验证4 */
  if (this.allNum > Number(this.orderForm.shipInfoDto.loadMax)) {
    this.modalShow = true;
    return;
  }

  // 最终请求
  this.sendDispatch()
},
/** 验证数据格式 */
validateFormCustom(formCopy) {
  return new Promise((resolve, reject) => {
    /** a信息 */
    const createDtoList = formCopy.createDtoList
    for (var i = 0; i < createDtoList.length; i++) {
      const createDto = createDtoList[i]
      const wrongPro = this.wrongPro(createDto.materials)
      if (!createDto.wtPurchaseOrder.ccName) reject("请选择xx");
      if (!createDto.wtPurchaseOrder.terminalUse) reject('请选择xx');
      if (!createDto.wtPurchaseOrder.deliveryArea) reject('请选择xx');
      if (createDto.materials.length <= 0) reject('请选择xx');
      if (createDto.materials.length > 10) reject('每个客户最多选择10条产品信息,请删减');
      if (this.isNullPro(createDto.materials)) reject('产品信息请填写完成(数值不能为0)');
      if (wrongPro) reject(`${wrongPro}比例不是100%, 请修改`);
    }
    /** b信息 */
    const shipInfoDto = formCopy.shipInfoDto
    if (!shipInfoDto.shipName) reject('请选择xx');
    if (!shipInfoDto.contact) reject('请输入xx');
    if (!shipInfoDto.phoneNumber) reject('请输入xx');
    if (!uni.$u.test.mobile(shipInfoDto.phoneNumber)) reject('请输入正确的手机号');
    if (!shipInfoDto.loadMin || !shipInfoDto.loadMax) reject('请输入xx');

    /** 通过验证 */
    resolve(true)
  })
},
/** 验证xxx是否充足 */
validateMoney() {
  return new Promise((resolve, reject) => {
    const ccId = this.orderForm.createDtoList[0].ccId
    const mcList = this.orderForm.createDtoList[0].materials
    clientServiceGetByCcId({ccId}).then((res) => {
      this.moneyObj = res
      this.realMoney = (res.advanceBalance - res.debtQuota).toFixed(2)
      if (allMoney > this.realMoney) {
        reject("xxx不足")
      } else {
        resolve(true)
      }
    }).catch((err) => {
      reject(false)
    })
  })
},

7.组件封装之–slot
<div class="container">
  <footer>
    <slot name="footer"></slot>
  </footer>
</div>
<base-layout>
  <template v-slot:footer>
    <p>Here's some contact info</p>
  </template>
</base-layout>

注意: v-slot 后面是冒号不是等号;可用template进行包裹;
或者: slot=“reference” 这么写

8.watch

注意写法,不然不会生效

timeGap: {
  handler: function (val) {
    this.rectList = this.rectList.map((item, index) => {
      return {
        ...item,
        planTime: val[index],
      }
    })
  },
  deep: true,
  immediate: true,
},
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值