el-checkbox内置的change事件不生效

在做购物车的全选和反选功能的时候,因为要将选项框的状态发送请求提交到后台,所以将对应的功能写在了change事件绑定的函数里:

这里el-checkbox绑定的是 cartStore.allSelected,是一个计算属性,然后我发现我点击全选这个框的话,change事件是会触发的,请求也会正常发送,但是当我是通过js逻辑改变了它的值(比如我把购物车的每个商品的选框都选中,allSelected会变成true),这种情况下是不会触发change事件的,也就不会发送请求。

我的解决办法是自己封装一个自定义组件:

1. 我会给这个组件用v-model绑定allSelected,那allSelected就要可写

2. 在这个子组件我就要实现v-model的原理也就是 :modelValue 和 @update:modelValue,所以在这个子组件中,可以根据父组件传过来的值再搞一个计算属性value,这个计算属性的getter返回modelValue接收的值,setter进行emit传递update:modelValue和值。

3. 子组件里面的el-checkbox绑定数据value,如果value的值改变了,就会触发update:modelValue,到这里就是实现了el-checkbox改变了value的值也会间接改变父组件传过来的值。

就是value改变 -> emit('update:modelValue',val) -> 影响到v-model="cartStore.allSelected" -> allSelected的set()就会执行,然后又返回了get()

4. 最后在子组件中再对value进行监听,如果改变了,就会像父组件emit自定义的autoChange事件,接着在父组件中的my-checkbox绑定autoChange事件执行发送请求到后台的函数就行。

这一步就是 emit的多了一个'autoChange' -> 发送请求。

// cartStore.js
// 设置全选的计算属性,getter和setter
const allSelected = computed({
  get() {
    return cartData.value.every((item) => item.selected)
  },
  set(val) {
    // 让全选计算属性可写
    cartData.value.forEach((item) => (item.selected = val))
  }
})
// 自定义组件 myCheckbox.vue
<script setup>
import { computed, watch } from 'vue'
const props = defineProps({
  // 这里不改名 父组件直接使用v-model就会传过来
  modelValue: Boolean
})
const emit = defineEmits(['update:modelValue', 'autoChange'])
const value = computed({
  get() {
    return props.modelValue
  },
  set(val) {
    emit('update:modelValue', val)
  }
})
// 监听value 如果改变了,就提交到父组件autoChange
watch(value, () => {
  emit('autoChange')
})
</script>

<template>
  // v-model不能直接绑定父组件传过来的modelValue,所以还得用一个计算属性来实现父组件v-model的功能
  // 然后监听value进行绑定
  <el-checkbox v-model="value"></el-checkbox>
</template>

<style lang="scss" scoped></style>
// 父组件
<script setup>
import { changeCart, changeSelect } from '@/api/cart'
import { useCartStore } from '@/stores'
import MyCheckbox from '@/components/MyCheckbox.vue'
const cartStore = useCartStore()
const onChange = async (item) => {
  // 商品修改重新提交到后台(登录状态下)
  if (cartStore.isLogin) {
    await changeCart(item)
    // 提交后更新购物车
    cartStore.updateCart()
  }
}

const onChangeAllSelect = async () => {
  // 提交全选/取消全选状态到后台数据
  if (cartStore.isLogin) {
    await changeSelect({
      selected: cartStore.allSelected,
      ids: cartStore.cartData.map((item) => item.skuId)
    })
    // 提交后更新购物车
    cartStore.updateCart()
  }
}
</script>

<template>
  ....
  <my-checkbox
    v-model="cartStore.allSelected"
    @autoChange="onChangeAllSelect"
  ></my-checkbox>
  ...
  <my-checkbox v-model="i.selected" @autoChange="onChange(i)"></my-checkbox>
  ...
</template>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值