Reputation: 35
So I'm trying to build a component in Vue 3 that acts as a form, and in order for the data to be processed by the parent I want it to emit an object with all the inputs on change. The issue I'm having is that I don't seem to be able to call $emit
from within watch()
(probably because of the context, but I also don't see why the component-wide context isn't passed by default, and it doesn't accept this
). I also cannot call any method because of the same reason.
I do see some people using the watch: {}
syntax but as I understand it that is deprecated and it doesn't make a whole lot of sense to me either.
Here's a minimal example of what I'm trying to accomplish. Whenever the input date is changed, I want the component to emit a custom event.
<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>
Upvotes: 2
Views: 17266
Reputation: 11
How should I do this in setup syntactic sugar
const emits = defineEmits(['confirmCallBack', 'cancelCallBack', 'closeCallBack', 'openCallBack', 'update:modelValue'])
const dialogForm = ref<CommonForm >({})
watch(dialogForm.value, (val) => {
consola.start('数据更新')
emits('update:modelValue', val)
})
Upvotes: 1
Reputation: 1
Don't mix between option and composition api in order to keep the component consistent, the emit
function is available in the context
parameter of the setup
hook::
<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>
if you want to add the method watchHandler
you could define it a plain js function like :
...
watch(date, (newVal) => {
context.emit("date-updated", {newVal})
})
function watchHandler(newVal) {
console.log(newVal);
context.emit("date-updated", {newVal})
}
...
Upvotes: 4