VueJS plugins conflict - vuejs2

I created two plugins in my VueJS app powered by Vue CLI 4 but when I tried to use it in my page only one will be working
| plugins
|-- axios.vue
|-- authentication.vue
axios.vue
import Vue from "vue";
Plugin.install = function(Vue) {
Vue.prototype.$myName = "Dean Armada";
};
Vue.use(Plugin);
export default Plugin;
authentication.vue
import Vue from "vue";
Plugin.install = function(Vue) {
Vue.prototype.$name = "Chris Guinto";
};
Vue.use(Plugin);
export default Plugin;
main.js
import axios from "./plugins/axios.js";
import authentication from "./plugins/authentication.js";
Vue.use(axios);
Vue.use(authentication);
instructions.vue
<template>
<div>
Hello World
</div>
</template>
<script>
export default {
created() {
console.log(this.$name);
console.log(this.$myName);
}
}
</script>
<style lang="scss" scoped>
</style>
TAKE NOTE
The output above will be "Dean Armada" only and the console.log(this.$name) is undefined
But if I commented out the Vue.use(axios) the console.log(this.$name) will work so the output will be "Chris Guinto" and the other one is undefined because the axios plugin is not activated
So how can I make them both work at the same time?

Perhaps try and simplify it a little with the following approach?
// plugins/axios.js
export default {
install(Vue){
Vue.prototype.$myname = "Dean Armada";
}
}
// plugins/authentication.js
export default {
install(Vue){
Vue.prototype.$name = "Chris Guinto";
}
}
// main.js
import axios from "./plugins/axios.js";
import authentication from "./plugins/authentication.js";
Vue.use(axios);
Vue.use(authentication);
new Vue({
el: '#app',
render: h => h(App)
})

Related

access component from .js file vuejs

I am using: https://www.npmjs.com/package/vue-loading-overlay
My main.js file looks like:
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
new Vue({
render: h => h(App),
}).$mount('#app')
And App.vue:
<template>
<div id="app">
<loading
:active.sync= "isLoading"
:can-cancel= "false"
:is-full-page= "false">
</loading>
<router-view></router-view>
</div>
</template>
<script>
//import Vue from 'vue';
import Loading from 'vue-loading-overlay';
import 'vue-loading-overlay/dist/vue-loading.css';
//Vue.use(Loading);
export default {
data() {
return {
isLoading: true
}
},
name: 'App',
components: {
Loading
}
}
</script>
<style>
</style>
This seems to work fine, but how can I manipulate the isLoading to be true or false, from main.js? I might be building a function or something in main.js for future use, and instead of having the <loading> on each view page, I would prefer to be able to control it globally some how.
I haven't tested this, but based on the referenced answer in my comment, this might work:
main.js
new Vue({
el: '#app',
props: ['isLoading'],
components:{App},
template: '<App v-bind:isLoading="true">'
})
You would have to make isLoading a prop in App.vue. The v-bind part above should make the prop reactive.
Also, you could create a bus and send events from main.js to App.vue, then update isLoading accordingly.
You should use store for it.
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
let store = new Vuex.Store({
state: {
isLoader: false,
},
getters: {
isLoader(state) {
return state.isLoader
},
},
mutations: {
isLoader(state, status) {
state.isLoader = status
},
},
actions: {
isLoader({commit}, status) {
commit('isLoader', status)
},
}
})
everywhere in your application you can set the isLoader to true using dispatch
vue.$store.dispatch("isLoader", true/false);

How do you include vuetify inside web component

I'm building a web component using the following command :
vue-cli-service build --target wc --name my-element 'src/components/mycomponent.vue'
I would like to use Vuetify inside of this component. How do I add it to mycomponent.vue so that it is scoped inside the component's shadow root?
This component will be dynamically loaded into apps built with other frameworks/styles. I want the web component to be able to use, for example, v-btn, v-layout, etc. within it.
Thank you,
Donnie
For vuetify 2.x, it requires initialization on Vue instance as follows.
// plugins/vuetify.js
import Vue from 'vue'
import Vuetify from 'vuetify/lib'
Vue.use(Vuetify);
const opts = {};
export default new Vuetify(opts);
// main.js
import Vue from 'vue';
import App from './app.vue';
import vuetify from './plugins/vuetify';
new Vue({
vuetify,
render: h => h(App),
}).$mount('#app');
You need to move such initialization into your web component instead.
<template>
...
</template>
<script>
import { VBtn, VLayout } from 'vuetify/lib'
import vuetify from '../plugins/vuetify';
export default {
name: 'MyWebComponent',
vuetify,
components: {
VBtn,
VLayout
},
...
}
</script>
<style>
...
</style>
From v1.3, you can import individual components, A La Carte...
<template>
<!-- whatever -->
</template>
<script>
import { VBtn, VLayout } from 'vuetify/lib'
export default {
name: 'MyElement',
components {
VBtn,
VLayout
},
// etc
}
</script>
See https://vuetifyjs.com/en/framework/a-la-carte#importing-components

VueJS Resource throwing undefined error on exact code as other project

