BootstrapVue(b-form-checkbox) 如何收集选中的复选框?

How to collect selected BootstrapVue (b-form-checkbox) check boxes?

我正在开发 Nuxt.js (Vue.js) 应用程序,模式对话框如下所示:

Basket.vue 组件的代码如下所示:

<template lang="pug">
  b-container(v-if='products.length > 0')
    b-row
      b-col(:cols="8")
        b-container
          b-row
            b-list-group
              b-list-group-item.flex-column.align-items-start(v-for="(product, index) in products" :key="index")
                b-container
                  b-row
                    b-col(:cols="1").d-flex.align-items-center.justify-content-center
                      b-form-checkbox {{ index + 1 }}
                    b-col(:cols="11")
                      basket-item(:product="product")
          b-row.row-middle-style
            b-button.close(type='button' aria-label='Close' @click="onRemoveItem")
              span(aria-hidden='true') &times;
                u Remove selected items
            b-button(type='button' @click="onContinue()").btn.btn-lg.buy__button Продолжить покупки
          b-row
            div
              hr
              | * доставка будет осуществлена из Санкт-Петербурга;
              br
              | * наш менеджер свяжется с вами сразу после обработки заказа;
  ...
</template>

<script lang="ts">
import Vue from 'vue'
import BasketItem from './BasketItem.vue'
import { mapState, mapActions } from 'vuex'

export default Vue.extend({
  components: {
    BasketItem,
  },
  data() {
    return {
    }
  },
  computed: {
    ...mapState(['products']),
  },
  methods: {
    ...mapActions({
      onRemoveItem: 'removeItem',
    }),
  },
})
</script>

<style lang="sass">
  ...
</style>

BasketItem.vue 组件的代码如下所示:

<template lang="pug">
  b-container
    b-row.style-item-row
      b-col(:cols="3")
        img(:src="product.image" :alt="product.alt")
      b-col(:cols="4")
        div {{ product.name }}
        div {{ product.description }}
      b-col(:cols="4")
        div Цена {{ product.price }}
        div Количество {{ product.quantity }}
      b-col(:cols="1")
        b-button.close(type='button' aria-label='Close' @click="onRemoveItem(product.id)")
          span(aria-hidden='true') &times;
</template>

<script lang="ts">
import Vue from 'vue'
import { mapActions } from 'vuex'

export default Vue.extend({
  props: {
    product: {
      type: Object,
    },
  },
  data() {
    return {
    }
  },
  methods: {
    ...mapActions({
      onRemoveItem: 'removeItem',
    }),
  },
})
</script>

<style lang="sass">
  ...
</style>

Vuex 代码如下所示:

import * as mutationTypes from './mutation_types'

export const state = () => ({
  products: [
    {
      id: 1,
      image: 'https://licota.ru/system/product_images/attachments/5d9b/1781/6332/3406/9d00/2a31/small/8bfa7c2c-c7c7-11e4-80f4-002590d99cf6.jpg?1570445184',
      alt: 'Товар 1',
      name: 'Товар 1',
      description: 'Описание 1',
      price: 100,
      quantity: 4
    },
    {
      id: 2,
      image: 'https://licota.ru/system/product_images/attachments/5d9b/329f/6332/3406/9d00/9336/small/e6a69bba-3450-11e9-812c-002590d99cf6.jpg?1570452124',
      alt: 'Товар 2',
      name: 'Товар 2',
      description: 'Описание 2',
      price: 200,
      quantity: 7
    }
  ]
})

export const getters = {
}

export const actions = {
  removeItem({ commit }, id) {
    commit(mutationTypes.REMOVE_ITEM, id)
  }
}

export const mutations = {
  [mutationTypes.REMOVE_ITEM] (state, id) {
    state.products = state.products.filter(x => {
      return x.id != id
    })
  }
}

如您所见,我有一个项目列表(有两个)。每一个前面都是BootstrapVue(b-form-checkbox)复选框。我可以 select 其中任何一个,然后单击“删除 selected 项目”。之后,它们将被删除。该操作的代码此时不存在。可以看到的Vuex代码是指点击item右上角的“x”

