\n
To accomplish this scenario I am using 2 main components. When someone clicked on a component I am adding that component to selectedStreams array. Selected stream array structure is similar to below structure
\n checked: {\n g1: ['val1'],\n g2: []\n }\n
\nWhen I click on heading checkbox I am triggering function
\n\n\nclickAll and try to change the selectedStreams[keyv].
\n
But this action doesn't trigger the child component and automatically checked the checkbox.
\nCan I know the reason why when I changed the parent v-model value it is not visible in child UI.
\nParent Component
\n <template>\n <div>\n <b-form-group>\n <StreamCheckBox\n v-for="(opts, keyv) in loggedInUsernamesf"\n :key="keyv"\n :name="opts"\n :main="keyv"\n v-model="selectedStreams[keyv]"\n @clickAll="clickAll($event, keyv)"\n ></StreamCheckBox>\n </b-form-group>\n </div>\n</template>\n<script>import StreamCheckBox from "./StreamCheckBox";\nexport default {\n name: "GroupCheckBox",\n components: {StreamCheckBox},\n data(){\n return {\n selectedStreams:{}\n }\n },\n computed: {\n loggedInUsernamesf() {\n var username_arr = JSON.parse(this.$sessionStorage.access_info_arr);\n var usernames = {};\n if (!username_arr) return;\n for (let i = 0; i < username_arr.length; i++) {\n usernames[username_arr[i].key] = [];\n var payload = {};\n payload["main"] = username_arr[i].val.name;\n payload["type"] = username_arr[i].val.type;\n if (username_arr[i].val.permissions) {\n for (let j = 0; j < username_arr[i].val.permissions.length; j++) {\n payload["value"] = username_arr[i].key + username_arr[i].val.permissions[j].streamId;\n payload["text"] = username_arr[i].val.permissions[j].streamId;\n }\n }\n usernames[username_arr[i].key].push(payload);\n }\n return usernames;\n },\n },\n\n methods: {\n \n clickAll(e, keyv) {\n if (e && e.includes(keyv)) {\n this.selectedStreams[keyv] = this.loggedInUsernamesf[keyv].map(\n opt => {\n return opt.value\n }\n );\n }\n console.log(this.selectedStreams[keyv]);\n }\n }\n }\n</script>\n\n<style scoped>\n\n</style>\n
\nChild Component
\n <template>\n <div style="text-align: left;">\n <b-form-checkbox-group style="padding-left: 0;"\n id="flavors"\n class="ml-4"\n stacked\n v-model="role"\n :main="main"\n >\n <b-form-checkbox\n class="font-weight-bold main"\n :main="main"\n :value="main"\n @input="checkAll(main)"\n >{{ name[0].main }}</b-form-checkbox>\n <b-form-checkbox\n v-for="opt in displayStreams"\n :key="opt.value"\n :value="opt.value"\n >{{ opt.text }}</b-form-checkbox>\n </b-form-checkbox-group>\n </div>\n</template>\n\n<script>\n export default {\n name:"StreamCheckBox",\n props: {\n value: {\n type: Array,\n },\n name: {\n type: Array,\n },\n main:{\n type:String\n }\n\n },\n computed:{\n role: {\n get: function(){\n return this.value;\n },\n set: function(val) {\n this.$emit('input', val);\n }\n },\n displayStreams: function () {\n return this.name.filter(i => i.value)\n },\n },\n methods:{\n checkAll(val)\n {\n this.$emit('clickAll', val);\n }\n }\n }\n</script>\n
\n","author":{"@type":"Person","name":"Shelly"},"upvoteCount":3,"answerCount":1,"acceptedAnswer":null}}Reputation: 440
I am using VUE JS and I want to have group of checkboxes as below. When someone clicked on main checkbox all the checkboxes under that check box should be selected. Please find the attached image for your reference
To accomplish this scenario I am using 2 main components. When someone clicked on a component I am adding that component to selectedStreams array. Selected stream array structure is similar to below structure
checked: {
g1: ['val1'],
g2: []
}
When I click on heading checkbox I am triggering function
clickAll and try to change the selectedStreams[keyv].
But this action doesn't trigger the child component and automatically checked the checkbox.
Can I know the reason why when I changed the parent v-model value it is not visible in child UI.
Parent Component
<template>
<div>
<b-form-group>
<StreamCheckBox
v-for="(opts, keyv) in loggedInUsernamesf"
:key="keyv"
:name="opts"
:main="keyv"
v-model="selectedStreams[keyv]"
@clickAll="clickAll($event, keyv)"
></StreamCheckBox>
</b-form-group>
</div>
</template>
<script>import StreamCheckBox from "./StreamCheckBox";
export default {
name: "GroupCheckBox",
components: {StreamCheckBox},
data(){
return {
selectedStreams:{}
}
},
computed: {
loggedInUsernamesf() {
var username_arr = JSON.parse(this.$sessionStorage.access_info_arr);
var usernames = {};
if (!username_arr) return;
for (let i = 0; i < username_arr.length; i++) {
usernames[username_arr[i].key] = [];
var payload = {};
payload["main"] = username_arr[i].val.name;
payload["type"] = username_arr[i].val.type;
if (username_arr[i].val.permissions) {
for (let j = 0; j < username_arr[i].val.permissions.length; j++) {
payload["value"] = username_arr[i].key + username_arr[i].val.permissions[j].streamId;
payload["text"] = username_arr[i].val.permissions[j].streamId;
}
}
usernames[username_arr[i].key].push(payload);
}
return usernames;
},
},
methods: {
clickAll(e, keyv) {
if (e && e.includes(keyv)) {
this.selectedStreams[keyv] = this.loggedInUsernamesf[keyv].map(
opt => {
return opt.value
}
);
}
console.log(this.selectedStreams[keyv]);
}
}
}
</script>
<style scoped>
</style>
Child Component
<template>
<div style="text-align: left;">
<b-form-checkbox-group style="padding-left: 0;"
id="flavors"
class="ml-4"
stacked
v-model="role"
:main="main"
>
<b-form-checkbox
class="font-weight-bold main"
:main="main"
:value="main"
@input="checkAll(main)"
>{{ name[0].main }}</b-form-checkbox>
<b-form-checkbox
v-for="opt in displayStreams"
:key="opt.value"
:value="opt.value"
>{{ opt.text }}</b-form-checkbox>
</b-form-checkbox-group>
</div>
</template>
<script>
export default {
name:"StreamCheckBox",
props: {
value: {
type: Array,
},
name: {
type: Array,
},
main:{
type:String
}
},
computed:{
role: {
get: function(){
return this.value;
},
set: function(val) {
this.$emit('input', val);
}
},
displayStreams: function () {
return this.name.filter(i => i.value)
},
},
methods:{
checkAll(val)
{
this.$emit('clickAll', val);
}
}
}
</script>
Upvotes: 3
Views: 1994
Reputation: 4801
First of all, I am not sure what is the purpose of having props
in your parent component. I think you could just remove props
from your parent and leave in the child component only.
Second of all, the reason for not triggering the changes could be that you are dealing with arrays, for that you could set a deep watcher
in your child component:
export default {
props: {
value: {
type: Array,
required: true,
},
},
watch: {
value: {
deep: true,
//handle the change
handler() {
console.log('array updated');
}
}
}
}
You can find more info here and here.
Upvotes: 3