Reputation: 12204
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.
Upvotes: 2
Views: 2528
Reputation: 23500
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>
Upvotes: 1