我的问题是如何收集 selected 项目,这些项目是选中的复选框以删除适当的项目?

更新:

我已经尝试过您的建议,但没有用。最有可能我做错了什么。 实际上,当我查看 DevTools 中的 Vue 部分时,isChecked computed 属性 在单击复选框后没有改变。 代码如下所示:

Basket.vue:

<template lang="pug">
  b-container(v-if='products.length > 0')
    b-row
      b-col(:cols="8")
        b-container
          b-row
            b-list-group
              b-list-group-item.flex-column.align-items-start(
                v-for="(product, index) in products"
                :key="product.id"
                v-bind="{...product}"
                v-on="{'update:checked': (data) => handleSetChecked(data)}"
              )
                b-container.set_pad
                  b-row
                    b-col(:cols="12").d-flex.align-items-center.justify-content-center
                      basket-item(:product="product" :productIndex="index")
          b-row.row-middle-style
            b-button.close(type='button' aria-label='Close' @click="onRemoveSelectedItems")
              span(aria-hidden='true') &times;
                u Удалить выбранное
            b-button(type='button' @click="onContinue()").btn.btn-lg.buy__button Продолжить покупки
          b-row
            div
              hr
              | * доставка будет осуществлена из Санкт-Петербурга;
              br
              | * наш менеджер свяжется с вами сразу после обработки заказа;
  ...
</template>

<script>
import Vue from 'vue'
import BasketItem from './BasketItem.vue'
import { mapActions } from 'vuex'

export default Vue.extend({
  components: {
    BasketItem,
  },
  data() {
    return {}
  },
  computed: {
    products() {
      return this.$store.getters.getProducts
    },
    toRemove() {
      return this.$store.getters.getProductsToRemove
    },
  },
  methods: {
    ...mapActions({
      onRemoveItem: 'removeItem',
    }),
    handleSetChecked(data) {
      this.$store.dispatch("setToRemove", data)
    },
    handleRemoveItems() {
      this.$store.dispatch("removeSelected")
    },
    onRemoveSelectedItems() {
      this.handleRemoveItems()
    },
  },
})
</script>

BasketItem.vue:

<template lang="pug">
  b-container
    b-row.style-item-row
      b-col(:cols="1").d-flex.align-items-center.justify-content-center
        b-form-checkbox(v-model="isChecked") {{ productIndex + 1 }}
      b-col(:cols="3")
        img(:src="product.image" :alt="product.alt")
      b-col(:cols="3")
        div {{ product.title }}
        div {{ product.description }}
      b-col(:cols="4")
        div Цена {{ product.price }}
        div Количество {{ product.quantity }}
      b-col(:cols="1")
        b-button.close(type='button' aria-label='Close' @click="onRemoveItem(product.id)")
          span(aria-hidden='true') &times;
</template>

<script>
import Vue from 'vue'
import { mapActions } from 'vuex'

export default Vue.extend({
  props: {
    product: {
      type: Object,
    },
    productIndex: {
      type: Number,
    },
  },
  data() {
    return {}
  },
  computed: {
    isChecked: {
      get() {
        return this.product.checked
      },
      set(val) {
        this.$emit("update:checked", {
          id: this.product.id,
          checked: val,
        })
      }
    },
  },
  methods: {
    ...mapActions({
      onRemoveItem: 'removeItem',
    }),
  },
})
</script>

Vuex:

import * as mutationTypes from './mutation_types'

export const state = () => ({
  products: [
    {
      id: 1,
      image: 'https://licota.ru/system/product_images/attachments/5d9b/1781/6332/3406/9d00/2a31/small/8bfa7c2c-c7c7-11e4-80f4-002590d99cf6.jpg?1570445184',
      alt: 'Товар 1',
      title: 'Товар 1',
      description: 'Описание 1',
      price: 100,
      quantity: 4,
      checked: false
    },
    {
      id: 2,
      image: 'https://licota.ru/system/product_images/attachments/5d9b/329f/6332/3406/9d00/9336/small/e6a69bba-3450-11e9-812c-002590d99cf6.jpg?1570452124',
      alt: 'Товар 2',
      title: 'Товар 2',
      description: 'Описание 2',
      price: 200,
      quantity: 7,
      checked: false
    }
  ]
})

