最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Why is "this" undefined in Vue Composition API setup function? - Stack Overflow

programmeradmin1浏览0评论

I have a Vue component using v3's composition API:

<template>
  <input type="checkbox" v-model="playing" id="playing" @input="$emit('play', $event.target.value)" />
  <label for="playing" >{{ playing ? 'Pause' : 'Play' }}</label>
</template>
<script>
export default {
  props: {
    done: Boolean
  },
  setup(props) {
    const playing = ref(true)
    watchEvent(() => {
      if (props.done) {
        playing.value = false
        this.$emit('play', playing.value)
      }
    }
    return { playing }
  }
}
</script>

When the watchEvent runs, I get the error Cannot read property "$emit" of undefined. It doesn't look like I'm using the wrong type of function (arrow versus normal function).

It seems like this is undefined throughout setup() regardless of whether it's a function or an arrow function.

I have a Vue component using v3's composition API:

<template>
  <input type="checkbox" v-model="playing" id="playing" @input="$emit('play', $event.target.value)" />
  <label for="playing" >{{ playing ? 'Pause' : 'Play' }}</label>
</template>
<script>
export default {
  props: {
    done: Boolean
  },
  setup(props) {
    const playing = ref(true)
    watchEvent(() => {
      if (props.done) {
        playing.value = false
        this.$emit('play', playing.value)
      }
    }
    return { playing }
  }
}
</script>

When the watchEvent runs, I get the error Cannot read property "$emit" of undefined. It doesn't look like I'm using the wrong type of function (arrow versus normal function).

It seems like this is undefined throughout setup() regardless of whether it's a function or an arrow function.

Share Improve this question asked Jul 22, 2020 at 13:38 Ted MorinTed Morin 6681 gold badge5 silver badges12 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 16

The setup function in the Vue Composition API receives two arguments: props and context.

The second argument provides a context object which exposes a selective list of properties that were previously exposed on this in 2.x APIs:

const MyComponent = {
  setup(props, context) {
    context.attrs // Previously this.$attrs
    context.slots // Previously this.$slots
    context.emit // Previously this.$emit
  }
}

It's important to note that it's not okay to destructure props (you'll lose reactivity), but it's okay to destructure context.

So the code example in the question, use setup(props, { emit }) and then replace this.$emit with emit.

For Vue 3 Composition API, from the documentation:

...we cannot directly access this.$router or this.$route anymore. Instead we use the useRouter and useRoute functions:

import { useRouter, useRoute } from 'vue-router'

export default {
  setup() {
    const router = useRouter()
    const route = useRoute()

    function pushWithQuery(query) {
      router.push({
        name: 'search',
        query: {
          ...route.query,
          ...query,
        },
      })
    }
  },
}
发布评论

评论列表(0)

  1. 暂无评论