How to register global components with vue-router - javascript

I'm using Vue.js with the vue-cli. I chose for the webpack setup.
I wired up the main.js file for routing, though I can't find a way to globally register my components.
main.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import App from './App'
import Companies from './components/pages/Companies'
import Income from './components/pages/Income'
import Login from './components/pages/Login'
Vue.use(VueRouter)
let router = new VueRouter()
router.map({
'/companies': {
component: Companies
},
'/income': {
component: Income
},
'login': {
component: Login
}
})
router.start(App, 'body')
App.vue
<template>
<div>
<router-view></router-view>
</div>
</template>
<script>
import {Auth} from './lib/api'
import Loader from './components/Loader'
export default {
components: {
Loader
},
ready () {
Auth.isLoggedIn().then(
(response) => {
if (response.data === false) {
this.$router.go('/login')
} else {
this.$router.go('/companies')
}
},
(response) => {
this.$router.go('/login')
}
)
}
}
</script>
When I use my Loader component in some view, I get the following warning.
[Vue warn]: Unknown custom element: - did you register the component correctly? For recursive components, make sure to provide the "name" option.
I provided the name in the component and it didn't make any difference. I'm using the loader-component in the login-view.
I found out that I should either define the component in the component that I'm going to use it or globally. Though, I can't find out how to define it globally with the routing.

The way you have it set up now, The loader component is only locally available in the template of the App component.
Routing has no influence on global component registration, just do it like without a router:
// main.js, before all the router stuff:
import Loader from './components/Loader'
Vue.component('loader', Loader)
or register it locally in your Login component. As you already did it in App.vue, you know what to do with Loader.vue

Related

vue3 cannot use bootstrap component

I'm in studying with Vuejs and I tried to use bootstrap/vue-boostrap component like Card or b-table but when I use them
[Vue warn]: Failed to resolve component: b-table
If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement. at
then I tried to import component in javascript and this what I got:
[plugin:vite:import-analysis] Failed to parse source for import analysis because the content contains invalid JS syntax. Install #vitejs/plugin-vue to handle .vue files.
So, I import #vitejs/plugin-vue according above, but it still got same.
App.vue
<header>toDoList</header>
<b-table striped hover :items="list"></b-table>
<input v-model="newTask">
<input v-model="newTaskDate">
<button #click="addnewTask()">add new Task</button>
</template>
<script>
import { BTable } from bootstrap-vue;
export default {
data() {
return {
list: [{name:"Doing somwthing",date:"1"}],
newTask: '',
newTaskDate: ''
}
},
methods: {
addnewTask() {
this.list.push({name:this.newTask, date:this.newTaskDate})
}
}
}
</script>
main.js
import App from './App.vue'
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'
import './assets/main.css'
createApp(App).mount('#app')
BootstrapVue is not Vue 3 compatible at the time.
You can only use BootstrapVue with Vue 3 Migration Build.
Check the Vue.js 3.x initial support and be sure your configure your setup accordingly.
Maybe it's a typo on your side, but what about this one? Note the quotes in the import statement.
import { BTable } from 'bootstrap-vue';

how to properly pass prop from laravel 8 blade to vue 3 component

I'm trying to get the value of user prop as in the blade file when the App component is mounted but I get undefined in the console. I was wondering if something changed in Vue 3 because it worked in Vue 2.
How can I get the value of the user prop?
laravel.blade file
#extends('layouts.app')
#section('content')
<App
#if(auth()->check())
:user="1"
#endif>
</App>
#endsection
App.vue
<template>
<div> {{user}} </div>
</template>
<script>
export default {
name: 'App',
props: [ 'user'],
mounted(){
console.log(this.user)
}
}
</script>
app.js
import { createApp } from 'vue';
import App from './components/App'
import router from './router';
require('./bootstrap');
const app = createApp(App)
app.use(router).mount("#app")
From the migration docs:
The propsData option has been removed. If you need to pass props to the root component instance during its creation, you should use the second argument of createApp
const app = createApp(
{
props: ['username'],
template: '<div>{{ username }}</div>'
},
{ username: 'Evan' }
)
It's not as convenient as the Vue 2 way, and I haven't found a good work-around of sending data from your Laravel controller directly to your Vue component. Best bet may be to get the info by querying your API in the created() method in Vue.

How to enable autocompletion for globally registered Vue components in VSCode?

