how can i make library with Vue.js (Feat. store, router) - javascript

first, i'm sorry that my English is not good.
...
I want to make vue.js components module.
I tried simple button component module and It works(it include vuex).
I saw this page.
and I want to make some module with 5 components that use both store and vue-router.
so I tried like this.
import LoadingSpinner from './components/common/LodingSpinner.vue';
import Modal from './components/common/Modal.vue';
import InputPage from './components/InputPage.vue';
import Page from './components/Page.vue';
import ProcessingPage from './components/ProcessingPage.vue';
import store from './store/index.js';
import route from './routes/index.js';
export default {
install(Vue, options) {
if (!options || !options.store) {
throw new Error('Please initialise plugin with a Vuex store.')
}
options.store.registerModule('dummylib', store);
options.route.registerModule('dummylib', route);
Vue.component('loading-spinner', LoadingSpinner);
Vue.component('modal', Modal);
Vue.component('input-page', InputPage);
Vue.component('page', Page);
Vue.component('processing-page', ProcessingPage);
}
when i finished it and install in new project, I can't see even App.vue and all components are missing.
Here is the main.js of the new project that will include the module.
import Vue from 'vue';
import App from './App.vue';
import store from './store';
import DummyButton from 'dummylib';
import router from './routes';
import InputPage from 'dummylib';
import Page from 'dummylib';
import ProcessingPage from 'dummylib';
import Modal from 'dummylib';
import LoadingSpinner from 'dummylib';
Vue.config.productionTip = false
Vue.use(DummyButton, {store});
Vue.use(InputPage, { store });
Vue.use(Page, { store });
Vue.use(ProcessingPage, { store });
Vue.use(Modal, { store });
Vue.use(LoadingSpinner);
new Vue({
store,
router,
render: h => h(App),
}).$mount('#app')
how can i solve this problems...
thank you for watching my question with not good english.
i hope you understand my intension.

Related

Call Vue store action through browser console

I'm trying to create a webapp using VUE Vite with a router and store. The getter function in the vue file works fine. I have access to the chatMessages stored in the store.js file.
My problem is that I need to call the addMessage Action from the store.js file in the dev console using the browser.
Question: How could I archive this?
On older vue versions it would be done the following way using the main.js file:
import Vue from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';
import './registerServiceWorker';
import { mapGetters, mapMutations, mapActions } from 'vuex';
Vue.config.productionTip = false;
const app = new Vue({
router,
store,
render: function (h) { return h(App) },
methods: {
...mapMutations([
'showLoading',
]),
...mapActions([
'addNotification',
]),
},
}).$mount('#app');
export default app;
Current vue3 chat.vue file:
<template>
<div></div>
</template>
<script>
import { mapGetters } from 'vuex';
export default {
name: 'Chat',
data: function() {
return {
}
},
methods: {
},
computed: {
...mapGetters({
chatMessages: 'chatMessageList',
}),
}
}
</script>
Current vue3 store.js file:
import { createStore } from 'vuex'
export default createStore({
state: {
chatMessages: {
list: [
{ type: "a", message: "test" }
]
}
},
mutations: {
addMessage(state, { type, message }) {
state.chatMessages.list.push({ type: type, message: message });
}
},
actions: {
addMessage({ commit }, { type, message }) {
commit('addMessage', { type, message });
}
},
getters: {
chatMessageList(state, getters) {
return state.chatMessages.list;
}
}
})
Current vue3 main.js file:
import App from "./App.vue";
import {createApp} from "vue";
import router from "./router/index.js";
import store from "./store/store";
import "bootstrap/dist/css/bootstrap.min.css";
import "bootstrap/dist/js/bootstrap.js";
window.app = createApp(App).use(router).use(store).mount('#app');
EDIT: I tested it the following way and I can call app.addMessage from the dev console but now the router wont work.
import App from "./App.vue";
import {createApp} from "vue";
import router from "./router/index.js";
import store from "./store/store";
import { mapGetters, mapMutations, mapActions } from 'vuex';
import "bootstrap/dist/css/bootstrap.min.css";
import "bootstrap/dist/js/bootstrap.js";
window.app = createApp({
methods: {
...mapActions([
'addMessage',
]),
}
}).use(router).use(store).mount('#app');
Assigning the store to the window object seems like a great approach, where you can easily then call it like in domiatorov's answer.
Another approach is:
var store = Array.from(document.querySelectorAll('*')).find(e => e.__vue_app__).__vue_app__.config.globalProperties.$store;
var actions = store._actions;
actions.addMessage[0]('mytype', 'mymessage');
The first part queries the body for an element containing __vue_app__ and will return your instance. In there, you can access config.globalProperties.$store to return your store object.
store is already available in this scope and can be exposed the same way as app:
window.store = store;
It can be used in console the same way as in an app:
store.dispatch(...)
I believe you can simply assign the store to the window object.
But do it from a top level single file component, the very first that is using the store and not in the setup to make sure the store got everything loaded.
Providing you have something like App.vue:
In setup() you would assign:
window.vueStore = store;
and use it from the console calling window.vueStore.

Vue 3 use function not works

I tried to upgrade one of my apps from Vue 2 to Vue 3.
Unfortunately I can't use: Vue.use() function.
For example my code in Vue 2:
import Vue from 'vue'
import App from './App.vue'
import store from './store'
import router from './router'
import VueCookie from 'vue-cookie'
Vue.use(VueCookie);
new Vue({
store,
router,
render: h => h(App)
}).$mount('#app')
Same in Vue 3:
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import { store } from './store'
import VueCookie from 'vue-cookie'
//Vue.use(VueCookie); //old line in vue 2
createApp.use('VueCookie'); //this is not works and return error
createApp(App).use(router,store).mount('#app') //Is this line correct?
What am I missing here?
Try like following, first define app then use it:
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import VueCookie from 'vue-cookie'
const app = createApp(App);
app.use(router);
app.use(store);
app.use(VueCookie);
app.mount('#app')
You can use it like:
import VueCookie from 'vue-cookie'
VueCookie.set("mycookie", "value", "1h")

How to Inject Vuex store into Vue 3

How would I inject vuex into Vue 3, in Vue 2 it was possible like:
new Vue({
el: '#app',
store: store,
})
But in Vue 3 how would you do it since there is no new Vue().
The created store will be injected using .use method :
import { createApp } from 'vue'
import { createStore } from 'vuex'
// Create a new store instance.
const store = createStore({
state () {
return {
count: 1
}
}
})
const app = createApp({ /* your root component */ })
// Install the store instance as a plugin
app.use(store)
For more details check the Vuex 4 docs
To use it in child component in options api, try to provide it as follows :
app.use(store)
app.config.globalProperties.$store=store;
then use it like $store in child components
for composition api (setup hook), you could just import the useStore composable function which returns the store instance :
import {useStore} from 'vuex'
setup(){
const store=useStore()// store instead of `$store`
}
Together with Router:
import * as Vue from 'vue';
import App from './App.vue';
import router from './routes';
import {store} from "./store/store";
Vue.createApp(App).use(router, store).mount('#app');

Laravel Vue.js component registration

I am creating a simple Vue.js application with Laravel. I have registered Vue.js with:
import Vue from 'vue';
import VueRouter from 'vue-router';
Vue.use(VueRouter);
import App from './components/App';
const app = new Vue({
el: '#app',
components: {
App
},
router,
});
If I create a custom component, this works just fine:
Vue.component('nav-section', {
template: `<div>This is odd</div>`
});
I can then call <nav-section></nav-section> in any given template, and it will output "This is odd."
However if I use Laravel's require method like so:
Vue.component('nav-section', require('./components/Navigation'));
It is not working anymore. <nav-section></nav-section> is empty, blank.
No errors in npm or console. Am I missing something, or some logic behind require?
Navigation.vue:
<template>
<div>
<span>Sample text</span>
</div>
</template>
<script>
export default {}
</script>
Vue.js:
import Vue from 'vue';
import VueRouter from 'vue-router';
Vue.use(VueRouter);
import App from './components/App';
Vue.component('nav-section', require('./components/Navigation'));
const app = new Vue({
el: '#app',
components: {
App
},
router,
});
Try writing it out like this, with the extension and default:
Vue.component('nav-section', require('./components/Navigation.vue').default);

Correct way to install custom VueJs Plugin

Im creating a custom plugin that encapsulates a bunch of authentication functionality with vuex and vue-authenticate.
The problem im having is figuring out the correct way to load and install the module into VueJS, im not sure if its my webpack or vuejs knowledge that is lacking but so far I have the following
/node_modules/plugin/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import routes from './routes'
import store from './vuex/store'
import EventBus from './bus/eventBus'
import config from './config'
import ping from './vuex/modules/apiArchitect/ping/store'
import auth from './vuex/modules/apiArchitect/auth/store'
import user from './vuex/modules/apiArchitect/user/store'
Vue.use(Vuex)
Vue.use(EventBus)
const store = new Vuex.Store({
modules: {
ping,
user,
auth
},
strict: true
})
let apiArchitect = {}
apiArchitect.install = function (Vue, options) {
Vue.prototype.$apiArchitect = store,
Vue.prototype.$apiArchitect.$config = config
Vue.prototype.$apiArchitect.$routes = routes
if (typeof window !== 'undefined' && window.Vue) {
window.Vue.use(apiArchitect)
}
}
export default apiArchitect
/src/main.js
import Vue from 'vue'
import App from './App'
import router from './router'
import apiArchitect from 'vue-apiarchitect'
import addRouteGuards from 'vue-apiarchitect/src/addRouteGuards'
Vue.config.productionTip = false
Vue.config.env = process.env.NODE_ENV
Vue.use(router)
Vue.use(apiArchitect)
console.log(apiArchitect)
addRouteGuards(router)
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
template: '<App/>',
components: { App }
})
So far I am able to import the plugin and run the install hook with Vue.use(apiArchitect) I can access this.$apiArchitect in my App.vue.
The problem I have is that the plugin provides some auth routes stored in $apiArchitect.routes these routes need to be merged with the routes provided by router. If I try access $apiArchitect.routes in main.js I get an 'undefined' error I can only access them after vue has been instantiated. If I actually try console.log apiArchitect in main.js all I see is an object containing an install function none of the plugin i've provided which makes me belive its not installing correctly.
Does anyone know how i can access the apiArchitect.$routes property in main.js or a better way of achieving this?
Thanks
You can add routes dynamically with router.addRoutes() since 2.2.x.
The argument must be an Array using the same route config format with
the routes constructor option.
For example, you can use addRoutes in created hook of the root component:
// your plugin
const myPlugin = {
install: function(Vue, options) {
Vue.prototype.$myPlugin = {
routes: [{
path: '/myplugin', component: options.myComponent
}]
}
}
}
// components
const testComponent = { template: '<p>Component called by plugin route</p>' }
const Home = { template: '<p>Default component</p>' }
// router
const router = new VueRouter({
routes: [{
path: '/', component: Home
}]
})
Vue.use(VueRouter)
Vue.use(myPlugin, { myComponent: testComponent })
new Vue({
el: '#app',
router,
created() {
this.$router.addRoutes(this.$myPlugin.routes); // dinamically add routes
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.0/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<div id="app">
<button #click="$router.push('/')">Home</button>
<button #click="$router.push('/myplugin')">Custom</button>
<router-view></router-view>
</div>

Categories

Resources