Как избежать мутации напрямую, когда все, что у вас есть, это щелчок? - PullRequest
0 голосов
/ 10 марта 2020

Как я могу мутировать реквизит правильно, чтобы я не получил [Vue предупреждение]: Избегать мутации опоры напрямую сообщение?

Я уже получил V-модель для работы с этим V-диалогом. Тем не менее, я также хочу предоставить кнопку закрытия в самом диалоге, которая вызывает это предупреждение о мутации, так как именно диалог изменяет переменную. Как лучше всего подойти к этому делу и решить его?

Диалог. vue:

<template>
    <v-dialog
        :value="value" @input="$emit('input', $event)"
        scrollable
        width="80vw"
        :transition="false"
    >
        <template v-slot:activator="{ on }">
            <div v-on="on" @click="$emit('open')">
                <slot name="button">
                    <v-btn color="primary">{{ buttonText == null ? title : buttonText }}</v-btn>
                </slot>
            </div>
        </template>
        <v-card
            elevation="10"
            height="80vh"
        >
            <v-system-bar
                color="light-blue darken-3"
                window
            >
                <span>{{title}}</span>
                <v-spacer></v-spacer>
                <v-icon @click="value=false">mdi-close</v-icon>
            </v-system-bar>
            <v-card-text> <!-- required here to make the scrollable v-dialog work -->
                <slot></slot>
            </v-card-text>
            <slot name="actions"></slot>
        </v-card>
    </v-dialog>
</template>

<script>
    export default {
        props: {
            title: {
                type: String,
                required: true,
            },
            buttonText: String,
            value: Boolean,
        },
    }
</script>

Я могу использовать его довольно красиво, например:

<mydialog title="Select something" button-text="A button!" v-model="dialog" @open="loadData()">
  Content goes here...
</mydialog>

The <v-icon @click="value=false">mdi-close</v-icon> - это то, что неправильно изменяет переменную «value».

Sidenote # 1: есть событие open, поэтому я могу заполнять данные (loadData) из базы данных при открытии диалога (по сравнению с его созданием). на DOM).

ОБНОВЛЕНИЕ; Я могу заставить его работать, выполнив:

<v-icon @click="$emit('close', $event)">mdi-close</v-icon>

и

<mydialog title="Select something" button-text="A button!" v-model="dialog" @open="loadData()" @close="dialog=false">

Однако я чувствую, что это далеко не элегантно. Нет ли каких-либо решений, в которых мне не нужно добавлять обработчики, чтобы закрыть этот диалог? Я почти чувствую, что это хуже, чем жить с предупреждением ..: |

1 Ответ

1 голос
/ 10 марта 2020

Используйте вычисляемое свойство с get и set. Вычисляемый диалог будет вести себя точно как обычная переменная, и это исключит предупреждение. Теперь вы можете использовать его для получения значения, а также для установки значения.

Попробуйте это:

<template>
  <v-dialog
    :value="dialog"
    @input="$emit('input', $event)"
    scrollable
    width="80vw"
    :transition="false"
  >
    <template v-slot:activator="{ on }">
      <div v-on="on" @click="dialogOpened()">
        <slot name="button">
          <v-btn color="primary">{{ buttonText == null ? title : buttonText }}</v-btn>
        </slot>
      </div>
    </template>
    <v-card elevation="10" height="80vh">
      <v-system-bar color="light-blue darken-3" window>
        <span>{{title}}</span>
        <v-spacer></v-spacer>
        <v-icon @click="dialog=false">mdi-close</v-icon>
      </v-system-bar>
      <v-card-text>
        <!-- required here to make the scrollable v-dialog work -->
        <slot></slot>
      </v-card-text>
      <slot name="actions"></slot>
    </v-card>
  </v-dialog>
</template>
export default {
        props: ['title', 'buttonText', 'value'],      
        data: () => ({
          dlg_close: false,
        }), 
        computed: {
          dialog: {
            get() {
              return this.value;
            },
            set(selection) {
              this.$emit("input", selection);
            }
          }
        },
        methods: {
            dialogOpened(newVal) {
                this.dialog = newVal;
            },
        },

    }
...