Vue 3, вызовите $emit при изменении переменной

#javascript #vue.js #vue-component #vuejs3 #vue-composition-api

Вопрос:

Поэтому я пытаюсь создать компонент в Vue 3, который действует как форма, и для того, чтобы данные обрабатывались родителем, я хочу, чтобы он создавал объект со всеми входными данными при изменении. Проблема, с которой я сталкиваюсь, заключается в том, что я, похоже, не могу звонить $emit изнутри watch() (вероятно, из-за контекста, но я также не понимаю, почему контекст для всего компонента не передается по умолчанию и не принимается this ). Я также не могу вызвать какой-либо метод по той же причине.

Я действительно вижу, что некоторые люди используют watch: {} синтаксис, но, насколько я понимаю, он устарел, и для меня это тоже не имеет большого смысла.

Вот минимальный пример того, чего я пытаюсь достичь. Всякий раз, когда дата ввода изменяется, я хочу, чтобы компонент выдавал пользовательское событие.

 <template>
  <input
    v-model="date"
    name="dateInput"
    type="date"
  >
</template>

<script>
import { watch, ref } from "vue";

    export default {
        name: 'Demo',
        props: {
        },
        emits: ["date-updated"],
        setup() {
          const date = ref("")

          watch([date], (newVal) => {
            // $emit is undefined
            console.log(newVal);
            $emit("date-updated", {newVal})
            // watchHandler is undefined
            watchHandler(newVal)
          })

          return {
            date
          }
        },
        data() {
            return {
            }
        },
        mounted() {
        },
        methods: {
          watchHandler(newVal) {
            console.log(newVal);
            $emit("date-updated", {newVal})
          }
        },
    }
</script>
 

Ответ №1:

Не смешивайте API опций и композиции, чтобы сохранить согласованность компонента, emit функция доступна в context параметре setup крючка::

 <template>
  <input
    v-model="date"
    name="dateInput"
    type="date"
  >
</template>

<script>
import { watch, ref } from "vue";
export default {
        name: 'Demo',
        props: {},
        emits: ["date-updated"],
        setup(props,context) {// or setup(props,{emit}) then use emit directly
          const date = ref("")

          watch(date, (newVal) => {
            context.emit("date-updated", {newVal}) 
          })

          return {
            date
          }
        },  
    }
</script>
 

если вы хотите добавить метод watchHandler , вы можете определить его как простую функцию js, например :

 ...
 watch(date, (newVal) => {
            context.emit("date-updated", {newVal}) 
          })

  function watchHandler(newVal) {
            console.log(newVal);
           context.emit("date-updated", {newVal})
          }
...
 

Комментарии:

1. Я бы предложил setup(props, { emit }) , чтобы им было легче управлять.

2. Контекст @Juckix-это второй параметр функции настройки. Подробнее об этом здесь v3.vuejs.org/api/composition-api.html#setup