The autocompletion feature of VSCode works perfectly fine with local registration of Vue components, like so:
<template>
<base-button />
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import BaseButton from '#/components/base/BaseButton.vue';
#Component({
components: { BaseButton }
})
export default class MyComponent extends Vue {}
</script>
Then, for example, with my base-button which has the props extraClass, id, and type, VSCode shows me all of them properly:
But when I register my base components globally in main.ts, like so:
import Vue from 'vue';
import App from './App.vue';
import BaseButton from '#/components/base/BaseButton.vue';
Vue.component('BaseButton', BaseButton);
Vue.config.productionTip = false;
new Vue({
render: h => h(App)
}).$mount('#app');
Vue still works as expected but VSCode now won't show me any autocompletions for those components.
How can I change that?
How can I enable VSCode to show me the autocompletion for the props of my self-written components when I register them globally?

Vue and Rollup: how to bundle a collection of components?

I want to bundle a couple of components that I wrote in Vue. To do
so I am using Rollup with an index.js file (the file which I call Rollup on) that looks like this:
import ComponentA from './components/ComponentA'
import ComponentB from './components/ComponentB'
var myMod = {
ComponentA: ComponentA,
ComponentB: ComponentB
}
window.myMod = myMod
that then gets bundled into main.js.
I can include my module now in an HTML page with a normal <script src="main.js"> tag.
From here I can now defined components that use my modules components e.g.
ComponentA = myMod.ComponentA
app = new Vue({
el: '#app',
components: { ComponentA },
// components: myMod, also works if I want to use all the components
template: ` ...<ComponentA/>...`
})
and, until recently, this was fine for me.
I was wondering I could now use my module of components in a single file vue component outside of my module (e.g. if I want to make a site with vue-cli-3).
e.g.
<template>...</template>
<script>
import myMod from 'main.js'
ComponentA = myMod.ComponentA
export default {
name: 'SFCInAnotherApp',
components: { ComponentA },
}
</script>
<style>...</style>
I have tried changing my index.js file to:
export default myMod
rather than window.myMod
however, now when I import my component, the module is undefined..
e.g.
<template>...</template>
<script>
import myMod from 'main.js'
console.log(myMod)
ComponentA = myMod.ComponentA
export default {
name: 'SFCInAnotherApp',
components: { ComponentA },
}
</script>
<style>...</style>
----> undefined
if I keep the window.myMod = myMod line, once the page renders (with errors from the apps trying to use myMod components), I can of course access myMod with no issue.
How do I use rollup to create a collection of components that I can then, from other vue projects, import via either:
import {componentA} from '<path-to-myMod>'
or
import myMod from '<file-with-my-mod>'
var ComponentA = myMod.ComponentA
In short:
Using Rollup, how should I in my index.js file import my Vue components and export my module so that I can use it as I currently do as well as import it into single file components?

Using mixins with Vuejs

I'm currently learning how to develop an app with Vuejs. I have a main.js file with the code for setting up Vue.js. I created a new directory /mixins with a new file api.js. I want to use that as mixin so that every component can use a function to access my api. But I don't know how to do it.
This is my /mixins/api.js file:
export default{
callapi() {
alert('code to call an api');
},
};
This is my main.js file:
import Vue from 'vue';
import VueRouter from 'vue-router';
import VueResource from 'vue-resource';
import { configRouter } from './routeconfig';
import CallAPI from './mixins/api.js';
// Register to vue
Vue.use(VueResource);
Vue.use(VueRouter);
// Create Router
const router = new VueRouter({
history: true,
saveScrollPosition: true,
});
// Configure router
configRouter(router);
// Go!
const App = Vue.extend(
require('./components/app.vue')
);
router.start(App, '#app');
How can I include my mixin the right way now, so that every component has access to the callapi() function?
If you want to use a mixin on a specific component, rather than all components, you can do it like this:
mixin.js
export default {
methods: {
myMethod() { .. }
}
}
component.vue
import mixin from 'mixin';
export default {
mixins: [ mixin ]
}
Another thing you might consider is using a component extension design pattern i.e. creating a base component and then inheriting from that in sub components. It's a little more involved but keeps code DRY if you have many components sharing many options and perhaps inheriting the template too.
I've written about it on my blog if you're interested.
You can apply mixin globally using Vue.mixin
api.js
------
export default {
methods: {
callapi() {};
}
}
main.js
-------
import CallAPI from './mixins/api.js';
Vue.mixin(CallAPI)
As the documentation states you should use it carefully:
Use global mixins sparsely and carefully, because it affects every single Vue instance created, including third party components.

Categories

Resources