Программно меняющееся выделение в v-data-table: ошибка в v-data-table или ошибка в моем коде? - PullRequest
0 голосов
/ 23 января 2020

Я хочу программно управлять выбранными элементами в v-data-таблице.

Я пытаюсь сделать это, помещая элементы в склейку и вставляя ее из переменной selected, которую я передал v-data-table * s v-model.

Этот пример гораздо лучше работает в коде:

https://codepen.io/masonk-the-decoder/pen/OJPdmaq?editable=true&editors=101

<div id="app">
  <v-app id="inspire">
    <v-data-table
      v-model="selected"
      :headers="headers"
      :items="desserts"
      :single-select="singleSelect"
      item-key="name"
      show-select
      class="elevation-1"
    >
      <template v-slot:top>
        <v-switch v-model="singleSelect" label="Single select" class="pa-3"></v-switch>
      </template>
    </v-data-table>
    <v-btn @click="clearSelection">Clear Selection</v-btn>
        <v-btn @click="random">Select Random</v-btn>
  </v-app>
</div>

const selected = [];
const desserts = [
        {
          name: 'Frozen Yogurt',
          calories: 159,
          fat: 6.0,
          carbs: 24,
          protein: 4.0,
          iron: '1%',
        },
        {
          name: 'Ice cream sandwich',
          calories: 237,
          fat: 9.0,
          carbs: 37,
          protein: 4.3,
          iron: '1%',
        },
        {
          name: 'Eclair',
          calories: 262,
          fat: 16.0,
          carbs: 23,
          protein: 6.0,
          iron: '7%',
        },
        {
          name: 'Cupcake',
          calories: 305,
          fat: 3.7,
          carbs: 67,
          protein: 4.3,
          iron: '8%',
        },
        {
          name: 'Gingerbread',
          calories: 356,
          fat: 16.0,
          carbs: 49,
          protein: 3.9,
          iron: '16%',
        },
        {
          name: 'Jelly bean',
          calories: 375,
          fat: 0.0,
          carbs: 94,
          protein: 0.0,
          iron: '0%',
        },
        {
          name: 'Lollipop',
          calories: 392,
          fat: 0.2,
          carbs: 98,
          protein: 0,
          iron: '2%',
        },
        {
          name: 'Honeycomb',
          calories: 408,
          fat: 3.2,
          carbs: 87,
          protein: 6.5,
          iron: '45%',
        },
        {
          name: 'Donut',
          calories: 452,
          fat: 25.0,
          carbs: 51,
          protein: 4.9,
          iron: '22%',
        },
        {
          name: 'KitKat',
          calories: 518,
          fat: 26.0,
          carbs: 65,
          protein: 7,
          iron: '6%',
        },
      ];
new Vue({
  el: '#app',
  vuetify: new Vuetify(),
  watch: {
    selected: (val) => console.log("selected watch: ", val),
  },
  data () {
    return {
      singleSelect: false,
      selected,
      desserts,
      random() {
        const idx = Math.floor(Math.random() * desserts.length);
        selected.push(desserts[idx]);
        console.log("Pushed: ", idx, desserts[idx]);
      },
      clearSelection() {
        selected.splice(0, selected.length);
      },
      headers: [
        {
          text: 'Dessert (100g serving)',
          align: 'left',
          sortable: false,
          value: 'name',
        },
        { text: 'Calories', value: 'calories' },
        { text: 'Fat (g)', value: 'fat' },
        { text: 'Carbs (g)', value: 'carbs' },
        { text: 'Protein (g)', value: 'protein' },
        { text: 'Iron (%)', value: 'iron' },
      ],

    }
  },
})

Я обнаружил, что когда я нажимаю «select random» в первый раз , вызывая вызов select.push, он успешно меняет выбор. Но pu sh кнопка снова и ничего не происходит.

clearSelection никогда не работает.

Нажатие на выбор всегда работает.

Редактирование: перемещение обработчиков на methods делает это работает. Но я не понимаю, почему наличие обработчиков в data что-то сломало. Замыкания - это просто кусочки данных, так что же здесь происходит?

(Codepen: https://codepen.io/masonk-the-decoder/pen/MWYLoyp)

const selected = [];
const desserts = [
        {
          name: 'Frozen Yogurt',
          calories: 159,
          fat: 6.0,
          carbs: 24,
          protein: 4.0,
          iron: '1%',
        },
        {
          name: 'Ice cream sandwich',
          calories: 237,
          fat: 9.0,
          carbs: 37,
          protein: 4.3,
          iron: '1%',
        },
        {
          name: 'Eclair',
          calories: 262,
          fat: 16.0,
          carbs: 23,
          protein: 6.0,
          iron: '7%',
        },
        {
          name: 'Cupcake',
          calories: 305,
          fat: 3.7,
          carbs: 67,
          protein: 4.3,
          iron: '8%',
        },
        {
          name: 'Gingerbread',
          calories: 356,
          fat: 16.0,
          carbs: 49,
          protein: 3.9,
          iron: '16%',
        },
        {
          name: 'Jelly bean',
          calories: 375,
          fat: 0.0,
          carbs: 94,
          protein: 0.0,
          iron: '0%',
        },
        {
          name: 'Lollipop',
          calories: 392,
          fat: 0.2,
          carbs: 98,
          protein: 0,
          iron: '2%',
        },
        {
          name: 'Honeycomb',
          calories: 408,
          fat: 3.2,
          carbs: 87,
          protein: 6.5,
          iron: '45%',
        },
        {
          name: 'Donut',
          calories: 452,
          fat: 25.0,
          carbs: 51,
          protein: 4.9,
          iron: '22%',
        },
        {
          name: 'KitKat',
          calories: 518,
          fat: 26.0,
          carbs: 65,
          protein: 7,
          iron: '6%',
        },
      ];
new Vue({
  el: '#app',
  vuetify: new Vuetify(),
  watch: {
    selected: (val) => console.log(val),
  },
  methods: {
    random() {
        const idx = Math.floor(Math.random() * desserts.length);
        this.selected.push(desserts[idx]);
        console.log("Pushed ", idx, desserts[idx]);
      },
      clearSelection() {
        console.log(this.selected.length);
        this.selected.splice(0, this.selected.length);
      },
  },
  data () {
    return {
      singleSelect: false,
      selected,
      desserts,

      headers: [
        {
          text: 'Dessert (100g serving)',
          align: 'left',
          sortable: false,
          value: 'name',
        },
        { text: 'Calories', value: 'calories' },
        { text: 'Fat (g)', value: 'fat' },
        { text: 'Carbs (g)', value: 'carbs' },
        { text: 'Protein (g)', value: 'protein' },
        { text: 'Iron (%)', value: 'iron' },
      ],

    }
  },
})

1 Ответ

0 голосов
/ 23 января 2020

Вы не можете ссылаться на другие свойства данных внутри свойства данных. Кроме того, почему вы инициализировали как выбранный массив, так и массив десертов вне экземпляра Vue? selected / deserts должно быть инициализировано внутри свойства data.

...