Set global variables from another js file in vue 3 - vue.js

Folder structure
main.js
/test/index.js
main.js file
import { createApp } from 'vue'
const app = createApp(App);
//the rest of code
app.config.globalProperties.$apple = "apple value";
app.config.globalProperties.$orange = "orangevalue";
/test/index.js file
app.config.globalProperties.$testvalue = "123";
How to set the global variable in /test/index.js in vue3

In /test/index.js define a plugin with this content :
export default {
install: (app) => {
app.config.globalProperties.$testvalue = "123";
}
}
then in main.js use it in this way app.use(testPlugin):
import { createApp } from 'vue'
import testPlugin from './test'
const app = createApp(App);
//the rest of code
app.config.globalProperties.$apple = "apple value";
app.config.globalProperties.$orange = "orangevalue";
app.use(testPlugin)

Related

Making global plugin that I can use anywhere in app

I have this class for sockets. Is there any way that I could make this globally accessible? I'd like to access the functions anywhere in my app for example like $socket.methodName()
What I've tried
class InitSocket {
constructor(options) {
this.options = options;
}
connect() {
console.log(this.options);
}
}
export default {
install: (Vue, options) => {
Vue.prototype.$socket = new InitSocket(options);
},
};
in main.js
const { createApp } = require('vue');
import App from "./App.vue";
import Sockets from './plugins/Socket'
const app = createApp(App);
app.use(Sockets , "test");
app.mount("#app");
But I am getting this message
Cannot set properties of undefined (setting '$socket') - What am I doing wrong?
In Vue 3 you can have multiple apps and you can no longer add to Vue prototype.
In order to write and use a plugin, follow the steps:
Step 1: Create the plugin
export default {
install: (app, options) => {
class InitSocket {
constructor(options) {
this.options = options;
}
connect() {
console.log(this.options);
}
}
// inject a globally available $socket() method
app.config.globalProperties.$socket = new InitSocket(options)
}
}
Step 2: Import and install it in main.js
import { createApp } from 'vue'
import App from "./App.vue";
import Sockets from './plugins/Socket'
const app = createApp(App);
app.use(Sockets , "test");
app.mount("#app");
Read more on the Vue docs: Plugins

Vue build didnt include my function to output .js file

