As the title of the question says. How can I set my helper class globally. So that I don't have to import it in every component. What are the possibilities?
Hi as Andrew v said you can directly use the prototype key and add it to your Vue app for Vue2:
import Vue from 'vue'
import { HelperClass } from '#/assets/js/myFunc.js';
Vue.prototype.$HelperClass = HelperClass
And then
this.$HelperClass.myFunc()
How to import my own class or method globally in Vue?
Otherwise for vue 3:
export default class {
myFunc() {
alert("Exported Class")
}
}
You can provide it for all your app using provide/inject:
import { createApp } from 'vue'
import App from './App.vue'
import HelperClass from './class'
const helperClass = new HelperClass();
createApp(App)
.provide('helperClass', helperClass)
.mount('#app')
import { inject } from 'vue'
export default {
setup() {
const message = inject('helperClass')
console.log(message.myFunc())
return { message }
}
}
Or in each .vue file needed with Composition Api:
import { ref } from 'vue'
import HelperClass from './whateveryourpathis'
export default {
setup() {
const helperClass = ref(new HelperClass())
console.log(helperClass.value.myFunc())
}
}
Or if you use the setup tag on the script
<script setup>
import { ref } from 'vue'
import HelperClass from './whateveryourpathis'
const helperClass = ref(new HelperClass())
console.log(helperClass.value.myFunc())
</script>
Related
I am trying to use a plugin VueDraggableNext in a project that also used Vuetify. Both plugins have a <draggable> element.
If I use the 'Options' API with Vue, I can use the following method to define which version of <draggable> I want to use:
<script>
....
import { defineComponent } from 'vue'
import { VueDraggableNext } from 'vue-draggable-next'
export default defineComponent({
components: {
draggable: VueDraggableNext,
},
....
....
and it works. But I wish to use the Composition API (it's what I'm used to!) - what is the syntax for defineComponent() in this case? I have tried re-ordering the imports, but to no effect, the vuetify version of <draggable> is always used.
main.js:
import { createApp } from 'vue'
import App from './App.vue'
import { VueDraggableNext } from'vue-draggable-next'
// Vuetify
import 'vuetify/styles'
import { createVuetify } from 'vuetify'
import * as components from 'vuetify/components'
import * as directives from 'vuetify/directives'
const vuetify = createVuetify({
components,
directives,
})
import '../assets/main.css'
createApp(App).use(vuetify).use(VueDraggableNext).mount('#app')
and I have tried the following in my vue.js but get error 'components is not defined'.
<script setup>
import { reactive,components} from 'vue'
import { defineComponent } from 'vue'
import { VueDraggableNext } from'vue-draggable-next'
defineComponent(
components = {
draggable: VueDraggableNext }
)
....
....
I have two vue components with own loaders, mounted into two already rendered DOM nodes:
Component A:
import { createApp } from 'vue'
import ComponentA from '#/Vue/ComponentA.vue';
import {createPinia} from 'pinia';
createApp(ComponentA).use(createPinia()).mount(document.querySelector('.c-component-a'));
Component B:
import { createApp } from 'vue'
import ComponentB from '#/Vue/ComponentB.vue';
import {createPinia} from 'pinia';
createApp(ComponentA).use(createPinia()).mount(document.querySelector('.c-component-b'));
Now, I want to load a global pinia store into multiple components:
Pinia store:
import {defineStore} from 'pinia';
export type RootState = {
foobar: number;
}
export const useGlobalApplicationStore = defineStore({
id: 'global',
state: () => ({
foobar: 100
} as RootState),
actions: {
setFoobar(payload: number): void {
this.foobar = payload;
}
},
getters: {
getFoobar(state: RootState): number {
return state.foobar;
}
}
})
If component A sets a value in this store, component B should react to changes.
Component A:
const globalApplicationStore = useGlobalApplicationStore();
setTimeout(() => {
globalApplicationStore.setFoobar(400);
}, 2000);
Output of {{globalApplicationStore.foobar}} in component A changes from 100 to 400 after 2 seconds, as expected.
Component B:
const globalApplicationStore = useGlobalApplicationStore();
Output of {{globalApplicationStore.foobar}} in component B does not change from 100 to 400.
I guess, both components loads the store as local instances.
How can I share a store between seperate mounted components?
After a long search I found out that it's pretty easy (as often...).
In my case, I use the progressive aspect of Vue.js to put apps in different places of my HTML code. Specifically, I want to populate a shopping cart icon in the header of my layout with the number of items. So I am using a App.vue for my product-app and a Basket.vue for my basket-indicator.
The simple trick is to instantiate pinia just once. Let's say you have a main.js as an entry-point of your app:
import { createApp } from "vue";
import App from "./App.vue";
import Basket from "./Basket.vue";
import {createPinia} from 'pinia';
const pinia = createPinia();
// Init App
createApp(App)
.use(pinia)
.mount("#app");
// Init Basket
createApp(Basket)
.use(pinia)
.mount("#basket");
In your App.vue you just import your stores (in my case a product store and a cart store).
<script setup>
... import components ...
import {useProductStore} from "#/stores/ProductStore";
import {useCartStore} from "#/stores/CartStore";
const productStore = useProductStore();
const cartStore = useCartStore();
productStore.fill();
</script>
<template>
... your components ...
</template>
the same in your Basket.vue:
<script setup>
import CartWidget from "#/components/CartWidget.vue";
import {useCartStore} from "#/stores/CartStore";
import {useProductStore} from "#/stores/ProductStore";
const cartStore = useCartStore();
const productStore = useProductStore();
productStore.fill();
</script>
<template>
<div class="container">
<CartWidget/>
</div>
</template>
That's it.
"pinia": "^2.0.17",
"vue": "^3.2.39"
Following the setup guide for Vuejs and Pinia
<script setup>
import {useStore} from "../stores/store.js";
export default {
setup() {
const store = useStore();
return {
store,
}
},
}
</script>
I get the following error from Vite:
[vite] Internal server error: [#vue/compiler-sfc] <script setup> cannot contain ES module exports. If you are using a previous version of <script setup>, please consult the updated RFC at https://github.com/vuejs/rfcs/pull/227.
How do I move to a version of <script setup> that will allow me to do the above?
Thanks!
A bit of confusion on my end it seems. The docs talk about adding <script setup> and then also demonstrate using setup(){}, but they don't explicitly state that its one or the other.
Method 1:
<script setup>
import {useStore} from "../stores/store.js";
const store = useStore();
// do stuff
</script>
Method 2:
<script>
import { defineComponent } from 'vue'
import {useStore} from "../stores/store.js";
export default defineComponent({
setup() {
const store = useStore();
// do stuff
return {
store,
}
}
})
</script>
I think you mismatched two methods of local components registration.
Check:
https://vuejs.org/guide/components/registration.html#local-registration
https://vuejs.org/guide/reusability/composables.html#what-is-a-composable
When using SFC with , imported components are automatically registered locally:
<script setup>
import { useStore } from '../store/store.js'
const { store } = useStore()
</script>
Add Following code to your main.js file
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import { createPinia } from 'pinia'
const app = createApp(App)
.use(createPinia())
app.mount('#app')
I am able to use dayjs inside vue3 component by adding it to data()
import dayjs from 'dayjs'
export default {
data() {
return {
dayjs
}
}
}
Then I will be able to use it inside template but is this the correct way to do?
What if I want to configure dayjs and use it globally? I tried
import dayjs from 'dayjs'
import { createApp } from 'vue'
const app = createApp(App)
app.use(dayjs) // doesn't work
app.dayjs = dayjs // doesn't work
app.mount("#app')
but couldn't get it to work so far.
What is the correct way to do it?
u can use
import dayjs from 'dayjs'
import { createApp } from 'vue'
const app = createApp(App)
app.config.globalProperties.$dayjs = dayjs
app.mount("#app')
The accepted method does not seem to take into account composition API. My understanding is that the only way to use this with Composition API is to provide/inject. Example below working with composition API, options API in script and templates.
//[main.js]
import dayjs from 'dayjs' //import dayjs in your main.js
app.provide('dayJS', dayjs) // provide dayJS
app.use(router).mount("#app") // mount app
// [component.js]
// Composition API setup ------------------
import { inject } from 'vue' // import inject from vue
const dayJS = inject("dayJS") // inject dayJS
//make sure that you return dayJS in setup along with any functions/variables
return { dayJS }
// Options API setup ------------------
app.component('mycomponent', {
inject: ['dayJS'],
created() {
console.log(dayJS())
}
})
//You can now use dayJS directly within setup ex: dayJS() or template ex: {{dayJS()}}.
You can use provide/inject to use dayjs inside of your component.
//main.js
import dayjs from 'dayjs'
import { createApp } from 'vue'
const app = createApp({
provide() {
return {
$dayjs: dayjs // <-- provide
}
},
app.mount("#app')
//myComponent.vue
<template>
DajsJS: {{ myDays }}
</template>
<script>
export default {
name: 'myComponent',
inject: ['$dayjs'], // <-- inject
computed: {
myDays() {
return this.$dayjs('1990-01-01')
}
}
}
</script>
If you are using composition api you can use direct dayjs without having to pass it through a provider. Look at the following example.
<template>
<section>
<h1>Título de ejemplo</h1>
<h2>
Fecha de creación
{{ dayjs('Fri Dec 17 2021 00:55:42 GMT-0500 (hora estándar de Colombia)').format('DD/MM/YYYY HH:mm') }}
</h2>
<h3>
Otra prueba {{ date }}
</h3>
</section>
</template>
<script lang="ts">
import { defineComponent, computed, ref } from "vue";
import dayjs from "dayjs";
export default defineComponent({
name: 'Ejemplo',
setup() {
const date_example = ref<string>('Fri Dec 17 2021 00:55:42 GMT-0500 (hora estándar de Colombia)');
const date = computed<string>((): string => {
return dayjs(date_example.value).format('DD/MM/YYYY HH:mm');
});
return {
dayjs,
date,
}
}
});
</script>
//[main.js]
import dayjs from "dayjs"; //import dayjs in your main.js
app.provide("dayJS", dayjs); // provide dayJS
app.config.globalProperties.$dayjs = dayjs; // //You can now use dayjs as $dayjs
app.use(router).mount("#app") // mount app
I am using Vue 3 with Composition API, and I want to use a third-party package (for example #meforma/vue-toaster), and it should be used like this (in Options API):
import Toaster from '#meforma/vue-toaster';
createApp(App).use(Toaster).mount('#app')
and then in the component:
this.$toast.show(`Hey! I'm here`);
this.$toast.success(`Hey! I'm here`);
this.$toast.error(`Hey! I'm here`);
this.$toast.warning(`Hey! I'm here`);
this.$toast.info(`Hey! I'm here`);
But this is not working inside the Composition API's setup() function.
#meforma/vue-toaster installs $toast on the application context, which can be accessed from getCurrentInstance().appContext.globalProperties in setup():
<template>
<button #click="showToast">Show toast</button>
</template>
<script>
import { getCurrentInstance } from 'vue'
export default {
setup() {
const $toast = getCurrentInstance().appContext.globalProperties.$toast
return {
showToast() {
$toast.show(`Hey! I'm here`)
$toast.success(`Hey! I'm here`)
$toast.error(`Hey! I'm here`)
$toast.warning(`Hey! I'm here`)
$toast.info(`Hey! I'm here`)
setTimeout($toast.clear, 3000)
}
}
}
}
</script>
i've the same issue.
So i've found and easy way to do:
I'm using Vite BTW.
my main.js
import { createApp } from 'vue'
import App from './App.vue'
import Toaster from '#meforma/vue-toaster';
let app = createApp(App)
app.use(Toaster, {
position: 'top-right'
}).provide('toast', app.config.globalProperties.$toast)
app.mount('#app')
my component:
import { inject } from 'vue'
export default {
name: 'table-line',
setup(props) {
const toast = inject('toast');
toast.success(`it works !`)
return {toast}
}
}
Hope it could be helpful
The setup function runs one-time before the component is created. It lacks the this context and may not be where you would want to place these anyway. You could try putting it into a method that you can call via a button.