'Uncaught TypeError: emit is not a function in vue3

when I write this code in vue 3 setup code block to get the input value follow this answer, this is part of the code:

import { defineComponent } from "vue";
import { defineProps, defineEmits } from 'vue'

export default defineComponent({
  setup() {
    const props = defineProps({
      modelValue: String
    })
    const emit = defineEmits(['update:modelValue'])
    function updateValue(value: any) {
      emit('update:modelValue', value)
    }
}

the app show error when running:

option.js:17388 Uncaught TypeError: emit is not a function
    at Proxy.updateValue (option.js:17388:13)
    at onInput._cache.<computed>._cache.<computed> (option.js:17428:78)
    at callWithErrorHandling (option.js:7359:22)
    at callWithAsyncErrorHandling (option.js:7368:21)
    at HTMLInputElement.invoker (option.js:15384:90)

I have defined the emit, why still tell me emit is not a function? This is my full code of the vue3 component:

<template>
  <div id="app">
    <div id="wrap">
      <label> 
        {{ username }}
      </label>
      <ul class="nav nav-tabs">
        <li>
          <input 
          :value="props" 
          placeholder="username" 
          v-on:input="updateValue($event.target.value)"/>
          <input v-model="password" placeholder="password" />
          <button @click="login">Login</button>
        </li>
      </ul>
    </div>
  </div>
</template>

<script lang="ts">
import { defineComponent } from "vue";
import { defineProps, defineEmits } from 'vue'

export default defineComponent({
  setup() {
    const props = defineProps({
      modelValue: String
    })
    const emit = defineEmits(['update:modelValue'])
    function updateValue(value: any) {
      emit('update:modelValue', value)
    }

    const login = () => {
      debugger
      alert(props.modelValue);
    };
    debugger

    return {
      login,
      updateValue,
      props
    };

  },
  components: {},
});
</script>

<style lang="scss" scoped>
</style>

I want to get the user input username from the template input.Seems did not work this way. what should I do to fix this problem? I have tried to upgrade the @vue/compiler-sfc to 3.2.31, still did not fix this problem.



Solution 1:[1]

defineEmits and defineProps are only used in script setup, the first example should define the props as option and the emit is the second parameter of the setup hook :


import { defineComponent } from "vue";


export default defineComponent({
   props:{
   modelValue: String
  },
  setup(props,{emit}) {

    function updateValue(value: any) {
      emit('update:modelValue', value)
    }
}

Solution 2:[2]

As you saied This expression is not callable error.try this:

import { defineComponent } from "vue";


export default defineComponent({
   props:{
   modelValue: String
  },
  setup(props,ctx) {

    function updateValue(value: any) {
      ctx.emit('update:modelValue', value)
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Dolphin