Works fine in dev mode, but after build process vue not includes setupToken function (from #/api.js) to app.js output file.
// App.vue
//...
import { setupToken } from '#/api
export default {
mounted () {
this.setupToken() // TypeError: this.setupToken is not a function
}
}
// #/api.js
import { mande } from 'mande'
export const postsAPI = mande(`${process.env.VUE_APP_ROOT_URL}/api/v1/posts`)
export const setupToken = ({ token }) => {
postsAPI.options.headers.Authorization = 'Bearer ' + token
}
I guess the problem with webpack config (im using default one), but not sure how to fix it.
setupToken does not exist on the object you're exporting from App.vue.
You are importing setupToken from #/api so you have to call it directly, i.e. setupToken() and not as an instance method, i.e. this.setupToken()
WebPack sees you are not using the method you're importing from #/api (because you are calling it as an instance method) so it tree-shakes it out.
BTW, try using TypeScript, it would have let you know of that error.
Import api.js in main.js
import Vue from 'vue'
import App from './App.vue'
import api from './api'
Vue.config.productionTip = false
new Vue({
api,
render: function (h) {
return h(App)
},
}).$mount('#app')
Modify api.js:
import Vue from 'vue'
Vue.mixin({
methods: {
setupToken({ token }) {
postsAPI.options.headers.Authorization = 'Bearer ' + token
}
}
}

(vue) Uncaught InternalError: too much recursion: failed to use axios

I met a weird problem, when I set up main.js and run the server, it shows me this error
and here is my code in main.js,
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import ElementPlus from 'element-plus';
import axios from 'axios'
import 'element-plus/lib/theme-chalk/index.css';
axios.defaults.baseURL = 'http://localhost:8000'
const app = createApp(App)
app.use(store)
app.use(router)
app.use(ElementPlus)
console.log('1111')
app.use(axios)
console.log('aaa')
app.mount('#app')
I set a console.log to track the error, the '1111' shows but 'aaa' never shows, so I can only know the error occurs in the line app.use(axios), that's so confusing, did anyone ever met this problem? How to solve it?
Here you have 2 options:
If you're using Vue3, import it in your Vue, like you did, but as written in this awnser, i think you should do something more like that:
import { createApp } from 'vue'
import axios from 'axios'
import VueAxios from 'vue-axios'
const app = createApp(App)
app.use(VueAxios, axios) // 👈
app.mount('#app')
You wanna use only axios and don't get bothered by it, then you don't have to use VueAxios or make something like app.use(axios) in your main.js, and then make a httpRequestsService file which will handle all the axios part.
For example, here is mine:
import axios from "axios";
axios.defaults.baseURL = process.env.API_BASE_URL
axios.interceptors.response.use(res => res, err => {
// some code if you wanna handle specific errors
throw err;
}
);
const getHeader = (method, endpoint, header, body) => {
const publicEndpoints = [
{
method: 'POST',
endpoint: '/auth/local'
}
]
const publicEndpoint = publicEndpoints.find(e => e.method === method && e.endpoint === endpoint)
if (!publicEndpoint) {
header.Authorization = localStorage.getItem("jwt")
}
return body ? { headers: header, data: body } : { headers: header }
}
export default {
get(endpoint, header = {}) {
return axios.get(endpoint, getHeader('GET', endpoint, header))
},
post(endpoint, body = {}, header = {}) {
console.log(body)
return axios.post(endpoint, body, getHeader('POST', endpoint, header))
},
put(endpoint, body = {}, header = {}) {
return axios.put(endpoint, body, getHeader('PUT', endpoint, header))
},
delete(endpoint, body = {}, header = {}) {
return axios.delete(endpoint, getHeader('DELETE', endpoint, header, body))
},
}

how to get access to vuex inside other js files like plugins in nuxt

i have a problem. i wanna get access to one of my getters inside my vee-validate.js file.
how can i do that?
in my pages and components, (in <script>...</script> part, outside export default{...}) i used this function:
component.vue
<script>
let lang;
function getLang({store}) {
lang = store.state.lang
}
export default{
...
}
but it is not working!
i'm trying to access my custom lang file (for translation purpose) that is stored in lang state in my vuex, and use it in vee-validate.js file for custom message.
i tried to import store but not working.
veevalidate.js:
import Vue from 'vue'
import { required } from 'vee-validate/dist/rules'
import { extend, ValidationObserver, ValidationProvider, setInteractionMode } from 'vee-validate'
import {store} from '../store'
let langFile = store
setInteractionMode('eager')
extend('required', {
...required,
message: ''
})
Vue.component('ValidationProvider', ValidationProvider);
Vue.component("ValidationObserver", ValidationObserver);
UPDATED: My store index.js
import langfile from '../static/lang'
export const state = () => ({
lang: null,
dir: null,
})
export const getters = {
//----------------- Language and Direction
lang(state){
return state.lang
},
dir(state){
return state.dir
},
}
export const mutations = {
SET_LANGUAGE(state, lang){
state.lang = lang
},
SET_DIRECTION(state, dir){
state.dir = dir
},
}
export const actions = {
async nuxtServerInit({dispatch, commit}) {
// ------------- Read Language File
let baseLang = process.env.SITE_LANGUAGE;
let siteLang = langfile[baseLang];
let siteDir = langfile[baseLang]['dir'];
commit('SET_LANGUAGE', siteLang);
commit('SET_DIRECTION', siteDir);
},
}

Vuex2.0 how to configure and how to getters

Early today try vuex 2.1.2 vue:2.1.0, the directory structure is as follows
store.js:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
import common from './common/store'
export default new Vuex.Store({
modules : {
common
}
})
mutations-types.js:
export const ADD_NUM = "ADD_NUM"
common/store.js:
import * as types from '../mutations-types'
const state = {
num : 1
}
const mutations = {
[types.ADD_NUM] : function(state){
state.num = state.num + 1;
},
}
export default {
state,
mutations
}
common/actions.js:
import * as types from '../mutations-types'
export default {
setNum : store => {
store.dispatch(types.ADD_NUM)
},
}
common/getters.js:
export default {
getNum : state => {
state.common.num
},
}
Then get the value of num in Hello.vue through getters
In the vue entry file main.js, a store is injected
run error:
Property or method "getNum" is not defined on the instance but
referenced during render
Why is this error reported? Does this directory structure and code correct?
First of all, I did not read the official documents
Using mapGetters solves the problem
THANKS #Potray
I refer to the official demo link