Using import () in vue to import the component incorrectly - ecmascript-6

I'm using the babel-plugins-sync-dynamic -import package in the vue instance. What should I do?
I installed the babel-plugin-synch-dynamic -import package, and in the vue instance import the corresponding components, and he had the following error.
export default {
name: 'App',
created () {
console.log(111)
Promise.resolve(import('./Test.vue')).then(response => {
console.log(response.default) // //Shouldn't you load a component dynamically?
})
}
}
I wrote it like this.An error is as follows

Components are loaded either before the instance is created (global) or using the components property (local):
// global registration
Vue.component('test', import('./Test.vue')).then(m => m.default)
// local registration
new Vue({
components: {
'test': () => import('./Test.vue'))
}
})

Related

Vue.js / Mixins - Is there a way to get the global mixin-object outside of the vue component?

I am new with Vue.js
I am using Vue.js 2.4.4.
I have created the global mixin in my app.js file:
...
import router from './router'
...(some imports and plugins definitions)
Vue.use(VeeValidate);
Vue.component(VuePassword);
...
Vue.mixin({
data: function(){
return {
get auth(){
return Auth;
}
}
}
});
const app = new Vue({
el: '#root',
template: `<app></app>`,
components: { App },
router
});
This mixin imports some Auth object with validation methods e.t.c which needed to be in every component.
All of my components can check this mixin and it's working fine.
But I need to check the auth state after every route request, and I want to use my currently existing mixin, so I am trying to make something like this in my router.js file:
import Vue from 'vue'
import VueRouter from 'vue-router'
...
Vue.use(VueRouter);
const router = new VueRouter({
routes:[
...
]
});
router.beforeEach((to, from, next) => {
if(to.meta.requiresAuth) {
if(...call to mixin method) {
next();
} else {
next('/');
}
} else {
next();
}
});
export default router
Question:
Is there a way to get the global mixin object and change it's inner values or can you please give some small advise or example what is the right solution to this kind of tasks?
Or should I use the plugins instead of mixins?
I would rather create a seperate file for auth and not make it a mixin. Then using Vue.use() which will set auth on the vue object.
A sample of what the files might look like:
auth.js
export default function(Vue) {
Vue.auth = {
// do your auth logic
}
}
Then in your main js file
main.js
import Auth from './auth.js'
Vue.use(Auth);
Then you should be able to use Vue.auth
Another option would be keep using the mixin and pass the value to a store (like vuex) or create your own if your project is small...

Vue.js how to use npm plugins

I have tried multiple different plugins with my Vue.js cli webpack projects and I am getting the same problem with all of them, namely that once I have included a plugin, I am unable to use it.
As an example. I have tried to use the plugin at this link. https://www.npmjs.com/package/vue-sessionstorage
Here is my main.js file
import Vue from 'vue'
import router from './router'
import VueMaterial from 'vue-material'
import { store } from './store'
import 'vue-material/dist/vue-material.css'
import 'vue-style-loader'
import VueSessionStorage from 'vue-sessionstorage'
import App from './App'
Vue.use(VueMaterial, VueSessionStorage);
Vue.config.productionTip = false;
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
store,
template: '<App/>',
components: { App },
});
I have run npm install --save vue-sessionstorage
As you can see, I have also imported VueSessionStorage
However, when I try to use it like this
methods: {
login: function () {
console.log("Login clicked");
this.$session.set('username','simon')
console.log(this.$session.get('username'));
},
register: function () {
console.log(this.$session.get('username'));
}
}
I get the error
vue.esm.js?65d7:563 TypeError: Cannot read property 'set' of undefined
at VueComponent.login (Login.vue?2ddf:35)
at boundFn (vue.esm.js?65d7:179)
at Proxy.invoker (vue.esm.js?65d7:1821)
at Proxy.Vue.$emit (vue.esm.js?65d7:2331)
at click (mdButton.vue?3bf8:38)
at HTMLButtonElement.invoker (vue.esm.js?65d7:1821)
handleError # vue.esm.js?65d7:563
Vue.$emit # vue.esm.js?65d7:2333
click # mdButton.vue?3bf8:38
invoker # vue.esm.js?65d7:1821
Vue.use does not permit multiple plugins to be initialized at once like that. Initialize them as two separate calls:
Vue.use(VueMaterial);
Vue.use(VueSessionStorage);

How can I use the axios.interceptor in a right way?

