如何将复选框绑定到 Vuex 商店?
How to bind checkboxes to Vuex store?
我有一个包含一些复选框的组件。我需要能够访问我的 Vue 应用程序中的其他组件检查了哪些复选框,但我终其一生都无法弄清楚(也无法在线查找)如何将复选框正确连接到我的 Vuex 商店。
将组件内的复选框连接到 Vuex 存储的正确方法是什么,以便它们的行为就像复选框通过 v-model 连接到组件数据一样?
这是我正在尝试做的事情的起点(在非常非常基本的意义上)
https://jsfiddle.net/9fpuctnL/
<div id="colour-selection">
<colour-checkboxes></colour-checkboxes>
</div>
<template id="colour-checkboxes-template">
<div class="colours">
<label>
<input type="checkbox" value="green" v-model="colours"> Green
</label>
<label>
<input type="checkbox" value="red" v-model="colours"> Red
</label>
<label>
<input type="checkbox" value="blue" v-model="colours"> Blue
</label>
<label>
<input type="checkbox" value="purple" v-model="colours"> Purple
</label>
<chosen-colours></chosen-colours>
</div>
</template>
<template id="chosen-colours-template">
<div class="selected-colours">
{{ colours }}
</div>
</template>
const store = new Vuex.Store({
state: {
colours: []
}
});
Vue.component('colour-checkboxes', {
template: "#colour-checkboxes-template",
data: function() {
return {
colours: []
}
}
});
Vue.component('chosen-colours', {
template: "#chosen-colours-template",
computed: {
colours() {
return store.state.colours
}
}
});
const KeepTalkingSolver = new Vue({
el: "#colour-selection"
});
目的是让在 colour-checkboxes 组件中选择的颜色输出到 chosen-colours 组件,通过 Vuex store。
您可以使用 computed property with getter as vuex getter and setter in computed property which will call a mutation 状态 属性 来执行此操作。
您可以看到这个 here 的示例,其中包含双向计算 属性:
<input v-model="message">
// ...
computed: {
message: {
get () {
return this.$store.state.obj.message
},
set (value) {
this.$store.commit('updateMessage', value)
}
}
}
您应该删除数据中的 colors = []。
我想提供一个实际使用复选框的答案。
这里列出了一种可能的解决方案:
一个更简单的解决方案可以实现如下:
<div v-for="tenant in tenants"
v-bind:key="tenant.id"
class="form-group form-check">
<input type="checkbox"
class="form-check-input"
v-bind:id="tenant.id"
v-bind:value="tenant.name"
@change="updateSelectedTenants">
这里的关键是使用 on-change 调用一个方法,它会将一个事件传递给该方法,其中包含进行更改所需的所有详细信息。
@change 函数:
updateSelectedTenants(e) {
console.log('e', e.target)
console.log('e', e.target.value)
this.$store.dispatch('updateSelectedTenants', e.target)
}
这里我想要值,在本例中将是租户名称,但进一步检查目标也会给出 'id',以及复选框是否为 'checked' 或未选中。
在商店那边,我们可以操作 'selectedTenants' 数组:
updateSelectedTenants (context, tenant) {
if(tenant.checked) {
// Tenant checked, so we want to add this tenant to our list of 'selectedTenants'
context.commit('addSelectedTenant', { id: tenant.id, name: tenant.value })
} else {
// otherwise, remove the tenant from our list
context.commit('removeSelectedTenant', tenant.id)
}
}
这里是实际的突变体:
addSelectedTenant (state, tenant) {
this.state.selectedTenants.push(tenant)
},
removeSelectedTenant (state, id) {
this.state.selectedTenants = this.state.selectedTenants.filter(tenant => {
return tenant.id != id
})
vuejs 文档很棒,但有时它们可以通过真实世界的示例来理解。我不认为认为可以使用计算值、get()、set()...来实现上述目标,但我希望看到一个可以实现的解决方案。
根据需要使用@change
更新Vuex:
HTML:
<input
v-for='item in items'
@change='update_checkboxes'
v-model='selected_checkboxes'
:value='item.id'
type='checkbox
/>
<label>{{item.name}}</label>
JS:
data: function(){
return {
selected_checkboxes: [] // or set initial state from Vuex with a prop passed in
}
},
methods: {
update_checkboxes: function(){
this.$store.commit('update_checkboxes', this.selected_checkboxes)
}
}
好的,我被要求展示我的解决方案。这是on jsfiddle
html 是:
<div id="app">
<label v-for="brother in ['Harpo','Groucho','Beppo']">
<input type='checkbox' v-model='theBrothers' v-bind:value='brother' />
{{ brother }}
</label>
<div>
You have checked: {{ theBrothers }}
</div>
</div>
js 是:
const store = new Vuex.Store({
state: {
theBrothers: []
},
})
new Vue({
el: "#app",
store: store,
computed: {
theBrothers: {
set(val){this.$store.state.theBrothers = val},
get(){ return this.$store.state.theBrothers }
}
},
})
基于@Saurabh 的解决方案 - 使用 actions 和 getters 而不是直接访问 vuex 状态很重要 - 这将确保整个应用程序的一致性。
<p>Mega test: <input type="checkbox" v-model="mega" /></p>
computed: {
mega: {
get () {
return this.$store.getters.mega
},
set (value) {
this.$store.dispatch('updateMega', value)
}
}
}
const store = new Vuex.Store({
state: {
mega: false
},
getters: {
mega (state) {
return state.mega
}
},
mutations: {
updateMega (state, value) {
state.mega = value
}
},
actions: {
updateMega (context, value) {
context.commit('updateMega', value)
}
}
})
2021 - 简单易读,充分利用 Vue/Vuex...
的力量
一个简单的问题有很多复杂的答案。 运行 下面的代码片段可以看到它的实际效果。
长话短说,你需要做的就是获取一个状态(下图names
),创建一个突变(下图setNames
)来设置它,然后绑定v-model
到具有 getter 和 setter 的 computed
(下面的 selectedNames
),getter 获得状态 names
,并且setter 调用突变 setNames
.
在我看来,这是解决此问题的最干净的解决方案,因为它遵循 Vue/Vuex 的自然模式以及复选框的典型实现方式。
这里的其他答案试图直接改变状态而不进行突变,而其他一些答案避免使用 v-model
这会带来预选值的问题并且需要更多代码,最后接受的答案没有'甚至显示有关如何实现它的任何 HTML 模板代码。
这是解决 所有 这些问题的有效解决方案:
const store = new Vuex.Store({
state: {
names: ['Max'],
},
mutations: {
setNames(state, names) {
state.names = names;
}
}
});
new Vue({
el: '#app',
store,
computed: {
selectedNames: {
get: function() {
return this.$store.state.names;
},
set: function(val) {
console.log(val);
this.$store.commit('setNames', val);
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://unpkg.com/vuex@3.6.2/dist/vuex.js"></script>
<div id="app">
<div>
<input type="checkbox" v-model="selectedNames" :value="'John'" id="checkbox-1" />
<label for="checkbox-1">Click me to add my value to the state</label>
<br />
<input type="checkbox" v-model="selectedNames" :value="'Max'" id="checkbox-2" />
<label for="checkbox-2">I am preselected since my value already exists in the state <code>names</code> array</label>
<div>State: <strong>{{ names }}</strong></div>
</div>
</div>
我有一个包含一些复选框的组件。我需要能够访问我的 Vue 应用程序中的其他组件检查了哪些复选框,但我终其一生都无法弄清楚(也无法在线查找)如何将复选框正确连接到我的 Vuex 商店。
将组件内的复选框连接到 Vuex 存储的正确方法是什么,以便它们的行为就像复选框通过 v-model 连接到组件数据一样?
这是我正在尝试做的事情的起点(在非常非常基本的意义上)
https://jsfiddle.net/9fpuctnL/
<div id="colour-selection">
<colour-checkboxes></colour-checkboxes>
</div>
<template id="colour-checkboxes-template">
<div class="colours">
<label>
<input type="checkbox" value="green" v-model="colours"> Green
</label>
<label>
<input type="checkbox" value="red" v-model="colours"> Red
</label>
<label>
<input type="checkbox" value="blue" v-model="colours"> Blue
</label>
<label>
<input type="checkbox" value="purple" v-model="colours"> Purple
</label>
<chosen-colours></chosen-colours>
</div>
</template>
<template id="chosen-colours-template">
<div class="selected-colours">
{{ colours }}
</div>
</template>
const store = new Vuex.Store({
state: {
colours: []
}
});
Vue.component('colour-checkboxes', {
template: "#colour-checkboxes-template",
data: function() {
return {
colours: []
}
}
});
Vue.component('chosen-colours', {
template: "#chosen-colours-template",
computed: {
colours() {
return store.state.colours
}
}
});
const KeepTalkingSolver = new Vue({
el: "#colour-selection"
});
目的是让在 colour-checkboxes 组件中选择的颜色输出到 chosen-colours 组件,通过 Vuex store。
您可以使用 computed property with getter as vuex getter and setter in computed property which will call a mutation 状态 属性 来执行此操作。
您可以看到这个 here 的示例,其中包含双向计算 属性:
<input v-model="message">
// ...
computed: {
message: {
get () {
return this.$store.state.obj.message
},
set (value) {
this.$store.commit('updateMessage', value)
}
}
}
您应该删除数据中的 colors = []。
我想提供一个实际使用复选框的答案。
这里列出了一种可能的解决方案:
一个更简单的解决方案可以实现如下:
<div v-for="tenant in tenants"
v-bind:key="tenant.id"
class="form-group form-check">
<input type="checkbox"
class="form-check-input"
v-bind:id="tenant.id"
v-bind:value="tenant.name"
@change="updateSelectedTenants">
这里的关键是使用 on-change 调用一个方法,它会将一个事件传递给该方法,其中包含进行更改所需的所有详细信息。
@change 函数:
updateSelectedTenants(e) {
console.log('e', e.target)
console.log('e', e.target.value)
this.$store.dispatch('updateSelectedTenants', e.target)
}
这里我想要值,在本例中将是租户名称,但进一步检查目标也会给出 'id',以及复选框是否为 'checked' 或未选中。
在商店那边,我们可以操作 'selectedTenants' 数组:
updateSelectedTenants (context, tenant) {
if(tenant.checked) {
// Tenant checked, so we want to add this tenant to our list of 'selectedTenants'
context.commit('addSelectedTenant', { id: tenant.id, name: tenant.value })
} else {
// otherwise, remove the tenant from our list
context.commit('removeSelectedTenant', tenant.id)
}
}
这里是实际的突变体:
addSelectedTenant (state, tenant) {
this.state.selectedTenants.push(tenant)
},
removeSelectedTenant (state, id) {
this.state.selectedTenants = this.state.selectedTenants.filter(tenant => {
return tenant.id != id
})
vuejs 文档很棒,但有时它们可以通过真实世界的示例来理解。我不认为认为可以使用计算值、get()、set()...来实现上述目标,但我希望看到一个可以实现的解决方案。
根据需要使用@change
更新Vuex:
HTML:
<input
v-for='item in items'
@change='update_checkboxes'
v-model='selected_checkboxes'
:value='item.id'
type='checkbox
/>
<label>{{item.name}}</label>
JS:
data: function(){
return {
selected_checkboxes: [] // or set initial state from Vuex with a prop passed in
}
},
methods: {
update_checkboxes: function(){
this.$store.commit('update_checkboxes', this.selected_checkboxes)
}
}
好的,我被要求展示我的解决方案。这是on jsfiddle
html 是:
<div id="app">
<label v-for="brother in ['Harpo','Groucho','Beppo']">
<input type='checkbox' v-model='theBrothers' v-bind:value='brother' />
{{ brother }}
</label>
<div>
You have checked: {{ theBrothers }}
</div>
</div>
js 是:
const store = new Vuex.Store({
state: {
theBrothers: []
},
})
new Vue({
el: "#app",
store: store,
computed: {
theBrothers: {
set(val){this.$store.state.theBrothers = val},
get(){ return this.$store.state.theBrothers }
}
},
})
基于@Saurabh 的解决方案 - 使用 actions 和 getters 而不是直接访问 vuex 状态很重要 - 这将确保整个应用程序的一致性。
<p>Mega test: <input type="checkbox" v-model="mega" /></p>
computed: {
mega: {
get () {
return this.$store.getters.mega
},
set (value) {
this.$store.dispatch('updateMega', value)
}
}
}
const store = new Vuex.Store({
state: {
mega: false
},
getters: {
mega (state) {
return state.mega
}
},
mutations: {
updateMega (state, value) {
state.mega = value
}
},
actions: {
updateMega (context, value) {
context.commit('updateMega', value)
}
}
})
2021 - 简单易读,充分利用 Vue/Vuex...
的力量一个简单的问题有很多复杂的答案。 运行 下面的代码片段可以看到它的实际效果。
长话短说,你需要做的就是获取一个状态(下图names
),创建一个突变(下图setNames
)来设置它,然后绑定v-model
到具有 getter 和 setter 的 computed
(下面的 selectedNames
),getter 获得状态 names
,并且setter 调用突变 setNames
.
在我看来,这是解决此问题的最干净的解决方案,因为它遵循 Vue/Vuex 的自然模式以及复选框的典型实现方式。
这里的其他答案试图直接改变状态而不进行突变,而其他一些答案避免使用 v-model
这会带来预选值的问题并且需要更多代码,最后接受的答案没有'甚至显示有关如何实现它的任何 HTML 模板代码。
这是解决 所有 这些问题的有效解决方案:
const store = new Vuex.Store({
state: {
names: ['Max'],
},
mutations: {
setNames(state, names) {
state.names = names;
}
}
});
new Vue({
el: '#app',
store,
computed: {
selectedNames: {
get: function() {
return this.$store.state.names;
},
set: function(val) {
console.log(val);
this.$store.commit('setNames', val);
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://unpkg.com/vuex@3.6.2/dist/vuex.js"></script>
<div id="app">
<div>
<input type="checkbox" v-model="selectedNames" :value="'John'" id="checkbox-1" />
<label for="checkbox-1">Click me to add my value to the state</label>
<br />
<input type="checkbox" v-model="selectedNames" :value="'Max'" id="checkbox-2" />
<label for="checkbox-2">I am preselected since my value already exists in the state <code>names</code> array</label>
<div>State: <strong>{{ names }}</strong></div>
</div>
</div>