export const getters = {
  getProducts: state => state.products,
  getProductsToRemove: state => state.products.filter(({
    checked
  }) => checked),
}

export const actions = {
  setToRemove({
    commit
  }, data) {
    commit("SET_TO_REMOVE", data)
  },
  removeSelected({
    commit
  }) {
    commit("REMOVE_SELECTED")
  },
  removeItem({ commit }, id) {
    commit(mutationTypes.REMOVE_ITEM, id)
  },
}

export const mutations = {
  SET_TO_REMOVE(state, {
    id,
    checked
  }) {
    state.products = state.products.map(product => {
      if (product.id === id) {
        return {
          ...product,
          checked,
        }
      } else {
        return product
      }
    })
  },
  REMOVE_SELECTED(state) {
    state.products = state.products.filter(({
      checked
    }) => !checked)
  },
  [mutationTypes.REMOVE_ITEM] (state, id) {
    state.products = state.products.filter(x => {
      return x.id != id
    })
  },
}

对“表单复选框输入”的引用:

https://bootstrap-vue.org/docs/components/form-checkbox

我建议您仔细考虑您的代码,并准备好逻辑步骤:

  1. 您根据 Vuex 商店中的列表列出了 UI 项列表
  2. 每个 UI 项目都有一个切换(复选框),用于设置它显示的项目的某些部分状态(是否应该删除)
  3. 通过点击开关(复选框),项目的状态应该改变
  4. 通过点击按钮(移除),Vuex 状态应该改变:移除所有状态满足条件的项目(它的 toRemove 状态是 true

就是这样。更简单地说:不要通过选择一些 UI 元素来工作。通过更新 UI 元素所基于的数据的状态来工作。 (让 Vue 的响应式功能完成剩下的工作。)

第一个片段很简单,没有使用 Vuex:

Vue.component('RowWithCb', {
  props: ["id", "title", "checked"],
  computed: {
    isChecked: {
      get() {
        return this.checked
      },
      set(val) {
        this.$emit("update:checked", val)
      }
    },
  },
  template: `
    <b-row>
      <b-col
        class="d-flex"
      >
        <div>
          <b-checkbox
            v-model="isChecked"
          />
        </div>
        <div>
          {{ title }}
        </div>
      </b-col>
    </b-row>
  `
})
new Vue({
  el: "#app",
  computed: {
    toRemove() {
      return this.rows.filter(({
        checked
      }) => checked)
    },
    toKeep() {
      return this.rows.filter(({
        checked
      }) => !checked)
    },
  },
  data() {
    return {
      rows: [{
          id: 1,
          title: "Row 1",
          checked: false,
        },
        {
          id: 2,
          title: "Row 2",
          checked: false,
        }
      ]
    }
  },
  template: `
    <b-container>
      <b-row>
        <b-col>
          <h3>Items:</h3>
          <row-with-cb
            v-for="row in rows"
            :key="row.id"
            v-bind="{
             ...row
            }"
            :checked.sync="row.checked"
          />
        </b-col>
      </b-row>
      <hr />
      <b-row>
        <b-col>
          <h4>To keep:</h4>
          {{ toKeep }}
        </b-col>
        <b-col>
          <h4>To remove:</h4>
          {{ toRemove }}
        </b-col>
      </b-row>
    </b-container>
  `
})
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.min.css" />
<script src="//polyfill.io/v3/polyfill.min.js?features=es2015%2CIntersectionObserver" crossorigin="anonymous"></script>
<script src="//unpkg.com/vue@latest/dist/vue.min.js"></script>
<script src="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.min.js"></script>
<script src="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue-icons.min.js"></script>
<div id="app"></div>

现在使用 VUEX

const initialState = () => ({
  rows: [{
      id: 1,
      title: "Row 1",
      checked: false,
    },
    {
      id: 2,
      title: "Row 2",
      checked: false,
    }
  ]
})

const store = new Vuex.Store({
  state: initialState(),
  mutations: {
    RESET(state) {
      const init = initialState()
      for (key in init) {
        state[key] = init[key]
      }
    },
    SET_TO_REMOVE(state, {
      id,
      checked
    }) {
      state.rows = state.rows.map(row => {
        if (row.id === id) {
          return {
            ...row,
            checked,
          }
        } else {
          return row
        }
      })
    },
    REMOVE_SELECTED(state) {
      state.rows = state.rows.filter(({
        checked
      }) => !checked)
    },
  },
  actions: {
    reset({
      commit
    }) {
      commit("RESET")
    },
    setToRemove({
      commit
    }, data) {
      commit("SET_TO_REMOVE", data)
    },
    removeSelected({
      commit
    }) {
      commit("REMOVE_SELECTED")
    },
  },
  getters: {
    getRows: state => state.rows,
    getRowsToRemove: state => state.rows.filter(({
      checked
    }) => checked),
    getRowsToKeep: state => state.rows.filter(({
      checked
    }) => !checked),
  }
})

Vue.component('RowWithCb', {
  props: ["id", "title", "checked"],
  computed: {
    isChecked: {
      get() {
        return this.checked
      },
      set(val) {
        this.$emit("update:checked", {
          id: this.id,
          checked: val,
        })
      }
    },
  },
  template: `
    <b-row>
      <b-col
        class="d-flex"
      >
        <div>
          <b-checkbox
            v-model="isChecked"
          />
        </div>
        <div>
          {{ title }}
        </div>
      </b-col>
    </b-row>
  `
})
new Vue({
  el: "#app",
  store,
  computed: {
    rows() {
      return this.$store.getters.getRows
    },
    toRemove() {
      return this.$store.getters.getRowsToRemove
    },
    toKeep() {
      return this.$store.getters.getRowsToKeep
    },
  },
  methods: {
    handleSetChecked(data) {
      this.$store.dispatch("setToRemove", data)
    },
    handleRemoveItems() {
      this.$store.dispatch("removeSelected")
    },
    handleResetStore() {
      this.$store.dispatch("reset")
    },
  },
  template: `
    <b-container>
      <b-row>
        <b-col>
          <h3>Items:</h3>
          <row-with-cb
            v-for="row in rows"
            :key="row.id"
            v-bind="{
             ...row
            }"
            v-on="{
              'update:checked': (data) => handleSetChecked(data)
            }"
          />
        </b-col>
      </b-row>
      <hr />
      <b-row>
        <b-col>
          <h4>To keep:</h4>
          {{ toKeep }}
        </b-col>
        <b-col>
          <h4>To remove:</h4>
          {{ toRemove }}
        </b-col>
      </b-row>
      <hr />
      <b-row>
        <b-col>
          <b-button
            @click="handleRemoveItems"
          >
            REMOVE
          </b-button>
          <b-button
            @click="handleResetStore"
          >
            RESET
          </b-button>
        </b-col>
      </b-row>
    </b-container>
  `
})
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.min.css" />
<script src="//polyfill.io/v3/polyfill.min.js?features=es2015%2CIntersectionObserver" crossorigin="anonymous"></script>
<script src="//unpkg.com/vue@latest/dist/vue.min.js"></script>
<script src="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.min.js"></script>
<script src="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue-icons.min.js"></script>
<script src="https://unpkg.com/vuex"></script>
<div id="app"></div>

你可以看到我没有弄乱任何复选框或 UI 元素(唯一的区别是 id 也是从 UI 组件发出的)。所有功能都已移至 Vuex 商店,仅此而已。 (比第一个片段更冗长,因为我添加了删除和重置功能。)


让我们分解一下

1。您需要一个列出项目的组件。在这种情况下,让我们为此使用根组件:

new Vue({
  el: "#app",
  data() {
    return {
      baseItems: [{
          id: "item_1",
          name: "Item 1",
        },
        {
          id: "item_2",
          name: "Item 2",
        },
      ]
    }
  },
  computed: {
    items() {
      return this.baseItems
    },
  },
  template: `
    <ul>
      <li
        v-for="item in items"
        :key="item.id"
      >
        {{ item.name }}
      </li>
    </ul>
  `
})
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.min.css" />
<script src="//polyfill.io/v3/polyfill.min.js?features=es2015%2CIntersectionObserver" crossorigin="anonymous"></script>
<script src="//unpkg.com/vue@latest/dist/vue.min.js"></script>
<script src="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.min.js"></script>
<script src="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue-icons.min.js"></script>
<div id="app"></div>

我故意把 items 写成 computed - 切换到 Vuex 会很容易。

2。您知道您列出的项目会比这复杂一点,所以让我们创建一个 component 来处理它们即将到来的复杂性:

Vue.component('ListItem', {
  props: ['id', 'name'],
  template: `
    <li>
      {{ name }}
    </li>
  `
})

new Vue({
  el: "#app",
  data() {
    return {
      baseItems: [{
          id: "item_1",
          name: "Item 1",
        },
        {
          id: "item_2",
          name: "Item 2",
        },
      ]
    }
  },
  computed: {
    items() {
      return this.baseItems
    },
  },
  template: `
    <ul>
      <list-item
        v-for="item in items"
        :key="item.id"
        v-bind="{
          ...item,
        }"
      />
    </ul>
  `
})
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.min.css" />
<script src="//polyfill.io/v3/polyfill.min.js?features=es2015%2CIntersectionObserver" crossorigin="anonymous"></script>
<script src="//unpkg.com/vue@latest/dist/vue.min.js"></script>
<script src="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.min.js"></script>
<script src="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue-icons.min.js"></script>
<div id="app"></div>

3。让我们让它们可移动 - 一个接一个或一堆:

Vue.component('ListItem', {
  props: ['id', 'name', 'toRemove'],
  computed: {
    selected: {
      get() {
        return this.toRemove
      },
      set(val) {
        this.$emit('update:to-remove', val)
      }
    },
  },
  template: `
    <li>
      <input
        type="checkbox"
        v-model="selected"
      />
      {{ name }}
    </li>
  `
})

new Vue({
  el: "#app",
  data() {
    return {
      baseItems: [{
          id: "item_1",
          name: "Item 1",
          toRemove: false,
        },
        {
          id: "item_2",
          name: "Item 2",
          toRemove: false,
        },
      ]
    }
  },
  computed: {
    items() {
      return this.baseItems
    },
  },
  methods: {
    handleRemoveSelected() {
      this.baseItems = this.baseItems.filter(item => !item.toRemove)
    },
  },
  template: `
    <div>
      So, it's easier to follow:
      {{ items }}
      <hr />
      <ul>
        <list-item
          v-for="item in items"
          :key="item.id"
          v-bind="{
            ...item,
          }"
          :toRemove.sync="item.toRemove"
        />
      </ul>
      <b-button
        @click="handleRemoveSelected"
      >
        REMOVE SELECTED
      </b-button>
    </div>
  `
})
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.min.css" />
<script src="//polyfill.io/v3/polyfill.min.js?features=es2015%2CIntersectionObserver" crossorigin="anonymous"></script>
<script src="//unpkg.com/vue@latest/dist/vue.min.js"></script>
<script src="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.min.js"></script>
<script src="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue-icons.min.js"></script>
<div id="app"></div>

好的,现在有您想要的功能 - 没有 Vuex

4。让我们混合 Vuex:

  • 将列表移动到 Vuex 状态
  • 将选择移动到 Vuex 操作
  • 将删除移动到 Vuex 操作

// initial state is a function per Vuex best practices
const initialState = () => ({
  items: [{
      id: "item_1",
      name: "Item 1",
      toRemove: false,
    },
    {
      id: "item_2",
      name: "Item 2",
      toRemove: false,
    }
  ]
})

const store = new Vuex.Store({
  state: initialState(),
  mutations: {
    // so you are able to reset the store to
    // initial state
    RESET(state) {
      const init = initialState()
      for (key in init) {
        state[key] = init[key]
      }
    },
    // this handles the "checked" state if each item
    SET_TO_REMOVE(state, {
      id,
      toRemove,
    }) {
      // returning a new, modified array
      // per FLUX process
      state.items = state.items.map(item => {
        if (item.id === id) {
          return {
            ...item,
            toRemove,
          }
        } else {
          return item
        }
      })
    },
    // the same function that was in the app before
    REMOVE_SELECTED(state) {
      state.items = state.items.filter(({
        toRemove
      }) => !toRemove)
    },
  },
  actions: {
    reset({
      commit
    }) {
      commit("RESET")
    },
    // action to commit the mutation: select item for removal
    setToRemove({
      commit
    }, data) {
      commit("SET_TO_REMOVE", data)
    },
    // action to commit the mutation: remove items
    removeSelected({
      commit
    }) {
      commit("REMOVE_SELECTED")
    },
  },
  getters: {
    getItems: state => state.items,
  }
})

Vue.component('ListItem', {
  props: ['id', 'name', 'toRemove'],
  computed: {
    selected: {
      get() {
        return this.toRemove
      },
      set(val) {
        this.$emit('update:to-remove', val)
      }
    },
  },
  template: `
    <li>
      <input
        type="checkbox"
        v-model="selected"
      />
      {{ name }}
    </li>
  `
})

new Vue({
  el: "#app",
  store,
  data() {
    return {
      baseItems: [{
          id: "item_1",
          name: "Item 1",
          toRemove: false,
        },
        {
          id: "item_2",
          name: "Item 2",
          toRemove: false,
        },
      ]
    }
  },
  computed: {
    items() {
      return this.$store.getters.getItems
    },
  },
  methods: {
    handleSetToRemove(data) {
      // data should be: { id, toRemove }
      this.$store.dispatch("setToRemove", data)
    },
    handleRemoveSelected() {
      this.$store.dispatch("removeSelected")
    },
    handleResetStore() {
      this.$store.dispatch("reset")
    },
  },
  template: `
    <div>
      So, it's easier to follow:
      {{ items }}
      <hr />
      <ul>
        <list-item
          v-for="item in items"
          :key="item.id"
          v-bind="{
            ...item,
          }"
          @update:to-remove="(toRemove) => handleSetToRemove({
            id: item.id,
            toRemove,
          })"
        />
      </ul>
      <b-button
        @click="handleRemoveSelected"
      >
        REMOVE SELECTED
      </b-button>
      <b-button
        @click="handleResetStore"
      >
        RESET
      </b-button>
    </div>
  `
})
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.min.css" />
<script src="//polyfill.io/v3/polyfill.min.js?features=es2015%2CIntersectionObserver" crossorigin="anonymous"></script>
<script src="//unpkg.com/vue@latest/dist/vue.min.js"></script>
<script src="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.min.js"></script>
<script src="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue-icons.min.js"></script>
<script src="https://unpkg.com/vuex"></script>
<div id="app"></div>


仅此而已。

  1. 您在小组件中处理选择 - 但选定状态的更改不会在该组件内部处理,而是发送给父级,父级又通过调用 Vuex 行动。这会改变 Vuex 商店中的状态,并且会“流”回道具。

  2. 如果您单击 REMOVE SELECTED,它不会查看组件(如果它们被选中),而是调用另一个 Vuex 操作,删除所有选定的项目(通过过滤)来自 Vuex 商店的状态。由于所有项目都从 Vuex 商店的 getter 中取出(如果基础状态发生变化,getter 会更新),新状态出现在列表中。

因此,在这种情况下,使用 Vuex 似乎有点矫枉过正,但如果您计划为列出的项目设置更复杂的状态,那么它可能是合理的。