Reputation: 508
I'm new to Vue.js and I'm trying to do the following. I have a working Vue 3 application where I'm testing the composition Api feature. My App.vue file is simple and has the following:
<template>
<div>
<p>Counter: {{ counter }}</p>
<button @click="increaseCounter()">Increase counter</button>
</div>
</template>
<script>
import { ref } from "vue";
export default {
setup() {
const counter = ref(3);
function increaseCounter() {
counter.value++;
}
return {
counter,
increaseCounter
};
}
};
</script>
Now everything is working with this code. What I want to do is to separate the script code into a new separate file and import in the App.vue to reuse it. I tried the following but with no luck:
<template>
<div>
<p> Msg: {{ msg }} </p>
<p>Counter: {{ counterApi.counter }}</p>
<button @click="counterApi.increaseCounter()">Increase counter</button>
</div>
</template>
<script>
import { counterApi } from "./counter-api.js";
export default {
created: () => {
counterApi.increaseCounter;
}
};
</script>
counter-api.js
import { ref } from "vue";
export default {
setup() {
const counter = ref(3);
function increaseCounter() {
counter.value++;
}
return {
counter,
increaseCounter
};
}
};
I'm getting the following error
Cannot read property 'increaseCounter' of undefined.
Thanks in advance
Upvotes: 1
Views: 2773
Reputation: 3614
You did not showed what is inside counter-api.js. Based on import you have, it should be something like this:
export function CounterApi {
const counter = ref(3);
function increaseCounter() {
counter.value++;
}
return {
counter,
increaseCounter
};
}
Or if we use more ES6:
export const CounterApi = () {
const counter = ref(3);
const increaseCounter = () {
counter.value++;
}
return {
counter,
increaseCounter
};
}
You imported file, but it's not enough because you did nothing with it. Instead:
<template>
<div>
<p>Counter: {{ counter }}</p>
<button @click="increaseCounter()">Increase counter</button>
</div>
</template>
<script>
import { CounterApi } from "./counter-api";
export default {
setup() {
const { counter, increaseCounter } = CounterApi();
return {
counter,
increaseCounter
};
}
};
</script>
Or
<template>
<div>
<p>Counter: {{ someName.counter }}</p>
<button @click="someName.increaseCounter()">Increase counter</button>
</div>
</template>
<script>
import { CounterApi } from "./counter-api";
export default {
setup() {
const someName = CounterApi(); // use all under single const
return { someName };
}
};
</script>
There is plenty articles about composition API, for example: https://vueschool.io/articles/vuejs-tutorials/state-management-with-composition-api/
Also it is good idea and common convention to name this composable as useCounterApi
and then const counterApi = useCounterApi()
or with dectruction const { something, something } = useCounterApi()
It is all in official docs: https://v3.vuejs.org/api/composition-api.html
Upvotes: 1