I use vue-cli and this is part of my main.js.In Vue's single File components' structure, I use axios to replace the ajax.
import Vue from 'vue'
import App from './App'
import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(VueAxios, axios)
Vue.config.productionTip = false
new Vue({
el: '#app',
template: '<App/>',
components: { App }
})
It makes axios available in every SFC by referring (this.axios). But when I try to use axios.interceptor, I come across an annoying problem. I want to set axios.interceptor.request and axios.interceptor.reponse for the whole project. however, I can only use this.axios.interceptor.request in a Single File Component and it only work in this file. This is the part code of App.js.
methods: {
// interceptor
setAxiosInterceptor () {
this.axios.interceptors.request.use(config => {
this.cover = true
return config
}, error => Promise.reject(error)
)
this.axios.interceptors.response.use(response => {
this.cover = false
return response
}, error => {
this.cover = false
return Promise.reject(error)
})
},
I have to set this.axios.interceptor in every SFC. So how can I set the axios.interceptor for the whole project and make it available in every SFC.

Vue.js - Making helper functions globally available to single-file components

I have a Vue 2 project that has many (50+) single-file components. I use Vue-Router for routing and Vuex for state.
There is a file, called helpers.js, that contains a bunch of general-purpose functions, such as capitalizing the first letter of a string. This file looks like this:
export default {
capitalizeFirstLetter(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
}
}
My main.js file initializes the app:
import Vue from 'vue'
import VueResource from "vue-resource"
import store from "./store"
import Router from "./router"
import App from "./components/App.vue"
Vue.use(VueResource)
const app = new Vue({
router: Router,
store,
template: '<app></app>',
components: { App }
}).$mount('#app')
My App.vue file contains the template:
<template>
<navbar></navbar>
<div class="container">
<router-view></router-view>
</div>
</template>
<script>
export default {
data() {
return {
//stuff
}
}
}
</script>
I then have a bunch of single-file components, which Vue-Router handles navigating to inside the <router-view> tag in the App.vue template.
Now let's say that I need to use the capitalizeFirstLetter() function inside a component that is defined in SomeComponent.vue. In order to do this, I first need to import it:
<template>Some Component</template>
<script>
import {capitalizeFirstLetter} from '../helpers.js'
export default {
data() {
return {
myString = "test"
}
},
created() {
var newString = this.capitalizeFirstLetter(this.myString)
}
}
</script>
This becomes a problem quickly because I end up importing the function into many different components, if not all of them. This seems repetitive and also makes the project harder to maintain. For example if I want to rename helpers.js, or the functions inside it, I then need to go into every single component that imports it and modify the import statement.
Long story short: how do I make the functions inside helpers.js globally available so that I can call them inside any component without having to first import them and then prepend this to the function name? I basically want to be able to do this:
<script>
export default {
data() {
return {
myString = "test"
}
},
created() {
var newString = capitalizeFirstLetter(this.myString)
}
}
</script>
inside any component without having to first import them and then prepend this to the function name
What you described is mixin.
Vue.mixin({
methods: {
capitalizeFirstLetter: str => str.charAt(0).toUpperCase() + str.slice(1)
}
})
This is a global mixin. with this ALL your components will have a capitalizeFirstLetter method, so you can call this.capitalizeFirstLetter(...)
Working example: http://codepen.io/CodinCat/pen/LWRVGQ?editors=1010
See the documentation here: https://vuejs.org/v2/guide/mixins.html
Otherwise, you could try to make your helpers function a plugin:
EDIT March 1st 2018:
The official way to make a plugin is to create an object with an install function:
import Vue from 'vue'
import helpers from './helpers'
const plugin = {
install () {
Vue.helpers = helpers
Vue.prototype.$helpers = helpers
}
}
Vue.use(plugin)
You should then be able to use them anywhere in your components using:
this.$helpers.capitalizeFirstLetter()
or anywhere in your application using:
Vue.helpers.capitalizeFirstLetter()
You can learn more about this in the documentation: https://vuejs.org/v2/guide/plugins.html
Old response:
import helpers from './helpers';
export default (Vue) => {
Object.defineProperties(Vue.prototype, {
$helpers: {
get() {
return helpers;
}
}
});
};
Then, in your main.js file:
import Vue from 'vue'
import helpersPlugin from './helpersPlugin';
Vue.use(helpersPlugin);
Source: https://gist.github.com/logaretm/56126af5867e391ea9507b462259caf3
Import it in the main.js file just like 'store' and you can access it in all the components.
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
store,
router,
render: h => h(App)
})
Great question. In my research I found vue-inject can handle this in the best way. I have many function libraries (services) kept separate from standard vue component logic handling methods. My choice is to have component methods just be delegators that call the service functions.
https://github.com/jackmellis/vue-inject
The way to do this is to assign the helper functions on the global object, instead of exporting them:
window.capitalizeFirstLetter = (str) => {
return str.charAt(0).toUpperCase() + str.slice(1);
};

Inject Custom Store into Application

Vuex allows you to inject the store into your root instance, making it accessible via this.$store in all child components.
Without Vuex, is it possible to inject a custom store implementation into child components?
e.g.
// main.js
let app = new Vue({router, store, ...App}).$mount("#flightdeck-app")
export { app, store, router }
// SomeComponent.vue
export default {
name: "Overview",
components: { "credentials": Credentials },
computed: {
count() {
// injected store; is currently undefined.
return this.$store.state.items.length
}
},
Attempting to access this.$store results in undefined in child components, as Vuex seemingly has additional hooks to make this happen.
You may create a custom plugin for vue that register an initialize your custom store (or anything, I'll create a logger object just for demonstration).
For example you could have
//myLogger.js
export default {
install(Vue, options) {
function log(type, title, text) {
console.log(`[${type}] ${title} - ${text}`);
}
Vue.prototype.$log = {
error(title, text) { log('danger', title, text) },
success(title, text) { log('success', title, text) },
log
}
}
}
Before your main Vue instance tell to register your plugin
//main.js
import Logger from './path/to/myLogger';
Vue.use(Logger);
var vm = new Vue({
el: '#app',
template: '<App/>',
components: { App }
})
Now you can call this.$log on any child component
//myComponent.vue
export default {
data() {
return {};
},
methods: {
Save() {
this.$log.success('Transaction saved!');
}
}
}
Hope it helps, for more detail please see Vue plugins documentation
Just use in your components files:
import store from './vuex/store.js'
Place your store in separate file to get it clear.
Import store to every component where you need store.

Resources