I am learning VueJS and I love it! but for the last 2 days I have been stuck on a weird problem.
I made a previous project and there the exact same code DOES work. In my new project (learning project) the identical code does NOT work.
It results in this error:
My code is as follow (everything works perfect except the resource):
Main.js
import Vue from 'vue'
import App from './App.vue'
import VueResource from 'vue-resource'
import router from './router'
Vue.config.productionTip = false
Vue.use(VueResource);
Vue.http.options.root = 'https://myapi.com/v1/list/';
Vue.http.interceptors.push((resource, next) => {
this.method = 'GET';
next();
});
new Vue({
el: '#app',
router,
render: h => h(App)
});
Home.vue code:
<template>
<div>
<StatsRowOne></StatsRowOne>
<button class="btn btn-primary" v-on:click="submit">search</button>
</div>
</template>
<script>
import StatsRowOne from './elements/StatsRowOne';
export default {
data(){
return {
results: [],
resource: {}
}
},
components: {
StatsRowOne: StatsRowOne
},
methods: {
submit() {
this.resource.get().then(function(response) {
alert('done');
});
}
},
created() {
this.resource = this.$resource('auto');
}
}
</script>
<style lang="scss" scoped>
</style>
A further explanation from my comment: the this.method is undefined on line 7 in your main.js file because it is used in an arrow function. Remember that arrow functions in ES6 preserves the lexical this, so you are actually not accessing the property correctly because this does not point to anything exposed by the interceptor in the callback.
Based on the documentation, it appears that you should be using resource.method instead.

I can't access to Vuex data: using vue-cli webpack

Right now, I'm trying to show the contents of state object from store.js on my App.vue.
I've tried vuex examples on Medium and other website, but I'm keep failing: non of them worked: some of them even gave me a WebPack config error.
My App.vue
<template>
<div id="app">
<img src="./assets/logo.png">
<h1>TEST</h1>
</div>
</template>
<script>
import Store from './store/index'
export default {
name: 'App',
Store
}
</script>
My store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
alpha: ['1st data']
},
mutations: {
ADD ({ alpha }) {
const beta = 'new!'
state.alpha.push(beta)
}
}
})
My main.js
import Vue from 'vue'
import App from './App'
import Vuex from 'vuex'
import store from './store/index'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
store,
components: { App },
template: '<App/>'
})
You shouldn't be importing the store in App.vue. It only needs to be included in main.js and passed as an option when constructing the Vue instance. Within a component, the store is thereafter accessible via this.$store.
Second, your mutation should receive a context object as it's first parameter. context consists of properties such including state and commit. Those are the ways in which you access state within a mutation.
// notice context is the first parameter
mutations: {
ADD (context, { param }) {
const beta = 'new!'
context.state.alpha.push(beta)
})
}
// you can also deconstruct context like this
mutations: {
ADD ({state}, { param }) {
const beta = 'new!'
state.alpha.push(beta)
})
}
I also changed the way alpha to param. You don't receive the state's properties unless you destructure even further.
The problem is that in your main.js is missing Vue.use(veux)
you should have something like this:
import Vue from 'vue'
import Vuex from 'vuex'
import App from './App'
import store from './store'
Vue.use(Vuex) // <-- Add this
/* eslint-disable no-new */
new Vue({
el: '#app',
store,
template: '<App/>',
components: { App }
})

Vue.js 2 - How to $emit event from one application/instance Vue to an other?

I use webpack with Single File Component.
I have 1 instance of Vue in my menu header to show a Cart Shopping dropdown :
import Vue from 'vue';
import App from './AppShoppingCart.vue';
new Vue({
el: '#shoppingCartApp',
template: '<App/>',
components: {App}
});
I have an other Vue instance in the same page (the catalog with products) :
import Vue from 'vue';
import App from './AppCatalog.vue';
new Vue({
el: '#catalogApp',
template: '<App/>',
components: {App}
});
I want to $emit an event from one instance to the other :
when Catalog change, I want to call a function in ShoppingCart.
I test eventHub :
import Vue from 'vue';
var eventHub = new Vue();
export default eventHub;
So I import event on each instance :
import eventHub from './events/eventHub';
In Catalog :
eventHub.$emit( "actproductslist-changed" );
In ShoppingCart :
eventHub.$on('actproductslist-changed', function(){ alert('AppShoppingCart') } );
But this won't works. It only works if the $on and $emit are in the same instance of Vue.
I think webpack create 2 modules and I can't share variables between my 2 instances.
Any one have an idea to have global variable with multiple instance with webpack ?
This setup works, where main.js is your entry point.
bus.js
import Vue from "vue"
const bus = new Vue();
export default bus;
main.js
import Vue from 'vue'
import App from './App.vue'
import App2 from './App2.vue'
new Vue({
el: '#app',
render: h => h(App)
})
new Vue({
el:"#app2",
render: h => h(App2)
})
App.vue
<template>
<button #click="sendMessage">Send Message</button>
</template>
<script>
import Vue from "vue"
import bus from "./bus"
export default {
methods:{
sendMessage(){
bus.$emit("testing")
}
}
}
</script>
App2.vue
<template></template>
<script>
import Vue from "vue"
import bus from "./bus"
export default {
mounted(){
bus.$on("testing", ()=> alert("message received"));
}
}
</script>
Post comment edit
To communicate across entry points, you can expose the bus Vue on the window.
webpack.config.js
entry: {
"main": './src/main.js',
"main2": './src/main2.js'
},
output: {
path: path.resolve(__dirname, './dist'),
publicPath: '/dist/',
filename: '[name].js'
},
bus.js
import Vue from "vue"
window.bus = new Vue();
main.js
import Vue from 'vue'
import App from './App.vue'
new Vue({
el: '#app',
render: h => h(App)
})
main2.js
import Vue from 'vue'
import App2 from './App2.vue'
import bus from "./bus"
new Vue({
el:"#app2",
render: h => h(App2)
})
App.vue
<template>
<button #click="sendMessage">Send Message</button>
</template>
<script>
import Vue from "vue"
export default {
methods:{
sendMessage(){
if (bus)
bus.$emit("testing")
}
}
}
</script>
App2.vue
<template></template>
<script>
import Vue from "vue"
export default {
mounted(){
bus.$on("testing", ()=> alert("message received"));
}
}
</script>
Note here that since bus is only imported in main2.js, you need to guard the use of it in App.vue for those cases where it might not exist (because it is only imported in main2.js).