简体   繁体   中英

How to make v-switch mandatory in vuetify?

I have three v-switch with values. each of them is bind to switch1 property.

When I click on the v-switch is remove/add value to switch1 .

How to do v-switch mandatory? meaning its impossible to uncheck all. at least one must be selected.

I think some event like if switch1 will be array of empty then cancel the switch click.

I try to do this with change event but I e come as Boolean and not the event.

 new Vue({ el: '#app', vuetify: new Vuetify(), data () { return { switch1: ['val1', 'val2', 'val3'], change: (e) => { console.log({ e })} } }, })
 <link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet"/> <link href="https://cdn.jsdelivr.net/npm/@mdi/font@4.x/css/materialdesignicons.min.css" rel="stylesheet"/> <link href="https://fonts.googleapis.com/css?family=Material+Icons" rel="stylesheet"/> <link href="https://cdn.jsdelivr.net/npm/vuetify@2.1.14/dist/vuetify.min.css" rel="stylesheet"/> <script src="https://cdn.jsdelivr.net/npm/babel-polyfill/dist/polyfill.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js"></script> <script src="https://cdn.jsdelivr.net/npm/vuetify@2.1.14/dist/vuetify.min.js"></script> <div id="app"> <v-app id="inspire"> <v-container class="px-0" fluid> {{ switch1 }} <v-switch v-model="switch1" label="val1" value="val1" @change="change($event)" ></v-switch> <v-switch v-model="switch1" label="val2" value="val2" @change="change($event)" ></v-switch> <v-switch v-model="switch1" label="val3" value="val3" @change="change($event)" ></v-switch> </v-container> </v-app> </div>

I'd use a watcher , and if none of the switches are true , then set the first one to true .

 new Vue({ el: '#app', vuetify: new Vuetify(), data() { return { switch1: ['val1', 'val2', 'val3'], } }, methods: { change: (e) => { /*console.log({ e })*/ } }, watch: { switch1(newVal, oldVal) { if (newVal.length) { this.switch1 = newVal } else { setTimeout(() => this.switch1 = oldVal) } } } })
 <link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet" /> <link href="https://cdn.jsdelivr.net/npm/@mdi/font@4.x/css/materialdesignicons.min.css" rel="stylesheet" /> <link href="https://fonts.googleapis.com/css?family=Material+Icons" rel="stylesheet" /> <link href="https://cdn.jsdelivr.net/npm/vuetify@2.1.14/dist/vuetify.min.css" rel="stylesheet" /> <script src="https://cdn.jsdelivr.net/npm/babel-polyfill/dist/polyfill.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js"></script> <script src="https://cdn.jsdelivr.net/npm/vuetify@2.1.14/dist/vuetify.min.js"></script> <div id="app"> <v-app id="inspire"> <v-container class="px-0" fluid> {{ switch1 }} <v-switch v-model="switch1" label="val1" value="val1" @change="change($event)"></v-switch> <v-switch v-model="switch1" label="val2" value="val2" @change="change($event)"></v-switch> <v-switch v-model="switch1" label="val3" value="val3" @change="change($event)"></v-switch> </v-container> </v-app> </div>

The other thing is that I wouldn't put @change event in data - I think they are better placed in the methods .

EDIT

I updated the snippet to offer a more general solution. Thanks for the setTimeout(() => this.switch1 = oldVal) comment @JonSud!

This may not exactly answer the question, but is an option to validate a section of switches and incorporating an error message when no switches are active.

This is accomplished by having an Array of switch values, switches , which tracks the state of each switch.

Within a computed property, noneSelected , we can filter the Array's values based on overall truthiness. When the length of the filtered Array is zero (0) we display the error message via v-if targeting the computed value.

 Vue.config.productionTip = false; new Vue({ el: '#app', vuetify: new Vuetify(), data () { return { switches: [false, false, false] } }, computed: { noneSelected() { return this.switches.filter(x => !!x).length === 0; } }, methods: { change: (e) => { console.log('event', e)} } });
 <link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet"/> <link href="https://cdn.jsdelivr.net/npm/@mdi/font@4.x/css/materialdesignicons.min.css" rel="stylesheet"/> <link href="https://fonts.googleapis.com/css?family=Material+Icons" rel="stylesheet"/> <link href="https://cdn.jsdelivr.net/npm/vuetify@2.1.14/dist/vuetify.min.css" rel="stylesheet"/> <script src="https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js"></script> <script src="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.js"></script> <div id="app"> <v-app id="inspire"> <v-container class="px-0" fluid> {{ switches }} <p v-if="noneSelected" style="color: red">At least one switch needs to be active.</p> <v-switch v-model="switches[0]" label="val1" @change="change($event)" ></v-switch> <v-switch v-model="switches[1]" label="val2" @change="change($event)" ></v-switch> <v-switch v-model="switches[2]" label="val3" @change="change($event)" ></v-switch> </v-container> </v-app> </div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM