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
Related
I wanted to access the vue.data or methods in the plugin.
no matter what I tried several times, it didn't work.
such as eventBus, Mixin etc...
so I'm curious about the possibility to call the methods like that.
thank you for reading this question.
here is the custom component.
<template>
<div>
<v-overlay :value="isProcessing">
<v-progress-circular indeterminate size="64"></v-progress-circular>
</v-overlay>
</div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
#Component
export default class ProgressCircular extends Vue {
private isProcessing: boolean;
startProcess() {
this.isProcessing = true;
}
}
</script>
and this is the plugin source.
import ProgressCircular from '#/components/ProgressCircular.vue';
import { VueConstructor } from 'vue';
import Vuetify from 'vuetify/lib';
import vuetify from './vuetify';
export default {
install(Vue: VueConstructor, options: any = {}) {
Vue.use(Vuetify);
options.vuetify = vuetify;
Vue.component('progress-circular', ProgressCircular);
Vue.prototype.$fireProgressing = function () {
// it didn't work
// I just wanted to access the method where in the Vue Component
// ProgressCircular.startProcess();
};
},
};
use the plugin syntax to extend vue like:
Vue.use({
install: Vue => {
Vue.prototype.$fireProgressing = () => {
};
}
});
or
Vue.use(YOURPLUGIN);
before you mount vue
For a legacy project we need to use vue 2.
However we want to implement state by using #vue/composition-api for vue 2
But my only question is, how to use it with options api?
I have a proof of concept with a .js file
import { reactive } from '#vue/composition-api';
const state = reactive({
counter : 0
})
export default{ state }
For setup it is easy:
<template>
<h1>hi
<div>We still in it: {{ counter }}</div>
<button #click="increment">+</button>
</h1>
</template>
<script>
import { defineComponent, computed } from '#vue/composition-api'
export default defineComponent({
name: "TestStateHello",
setup() {
const store = require("./useState").default;
return {
counter: computed(() => store.state.counter),
increment: () => store.state.counter++,
};
},
})
</script>
But when i want to use regular options api to have access to reactive state of counter i don't seem to know how.
your help will be very grateful!
Just import it globally (outside of the returned options object):
<template>
<h1>hi
<div>We still in it: {{ counter }}</div>
<button #click="increment">+</button>
</h1>
</template>
<script>
import { defineComponent, computed } from '#vue/composition-api'
// Alternative (after fixing export): import {store} from './useState';
// You can use this in setup, too - no need to the require inside the setup()
const store = require("./useState").default;
export default defineComponent({
name: "TestStateHello",
computed: {
counter: () => store.state.counter,
},
methods: {
increment: () => store.state.counter++,
}
})
</script>
I suggest you change the export to:
import { reactive } from '#vue/composition-api';
const state = reactive({
counter : 0
})
export state; // < then import works as above
When dealing with options api you can make use of provide-inject-concept
How it works.
You can provide file of store in main.js like below
import GStore from "./useState"
app.provide('GStore',GStore)
Then in component you can inject that store
export default {
inject:["GStore"]
methods:{
//Code just to show how to access store counter
testingState(){
return this.GStore.state.counter;
}
}
}
Can I use "WebGL Earth" or "globe.gl" in vue.js? I search a lot but what I found was that there is "react-globe.gl" for react developers, but can't find the same for vue.
If I can use any of them in vue, how can I import and initialize it?
I am currently am using globe.gl with vue 3, got it running like this.
Can also checkout a template repo I have https://github.com/GBerghoff/Globe.gl-with-Vue-3
<template>
<div ref="globeDiv"></div>
</template>
<script>
import Globe from "globe.gl";
import { ref, onMounted } from "vue";
export default {
setup() {
const globeDiv = ref(null);
onMounted(() => {
const myGlobe = Globe();
myGlobe(globeDiv.value).globeImageUrl(
"//unpkg.com/three-globe/example/img/earth-night.jpg"
);
});
return {
globeDiv,
};
},
};
</script>
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.
In my app I using vue-js-modal.
My modal-test component:
<template>
<modal name="modal-test">
<div class="modal-test__content">I am modal</div>
</modal>
</template>
<script>
export default {
name: 'modalTest',
};
</script>
My unit-test:
import { expect } from 'chai';
import { mount, createLocalVue } from '#vue/test-utils';
import ModalTest from '#/modal/modalTest.vue';
import VModal from 'vue-js-modal';
const localVue = createLocalVue();
localVue.use(VModal);
describe('ModalTest.vue', () => {
it('modal', () => {
const wrapper = mount(ModalTest, {
localVue,
});
expect(wrapper.find('.modal-test__content').exists()).eq(true);
});
});
Tell me pls, how can I test exists div.'modal-test__content' inside modal?
I'm not familiar with vue-js-modal but in my case for custom modal I had to nest the use in the components prop. I think it may be because I'm using Vuetify, however.
import { expect } from 'chai';
import { mount, createLocalVue } from '#vue/test-utils';
import sinon from 'sinon';
import FileItem from '#/components/fileItem.vue';
import Modal from '#/components/common/Modal.vue';
import Vue from 'vue';
import Vuetify from 'vuetify'; // eslint-disable-line
Vue.use(Vuetify, {
components: {
Modal
}
});
Then Modal will be rendered on the page.
In the case of testing you have to remember that when you're testing the UI you have to think "What's the public interface", "Which one is the input and the output". In the example you provided there are no input. Everything is static so you don't need to test it.
On the other hand, you don't need to import the local vue, and instead of using mount you would prefer in most of the cases use shallowMount.
For finding the div you can do: expect(wrapper.find('div').exists()).toBe(true);
I know that probably you don't need this answer anymore, but may be useful for someone else.
Regards.