Home > Net >  How to call a method from a callback defined in data() in Vue 2.7?
How to call a method from a callback defined in data() in Vue 2.7?

Time:01-19

I use a 3rd party component called HelloWorld. The component accepts a prop called closeCallbacks. It is an array of callbacks that are called when the HelloWorld component is closed.

I can not change the way the 3rd party component works.

I implement the template of my component to use HelloWorld component and pass closeCallbacks from the data:

<template>
    <HelloWorld :closeCallbacks="closeCallbacks" />
</template>

Then, I define the array of callbacks, where one callback item contains a property called action required by HelloWorld component. The action callback is called when HelloWorld is closed:

<script lang="ts">
export default defineComponent({
    data() {
        return {
            closeCallbacks: [
                {
                    action: function () {
                        return this.handleCloseCallback();
                    },
                },
            ],

        };
    },
    methods: {
        handleCloseCallback: function () {
        //
        },
    },
});
</script>

When the action callback is called, I want to call a method of my component that is called handleCloseCallback (as pictured above).

However in Vue 2.7 I get an error:

Property 'handleCloseCallback' does not exist on type '{ name: string; action: (item: any) => void; }'.

When I will change handleCloseCallback to an array function:

handleCloseCallback: () => {
            //
            },

I get another error:

Property 'handleCloseCallback' does not exist on type 'CreateComponentPublicInstance<{}, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {}, {}, {}, false, OptionTypesType<{}, {}, {}, {}, {}, {}>, ... 5 more ..., {}>'.

My question is: how to call a method from a callback defined in data?

CodePudding user response:

Would this fix your issue?

<template>
  <HelloWorld v-if="closeCallbacks.length" :closeCallbacks="closeCallbacks" />
</template>
<script>
export default defineComponent({
  data: () => ({
    closeCallbacks: []
  }),
  mounted() {
    this.closeCallbacks = [{ action: this.handleCloseCallback }]
  },
  methods: {
    handleCloseCallback() {}
  }
})
<script>

Point being: this.handleCloseCallback is defined on mounted, but it's not yet defined at the time data is parsed.
Note I used a v-if to defer rendering of the components until closeCallbacks is populated, to avoid the initial rendering of the component with an empty closeCallbacks.


I believe this is what Estus was suggesting. Not only it should also work, but I find it much cleaner:

export default defineComponent({
  computed: {
    closeCallbacks() {
      return [{ action: this.handleCloseCallback }]
    }
  },
  methods: {
    handleCloseCallback() {}
  }
})
  • Related