Skip to content

问题描述


mounted中修改checkbox的值,设想应该会触发change事件,但实际上并没有触发。

代码如下:

vue
<template>
	   <el-checkbox v-model="checkBox" @change="change">测试</el-checkbox>
</template>
<script>
  export default{
  	data() {
      return {
        checkBox: false,
      }
    },
    methods:{
    	change(){
      	console.log('改变了值')
      }
    },
    mounted(){
    	this.checkBox = true
    }
  }
</script>

原因探究


html中checkbox 的实现:

我们先来看看在html中checkbox 的实现:<input type="checkbox">

其中checked属性用于控制控件是否被选中,onchange事件,在元素值被改变时执行。

这里要注意:

当我们用js修改checked绑定的值时,并不会触发onchange事件,用鼠标点击会checkbox框会触发onchange事件。

如下边这段代码

html
<body>
	<section id="app">
		<button onclick="alterCheckboxValue()">切换!</button>
		<input type="checkbox" id="checkbox1" onchange="handleChange()">
	</section>
	<script>
		function alterCheckboxValue() {
			const el = document.querySelector("#checkbox1");
			el.checked = !el.checked;
		}
		function handleChange(e) {
			console.log("触发change事件");
		}
	</script>
</body>

v-model指令

<font style="color:rgb(64, 64, 64);">v-model</font><font style="color:rgb(64, 64, 64);"><input></font>

vue
  <input type="text" v-model="msg">
	// 等价于
	<input type="text" v-bind:value="msg" v-on:input="msg=$event.target.value">

**<font style="color:rgb(18, 18, 18);">v-model</font>**<font style="color:rgb(18, 18, 18);">:value="msg" </font>``@input<font style="color:rgb(18, 18, 18);">="msg=$event.target.value"</font>

  • @input
****

出错的代码

我们再来看看出错的代码

vue
<el-checkbox v-model="value" @change="HandleChange">

根据上边内容,我们可以知道,这段代码中

  • v-model = "value"** **应该就是对input标签checked属性与value进行了一个绑定
  • @change = "HandleChange"就是onchange事件

如果elmentUI没有做特殊处理,当我们通过JS修改value值时,也不会触发HandleChange方法

el-checkbox源码:

我们再来看看el-checkbox源码:

参考:https://blog.csdn.net/tangran0526/article/details/99686744

查看源码可以看到,确实如我们所想,当绑定的值变化后,并没有触发这个 handleChange事件,而是触发了el-form父元素的change事件。

javascript
watch: {
  		// el-checkbox绑定的值
      value(value) {
        this.dispatch('ElFormItem', 'el.form.change', value);
      }
    }

解决


重新封装el-checkbox,添加vaule的监听属性,触发change事件。

vue
<!--解决lay-->
<template>
  <el-checkbox v-model="model"/>
</template>

<script>
export default {
  name: 'my-checkBox',
  props: {
    value: false,
    autoChange: {
      type: Function,
      default: () => {
      }
    }
  },
  data() {
    return {
      selfModel: false,
    }
  },
  computed: {
    model: {
      get() {
        return this.value !== undefined
            ? this.value : this.selfModel
      },

      set(val) {
        this.$emit('input', val)
        this.selfModel = val;
      }
    },
  },
  watch: {
    value() {
      this.$emit('autoChange', this.value)
    }
  }
}
</script>

父组件中使用:

vue
 <auto-checkbox v-model:value="item.checkBoxShow" @autoChange="layerChange(item)"/>