I'm creating a Laravel website that will be a single page application. I'm new to VueJS even if I have experience with javascript in general.
I need to display several routes, such as /blog/new, /blog/:id, /blog/edit, etc. /blog itself is defined by Laravel, and works as the blog index.
I installed vue-router, and tried to follow some examples I saw but nothing happens:
app.js
import './bootstrap';
import Vue from 'vue';
import VueRouter from 'vue-router';
const blogIndex = { template: require('./components/blog/index.vue') };
const blogNew = { template: require('./components/blog/new.vue')};
const routes = [
{
path: '/blog',
component: blogIndex,
name: 'blog-index'
},
{
path: '/blog/new',
component: blogNew,
name: 'blog-new'
}
];
const router = new VueRouter({
routes,
mode: "history"
});
Vue.use(VueRouter);
Vue.component('example', require('./components/Example.vue'));
Vue.component('navbar', require('./components/Navbar.vue'));
Vue.component('blog_index', require('./components/blog/index.vue'));
console.log(testvar);
const app = new Vue({
router
}).$mount('#app');
components/blog/index.vue
<template>
<div>
<h1>Blog index</h1>
<router-link :to="{ name: 'blog-new' }">New article</router-link>
<router-view></router-view>
</div>
</template>
<script>
export default {
mounted() {
console.log('blog#index mounted');
}
}
</script>
components/blog/new.vue
<template>
<h2>Here is blog/new y'all</h2>
</template>
<script>
export default {
mounted() {
console.log('blog#new mounted');
}
}
</script>
So far, the only thing that works is my address bar that gets modified, but the template itself doesn't seem to be loaded (I go from /blog to /blog/new).
I've seen that I need add <router-view></router-view> in my html file, but this triggers an error and blocks VueJS's display.
My question is: what am I missing, or what did I do wrong?
Thank you in advance
You need to use <router-view></router-view> in your main App.vue file, which is the part that new routes are loaded into.
<template>
<router-view></router-view>
</template>
You currently state you have this in components/blog/index.vue - which I believe is just for your nested routes. https://router.vuejs.org/en/essentials/nested-routes.html
Related
I'm currently building an app and I would like to add extensions to this app. These extensions should have their own Vue components and and views (and thus also routes). I don't want to rebuild the app but instead add the new views and routes dynamically. Is there a good way to do that with Vue 2?
In the following I added the files that I hope makes this question a bit more comprehensible. The router/index.js contains the basic structure and is added to the main.js file in the regular fashion. During the load of the app.vue the new routes should be loaded and appended to the already existing ones.
router
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
}
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
export default router
main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
Vue.config.productionTip = false
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
App.vue
<template>
<div id="app">
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link> |
<router-link to="/test">Test</router-link>
</div>
<router-view/>
</div>
</template>
<script>
// # is an alias to /src
import TestView from '#/views/Test.vue'
export default {
name: 'Home',
components: {},
created() {
<add route to router>({
component: TestView,
name: "Test",
path: "/test"
})
}
}
</script>
I used the phrase <add route to router> to demonstrate the way I would like to add the route. After the route is added the user should be able to directly navigate to the new view using <router-link to="/test">Test</router-link>.
Any help would be appreciated.
Use addRoute to add routes at runtime. Here is the explanation for this method from the docs:
Add a new route to the router. If the route has a name and there is already an existing one with the same one, it overwrites it.
Import the router into App.vue to use it:
App.vue
<script>
import router from './router/index.js';
import TestView from '#/views/Test.vue'
export default {
created() {
router.addRoute({
component: TestView,
name: "Test",
path: "/test"
})
}
}
</script>
TLDR: Ive nested a component into a views folder and it wont show, I believe I have imported it correctly and think I'm missing something / any help here would be great
im importing a component into a views file which is then to be displayed via the vue router - the issue is the component or view does not show -
Oddly this code works if I ask the router to display the component as a stand alone, but not when I nest the component into the views file:
File structure is:
VIEWS FILE importing the component to be nested inside of it:
src/views/Contact.vue <<<< i imagine I have an issue here but I cannot seem to figure this out
<template>
<div class="contact_container">
<Contact/>
</div>
</template>
<script>
import Contact from '#/components/Contact.vue'
export default {
name: 'Contact',
components: {
Contact
}
}
</script>
Component file
src/components/Contact.vue
<template>
<div>
<h1>Welcome to the contact page</h1>
</div>
</template>
<script>
export default {
name: 'Contact',
data(){
return{
}
}
}
</script>
Views Router File:
src/router/index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
import Contact from '../views/Contact.vue'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
},
{
path: '/contact',
name: 'Contact',
component: Contact
}
]
const router = new VueRouter({
routes
})
export default router
and finally App.veu
<template>
<div id="app">
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link> |
<router-link to="/contact">Contact</router-link>
</div>
<router-view/>
</div>
</template>
/// UPDATED ///
In the code below - what does the name property do?
(the code below is defining a component)
<template>
<div>
<h1>Welcome to the contact page</h1>
</div>
</template>
<script>
export default {
name: 'Contact-Component', <<<< what does this do?
data(){
return{
}
}
}
</script>
The reason why i'm a little lost here is because when we use this component we import it into another file using the below:
import Contact from '../views/Contact.vue'
In that process we have defined the component as Contact (so it is not referenced by its name any more) .... so why did we define a name?
If there is any documentation on this that would be amazing and while it seems like a silly question (and probably is) it is distracting me with curiosity...
Thanks for any help -
Wally
change your code with this
<template>
<div class="contact_container">
<Contact/>
</div>
</template>
<script>
import Contact from './components/Contact.vue'
export default {
name: 'Contact',
components: {
"Contact":contact
}
}
</script>
The name is used to allow the component to recursively invoke itself in its template. It also helps when debugging as it allows for a more helpful error message.
Have a read over this to get a better idea: https://v2.vuejs.org/v2/api/#name
You have to let the app know it's a Vue component:
<script lang="js">
import Vue from 'vue';
export default Vue.extend({
name: 'Contact',
...
});
The global function init() outputs a console log when the screen is loaded. However, clicking the child component button does not re-enable the init() function.
How can I call the global function init() when I click a button in my child's component?
App.vue (parent)
<template>
<div id="app">
<div id="nav">
<router-link :to="{name: 'home'}">Home</router-link> |
<router-link :to="{name: 'about'}">About</router-link>
</div>
<router-view></router-view>
</div>
</template>
<script>
import './assets/css/style.css'
import './assets/js/commmon.js'
export default {
}
</script>
Home.vue (child)
<template>
<div>
Home Button<br><br>
</div>
</template>
main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
Vue.config.productionTip = false
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
router.js
import Vue from 'vue'
import Router from 'vue-router'
import Home from './views/Home.vue'
import About from './views/About.vue'
Vue.use(Router)
export default new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{ path: '/', name: 'home', component: Home},
{ path: '/about', name: 'about', component: About},
]
})
function init() {
console.log('load inti()')
}
init();
$('#btn_link').click(function(){
init();
});
The whole idea of js modules is to stop you having, or supposedly needing, a global scope. People sometimes suggest a workaround of adding your global functions to the Vue object, which strikes me as a cure worse than the disease. My answer to this is to provide one global object in the root of your vue app, put your functions inside, then inject it into any component that needs it.
As it says in the comments, don't use jquery with Vue. Your event handler should be in the methods of the component that contains the button.
i am making a page with vue, vue-router and laravel, the problem, when i enter in localhost/myproject/public_html/, the Home component is not rendered in the router-view, if i click in the router link to the Service component, it render the content normally, and when i click to the home path it render the home component content, so why this happens? this is my app.js structure
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
import App from './views/App'
import Home from './views/Home'
import Service from './views/Service'
const router = new VueRouter({
mode: 'history',
routes: [
{
path: '/',
name: 'home',
component: Home
},
{
path: 'servicios',
'name' : 'services',
component: Service
}
],
});
const app = new Vue({
el: '#app',
components : { App },
router,
});
this is my App.vue
<template>
<div>
Hola
<router-link :to="{ name : 'services' }">
ir a servicios
</router-link>
<router-view>
</router-view>
</div>
</template>
<script>
import PageLogo from '../components/PageLogo'
import Loading from '../components/Loading'
export default {
mounted : function(){
console.log(this.$router.currentRoute.path)
},
components : {
'page-logo' : PageLogo,
'loading' : Loading
},
methods : {
ajaxOver : function() {
}
}
}
</script>
this is my Home.vue
<template>
<div class="row">
Home page
<router-link :to="{ name : 'services' }">
go to services
</router-link>
</div>
</template>
<script>
export default {
mounted: function() {
console.log('hola')
}
}
</script>
and this is Service.vue
<template>
<div>
Services page
<router-link :to="{ name : 'home' }">
go to home
</router-link>
</div>
</template>
<script>
export default {
mounted : function(){
console.log('services')
}
}
</script>
so how can i solve this? if i reload the page in any route, the component should be mounted, but in the vue router is not being displayed, so the component is not mounted.
Edit:
As requested, in App.vue the log is /myproject/public_html/
I've never used Laravel before, but I think you're looking for base.
Vue docs:
type: string
default: "/"
The base URL of the app. For example, if the entire single page application is served under /app/, then base should use the value "/app/".
Since you're serving your project at localhost/myproject/public_html/, vue is seeing /myproject/public_html/ instead of /.
You can change this by adding the base route to the vue-router constructor.
const router = new VueRouter({
mode: 'history',
base: '/myproject/public_html/',
...
}
New to Vue, working off a scaffolded project from the command line. Currently I have:
index.js
import Vue from 'vue'
import Router from 'vue-router'
import Home
from '../components/home'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'home',
component: Home
}
]
})
main.js
import Vue from 'vue'
import App from './App'
import router from './router'
Vue.config.productionTip = false
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
App.vue
<template>
<div id="app">
<router-view/>
</div>
</template>
<script>
export default {
name: 'App',
}
</script>
<style>
#app {
// default styles are here
}
</style>
And home.vue
<template>
<chart-component></chart-component>
</template>
// rest of home
I am trying to create and import chart-component.vue to use inside home.vue but not sure where to import it at. I've tried adding it in main.js and App.vue unsuccessfully.
chart-component.vue
<template>
<div>
<h1>Testing Chart Component</h1>
</div>
</template>
<script>
export default {
name: 'chart',
data() {
return {
}
}
}
</script>
This seems like a simple problem but unsure how to solve it. My best guess was importing it inside App.vue and adding a components { ChartComponent } underneath the name. Second attempt was importing it into main.js and putting ChartComponent inside components: { App, ChartComponent }.
I would rename your component to ChartComponent from chart-component, as the dash is not a supported character. Vue will properly convert the name to dashes as needed, but when you're searching your code for components, it helps to have consistent names.
anyway. for using a component, you need to import it and define it first
home.vue:
<template>
<ChartComponent></ChartComponent>
</template>
<script>
import ChartComponent from './ChartComponent';
export default {
components: {
ChartComponent
}
}
</script>
Got it to work. Since I only need it locally inside the home.vue component I imported it inside there under data I added
components: {
'chart-component': ChartComponent
}
Importing component becomes much easier in Vue 3 script setup SFCs
<script setup>
import ChartComponent from './components/ChartComponent.vue'
</script>
<template>
<ChartComponent />
</template>