I'm trying to render multiple components that use inline-templates using vue-router but as soon as i define the inline-template the component renders no matter the url.
Does inline-templatesworks with vue-router?
It really depends on what you mean by "work". You can Frankenstein something like this and it will do what you want without throwing any errors, but I feel I'm making the world an uglier place by just posting this example:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Vue-router with inline-template</title>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
</head>
<body>
<div id="app">
<router-link to="/foo">Go to Foo</router-link>
<router-link to="/bar">Go to Bar</router-link>
<router-view>
<foo inline-template id="foo"><div>foo</div></foo>
</router-view>
</div>
<script>
const Foo = { template: document.getElementById('foo').innerHTML };
const Bar = { template: '<div>bar</div>' };
const routes = [
{ path: '/foo', component: Foo },
{ path: '/bar', component: Bar },
];
const router = new VueRouter({
routes,
});
var app = new Vue({
el: '#app',
router,
});
</script>
</body>
</html>
This is pretty much the intro example from vuejs.org with one of the templates made into inline.
You can refer to your inline template using #
const Foo = { template: '#my-foo-template' }
const routes = [
{ path: '/foo', component: Foo },
];
<foo inline-template id="my-foo-template"> ... </foo>
Related
I'm using vue router to load components. The Home & About components load fine in the browser but the Login component fails to load and returns the error above.
resources/js/components/LoginComponent.vue
<template>
<div>
<h1>login</h1>
</div>
</template>
<script>
export default {}
</script>
resources/js/app.js
import './bootstrap';
import LoginComponent from "./components/LoginComponent.vue";
const Home = { template: '<div>Home</div>' }
const About = { template: '<div>About</div>' }
const routes = [
{ path: '/', component: Home },
{ path: '/about', component: About },
{ path: '/login', component: LoginComponent } // edited
]
const router = VueRouter.createRouter({
// 4. Provide the history implementation to use. We are using the hash history for simplicity here.
history: VueRouter.createWebHashHistory(),
routes, // short for `routes: routes`
})
// 5. Create and mount the root instance.
const app = Vue.createApp({})
app.use(router)
app.mount('#app')
app.blade.php
<body>
<div id="app">
<h1>Hello App!</h1>
<p>
<!-- use the router-link component for navigation. -->
<!-- specify the link by passing the `to` prop. -->
<!-- `<router-link>` will render an `<a>` tag with the correct `href` attribute -->
<router-link to="/">Go to Home</router-link>
<router-link to="/about">Go to About</router-link>
<router-link to="/login">Go to Login</router-link>
</p>
<!-- route outlet -->
<!-- component matched by the route will render here -->
<router-view></router-view>
Can you spot anything obvious as I'm stumped at the moment?
Edit:
For the correct usage of my particular versions of vue & vue-router
resources/js/app.js
import LoginComponent from "./components/LoginComponent.vue";
import './bootstrap';
const Home = { template: '<div>Home</div>' }
const routes = [
{ path: '/', component: Home },
{ path: '/login', name: "Login", component: LoginComponent },
]
resources/views/layouts/app.blade.php
<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<!-- CSRF Token -->
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>{{ config('app.name', 'Laravel') }}</title>
<!-- Scripts -->
#vite(['resources/sass/app.scss', 'resources/js/app.js'])
</head>
<body>
<div id="app">
<p>
<router-link to="/">Go to Home</router-link>
<router-link to="/login">Login</router-link>
</p>
<router-view></router-view>
</div>
<script src="https://unpkg.com/vue#3"></script>
<script src="https://unpkg.com/vue-router#4"></script>
</body>
</html>
For the past three hours or so, I have been trying to convert a VueJS 2 + vue-router + CDN project to VueJS 3. I haven't been able to make it work so far. The VueJS 2 version works just fine. The VueJS 3 version just won't work. I understand that sooner or later a project would need to be implemented with CLI, but I'd rather use CDN for the moment since I'm still experimenting.
The error message I receive is: Uncaught ReferenceError: createRouter is not defined. I have received many others in my trials and tribulations.
Here is the JS part (VueJS 2, works fine):
const Home = { template: `<h1>Contenuto Home</h1>` };
const About = { template: `<h1>Contenuto About</h1>` };
const Portfolio = { template: `<h1>Contenuto Portfolio</h1>` };
const Contatti = { template: `<h1>Contenuto Contatti</h1>` };
const routes = [
{ path: "/", component: Home },
{ path: "/about", component: About },
{ path: "/portfolio", component: Portfolio },
{ path: "/contatti", component: Contatti }
];
const router = new VueRouter({
routes // short for `routes: routes`
});
const vm = new Vue ({
router,
el: "#app",
data: {
mess: "Ciao Mondo"
}
}).$mount("#app");
The HTML looks like this (VueJS 2, works fine):
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue Router</title>
</head>
<body>
<div id="app">
<h1>{{ mess }}</h1>
<!-- i links -->
<router-link to="/">Home</router-link>
<router-link to="/about">About</router-link>
<router-link to="/portfolio">Portfolio</router-link>
<router-link to="/contatti">Contatti</router-link>
<!-- contenitore per il HTML -->
<router-view></router-view>
</div>
<!-- VueJS -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- vue-router -->
<script src="https://unpkg.com/vue-router#3.0.2/dist/vue-router.js"></script>
<!-- custom JS -->
<script src="main.js"></script>
</body>
</html>
Here is my attempt at converting this code to VueJS 3 (doesn't work - Uncaught ReferenceError: createRouter is not defined):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script src="https://unpkg.com/vue#next"></script>
<script src="https://unpkg.com/vue-router#4"></script>
<div id="app">
<h1>{{ mess }}</h1>
<!-- i links -->
<router-link to="/">Home</router-link>
<router-link to="/about">About</router-link>
<router-link to="/portfolio">Portfolio</router-link>
<router-link to="/contatti">Contatti</router-link>
<!-- contenitore per il HTML -->
<router-view></router-view>
</div>
<script>
let app = Vue.createApp({
data() {
return {
mess: "ciao mondo"
}
}
});
const Home = { template: `<h1>Contenuto Home</h1>` };
const About = { template: `<h1>Contenuto About</h1>` };
const Portfolio = { template: `<h1>Contenuto Portfolio</h1>` };
const Contatti = { template: `<h1>Contenuto Contatti</h1>` };
const routes = [
{ path: "/", component: Home },
{ path: "/about", component: About },
{ path: "/portfolio", component: Portfolio },
{ path: "/contatti", component: Contatti }
];
const router = new createRouter({
history: createWebHistory(process.env.BASE_URL),
routes // short for `routes: routes`
});
app.mount("#app");
</script>
</body>
</html>
const app = Vue.createApp({
data() {
return {
mess: "ciao mondo"
}
}
});
const Home = { template: `<h1>Contenuto Home</h1>` };
const About = { template: `<h1>Contenuto About</h1>` };
const Portfolio = { template: `<h1>Contenuto Portfolio</h1>` };
const Contatti = { template: `<h1>Contenuto Contatti</h1>` };
const routes = [
{ path: "/", component: Home },
{ path: "/about", component: About },
{ path: "/portfolio", component: Portfolio },
{ path: "/contatti", component: Contatti }
];
const router = VueRouter.createRouter({
history: VueRouter.createWebHashHistory(),
routes
})
app.use(router)
app.mount('#app')
I'm playing with vue for the first time and have knocked up a simple test file. I have a table that is populated by data from an api call, and have used the vue router to create links to each item but this link isn't displaying the content. the network shows it's making the request to the api, but for some reason the template is not showing (not even the hard-coded content). Why? Also, why does the route content not display on the first router view, but only the router-view in the tbl component?
<!doctype html>
<html lang="en">
<head>
<title>Vue.js test</title>
<meta charset="utf-8">
</head>
<body>
<div id="app">
<!-- this route displays correctly -->
<router-link to="/foo">Go to Foo</router-link>
<table-notification/>
<!-- content is not displayed here - why? -->
<router-view></router-view>
</div>
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/vue-router"></script>
<script src="axios.min.js"></script>
<script>
const foo = {template:'<div>asdfasdf</div>',};
var router = new VueRouter({
routes: [
{path: '/foo', component: foo},
{path: '/notifications/:id', component: notification_view}
]
});
var app = new Vue({
router: router
}).$mount('#app');
var notification_view = new Vue({
router: router,
template: `
<div>iop
id: {{ obj.id}}<br/>
title: {{ obj.data.title}}<br/>
message: {{obj.data.message}}<br/>
</div>
`,
data: {
obj: {},
id: 0,
},
watch: {
'$route' (to, from) {
// check for id in url
if (this.$route.params.id)
this.update_notification();
}
},
methods: {
update_notification: function(){
this.id = this.$route.params.id;
axios.get('http://api2/notifications/' + this.id)
.then(response => {this.obj = response.data.packet;});
}
}
});
var tbl = new Vue({
router:router,
el: 'table-notification',
template: `
<div>
<table>
<tr>
<th>Title</th>
<th>Created</th>
<th>Actions</th>
</tr>
<tr v-for="obj in objects">
<td><router-link :to="link(obj)">{{obj.data.title}}</router-link></td>
<td>{{obj.created}}</td>
<td>actions</td>
</tr>
</table>
<router-view/>
<!-- why must router-view be here, and why isn't notification_view showing any output?-->
</div>
`,
methods: {
link: function(obj) {return '/notifications/' + obj.id;}
},
data: {
objects: [],
},
created: function(){
axios.get('http://api2/notifications').
then(response =>
{
this.objects = response.data.packet;
});
}
});
</script>
</body>
</html>
I think you are misunderstanding the idea of Vue instances...
In you example you have:
a JSON foo that I think it is a component,
An App instance, which is mounted to the #app element
Another instance called notification_view with the same router, what I think is is another component
Another tbl instance, that I think it is another component
You actually need one instance and a bunch of components as in this example:
https://jsfiddle.net/dcr3jyzo/
I am trying to use a navigation guard w my router... when I use it the App component is displayed ( the navigation header) but the child HomePage component is not displayed... If I get rid of the navigation guard, no problem App and HomePage components are well displayed
what's wrong with my navigation guard usage in this case ?
router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import Home from '#/pages/HomePage'
import ShoppingLists from '#/pages/ShoppingListsPage'
Vue.use(Router)
const router = new Router({
// HTML5 mode history
mode: 'history',
routes: [
{
path: '/',
name: 'Home',
component: Home,
meta: { title: 'Home' }
},
{
path: '/shoppinglists',
name: 'ShoppingLists',
component: ShoppingLists,
meta: { title: 'Shopping Lists' }
}
]
})
router.beforeEach(function (to, from, next) {
if (to.meta && to.meta.title) {
document.title = to.meta.title
}
})
export default router
main.js
import Vue from 'vue'
import App from './App'
import router from './router'
/* eslint-disable no-new */
new Vue({
el: 'app',
router,
components: { App }
})
App.vue
<template>
<div id="app">
<ul class="navigation">
<li id="home"><router-link :to="{ name: 'Home' }" >Home</router-link></li>
<li id="shoppinglists"><router-link :to="{ name: 'ShoppingLists' }" >Shopping Lists</router-link></li>
</ul>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'app'
}
</script>
HomePage.vue
<template>
<div class="hello">
<img src="./../assets/logo.png">
<h1>{{ msg }}</h1>
</div>
</template>
<script>
export default {
name: 'Hello',
data () {
return {
msg: 'Welcome to our ShoppingList app'
}
}
}
</script>
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>shopping-list</title>
<link rel="shortcut icon" type="image/png" href="/static/favicon.ico"/>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<app></app>
<!-- built files will be auto injected -->
</body>
</html>
You have forgotten to add next().
router.beforeEach(function (to, from, next) {
if (to.meta && to.meta.title) {
document.title = to.meta.title
next()
}
next()
})
When I click foo, the console would print as expected, but the <router-view> render nothing.
The offical docs only display how to use it in a single html file and javascript code is embeded directly in it. I've read many examples but I can't make it in webpack.
Or is there any example about vue 2 router in webpack?
I create app.vue file as a layout:
<template>
<div id="app">
<h1>Hello App!</h1>
<p>
<router-link to="/foo">Go to Foo</router-link>
<router-link to="/bar">Go to Bar</router-link>
</p>
<router-view></router-view>
</div>
</template>
<script>
export default {
}
</script>
and webpack entry file:
import Vue from 'vue';
import VueRouter from 'vue-router'
import VueResource from 'vue-resource'
Vue.use(VueResource)
Vue.use(VueRouter)
import appView from 'app.vue'
const Foo = { template: '<div>foo</div>' , mounted(){console.log(this,'mount foo')}}
const Bar = { template: '<div>bar</div>' }
const routes = [
{ path: '/foo', component: Foo },
{ path: '/bar', component: Bar }
]
const router = new VueRouter({
routes
})
new Vue({
router,
render (h) {
return h(appView);
},
}).$mount('#app')
the html file:
<!DOCTYPE html>
<html lang='zh'>
<head>
</head>
<body>
<div id="app">
</div>
<script type="text/javascript" src="/static/bunlde.js"></script>
</body>
</html
In case others fall in this trap like me. In your webpack 2 config file, add:
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
},