Изменять переменную одновременно в нескольких компонентах Vue js
Есть родительский компонент, в нем есть переменная которая отвечает за состояние чекбокса. Чекбокс это дочерний компонент и нужно чтобы в случае изменения переменной в род. компоненте эта переменная менялась также в дочернем компоненте
Род. компонент
<template>
<div class="new-products">
<div>
<CheckBoxInput
@checked="checkedPrice"
id="product-price"
:model="modal.purchaseAgreement.price"
/>
</div>
</div>
</template>
<script>
import CheckBoxInput from "@/components/inputs/CheckBoxInput";
export default {
components: {
CheckBoxInput,
},
data() {
return {
modal: {
purchaseAgreement: {
price: false,
},
},
};
},
methods: {
checkedPrice(model) {
this.modal.purchaseAgreement.price = model;
},
},
};
</script>
Дочерний компонент
<template>
<div>
<input
:id="id.replace(' ', '')"
v-model="model"
type="checkbox"
@input="v && v.$touch()"
@click="checkedInput"
/>
</div>
</template>
<script>
export default {
name: "CheckBox",
props: {
id: {
type: String,
default: "id" + parseInt(Math.random() * 1000),
},
model: {
type: Boolean,
default: false,
},
},
data() {
return {
active: this.model,
};
},
methods: {
checkedInput() {
this.active = !this.active;
this.$emit("checked", this.active);
},
},
};
</script>
Мой вариант работает, но с багом, из-за чего при очистке переменной в главном компоненте, дочерний не меняется с первого раза
Ответы (1 шт):
Как описано в документации - Настройка v-model у компонента, создаете компонент CheckBoxInput, как:
const CheckBoxInput = Vue.component('check-box-input', {
model: {
prop: 'checked',
event: 'change'
},
props: {
id: {
type: String,
default: "id" + parseInt(Math.random() * 1000),
},
checked: {
type: Boolean,
default: false,
},
},
template: `
<div>
<fieldset>
<legend>Checkbox [ID:{{id}}]</legend>
<input
:id="id.replace(' ', '')"
:checked="checked"
@change="$emit('change', $event.target.checked)"
type="checkbox"
/>
</fieldset>
</div>
`,
})
После этого подключаете этот компонент в ваше приложение, как:
<check-box-input id="product-price" v-model="modal.purchaseAgreement.price"></check-box-input>
const CheckBoxInput = Vue.component('check-box-input', {
model: {
prop: 'checked',
event: 'change'
},
props: {
id: {
type: String,
default: "id" + parseInt(Math.random() * 1000),
},
checked: {
type: Boolean,
default: false,
},
},
template: `
<div>
<fieldset>
<legend>Checkbox [ID:{{id}}]</legend>
<input
:id="id.replace(' ', '')"
:checked="checked"
@change="$emit('change', $event.target.checked);$emit('checked', $event.target.checked)"
type="checkbox"
/>
</fieldset>
</div>
`,
})
new Vue({
el: '#app',
components: {
CheckBoxInput,
},
data() {
return {
modal: {
purchaseAgreement: {
price: false,
},
},
};
},
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="app">
<div class="new-products">
<div>
<fieldset>
<legend>Родительский компонент</legend>
<pre>{{ $data }}</pre>
<button @click="modal.purchaseAgreement.price = !modal.purchaseAgreement.price">Изменить checkbox из родителя - {{modal.purchaseAgreement.price}}</button>
<check-box-input id="product-price" v-model="modal.purchaseAgreement.price"></check-box-input>
<check-box-input id="product-price2" v-model="modal.purchaseAgreement.price"></check-box-input>
</fieldset>
</div>
</div>
</div>
В итоге вы получаете возможность управления состоянием чекбокса и соответственно получаете возможность изменения его состояния как из родительского компонента(модифицируя значение свойства, которое используется в качестве v-model) так и из его самого(полагаясь на функционал компонента)