2

I am having a hard time figuring out how much Vue 3 composition API methods can access the vue app's attributes, including data.

This is the jsfiddle which itself is a fork of the Vue demo fiddle.

Basically, using a method defined via the options API, I can easily retrieve data values.

However, when I use method defined via the composition API, it's pretty much as if data and the app instance in general is invisible to me. No this, as has been said before. But in general, it is as if the composition and the options API parts have been segmented apart from each other.

testopt, defined using options API, can see data, and references returned by setup.

"Yo! from options API:Hello Vue!"
"this.msg2:Hello2"

testcompo, defined in composition API can't see data, but can see references returned by setup.

"Yo! from composition API: this:undefined:"
"context:[object Object]:"
"context.data:undefined:"
"context.$data:undefined:"
"context.attrs:[object Object]:"
"context.attrs.data:undefined:"
"arg2:undefined:"
"msg2:Hello2"
"Yes, I know how setup and refs work.  counter is now:4"
<script type="importmap">
  {
    "imports": {
      "vue": "https://unpkg.com/vue@3/dist/vue.esm-browser.js"
    }
  }
</script>

<div id="app">

<div>{{ message }}</div>

<button @click="testopt">
Test option API this
</button>

<button @click="testcompo">
Test composition API this
</button>


</div>

<script type="module">
  import { createApp, ref } from 'vue'

  createApp({
    data() {
      return {
        message: 'Hello Vue!'
      }
    },
    setup(props, context){
    
        const msg2 = ref("Hello2");
        const counter = ref(1);      
    
        function testcompo (evt, arg2) {
         console.clear();
         console.log("Yo! from composition API: this:" + this + ":");
         console.log("context:" + context + ":");
         console.log("context.data:" + context.data + ":");
         console.log("context.$data:" + context.$data + ":");
         console.log("context.attrs:" + context.attrs + ":");
         console.log("context.attrs.data:" + context.attrs.data + ":");
         console.log("arg2:" + arg2 + ":");
         console.log("msg2:" + msg2.value);
         counter.value++;
         console.log("Yes, I know how setup and refs work.  counter is now:" + counter.value);
      };
      
        return {testcompo, counter,msg2}
    },
    
    methods : {
       testopt(evt){
         console.clear();
         console.log("Yo! from options API:" + this.message)
         console.log("this.msg2:" + this.msg2);
       }
    }
  }).mount('#app')
</script>

Should I generally understand that mixing composition and options API is a no-go? Is there no interop or is there a bridge object somewhere in the context and on this allowing one side to access the other? Is there a way to get this back on composition API method?

What I have also looked at:

javascript - Vue 3 Composition API data() function - Stack Overflow

typescript - Can't access this in Vue 3 methods with regular OR arrow functions - Stack Overflow

javascript - Vue 3 composition API and access to Vue instance - Stack Overflow

But all these answers seemed more narrowly focused on explaining how to do one particular thing using composition API rather than the generic question on how composition methods interact with the Vue app instance, if at all.

5
  • The concept of composition API is grouping your code in a logical concern way. So, in theory, you don't need to access other data at all because all the data you need should be placed inside the composition. If you want to share some data between compositions, you can pass it as variables or add it to vuex/pinia Commented Sep 30, 2022 at 2:29
  • @Duannx Sorry, not super helpful here. I wasn't asking whether Composition or Options API was better, I was asking for a specific aspect of integrating between the 2. And I know what vuex is already, I wasn't asking about it either. Commented Oct 13, 2022 at 2:35
  • I mean you don't need to access other data if using composition API in the right way. To answer your question directly, it is a no-go to mix composition and options API Commented Oct 13, 2022 at 2:47
  • @Duannx Sorry for being cranky. But in a way saying that the 2 don't mix is a pretty solid answer, with the understanding that they do mix - which is why I accepted the answer below - IF you use undocumented functions. It also doesn't help that a lot of the vue3 code examples I've seen are still based on... options API . Commented Oct 13, 2022 at 2:55
  • I see we have different points of view here. Maybe you are migrating from Vue2 to Vue3 and just don't want to rewrite all the code. If you decide to mix composition API with options API, you can use the getCurrentInstance method as the accepted answer points out. I see you already know the risk of using it. Commented Oct 13, 2022 at 3:52

1 Answer 1

1

You can use getCurrentInstance to access options api:

const { createApp, ref, getCurrentInstance } = Vue
createApp({
  data() {
    return {
      message: 'Hello Vue!'
    }
  },
  setup(props, context){
    const msg2 = ref("Hello2");    
    const vm = getCurrentInstance()
    function testcompo (evt, arg2) {
       console.clear();
       console.log("Yo! from composition API: " + msg2.value);
       console.log("message: " + vm.data.message);
    };
    return { testcompo, msg2 }
  },
  methods : {
     testopt(evt){
       console.clear();
       console.log("Yo! from options API: " + this.message)
       console.log("msg2: " + this.msg2);
     }
  }
}).mount('#app')
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<div id="app">
  <div>{{ message }}</div>
  <button @click="testopt">
  Test option API this
  </button>
  <button @click="testcompo">
  Test composition API this
  </button>
</div>

Sign up to request clarification or add additional context in comments.

2 Comments

OK, thanks, accepting. But... there are lots of getCurrentInstance answers for Vue3 so it would be nice if the Vue 3 community could decide what to do with it or not. This is what concerns me: Why getCurrentInstance is descriped as anti pattern in application code? · Issue #1422 · vuejs/docs · GitHub : Because the instance is an internal instance that exposes non-public APIs. Anything you use from that instance can technically break between any release types, since they are not subject to semver constraints.
I mean, a lot of people are really confused by the firewall between Composition API and Options API stuff, especially when it comes to porting big V2 codebases. Ideally we'd have an option to gradually move from options to composition. And instead we have to rely on an internal method. I like the composition API myself, especially <script setup> , but not ready to rewrite everything in it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.