官方路由:对于大多数单页面应用,都推荐使用官方支持的vue-router库,可能在使用vue-router的时候,我们并不了解其原理,官网也提供的一个完整的例子如下:
const NotFound = { template: '<p>Page not found</p>' }
const Home = { template: '<p>home page</p>' }
const About = { template: '<p>about page</p>' }
const routes = {
'/': Home,
'/about': About
}
new Vue({
el: '#app',
data: {
currentRoute: window.location.pathname
},
computed: {
ViewComponent () {
return routes[this.currentRoute] || NotFound
}
},
render (h) { return h(this.ViewComponent) }
})
但是我试了下此例子,在最后渲染的时候render (h) { return h(this.ViewComponent) }会报错,先修改如下:
目录结构如下,主要用到的文件已用红色标注
App.vue
<template>
<div class="container">
<ul>
<li>
<v-link href="/">Home</v-link>
</li>
<li>
<v-link href="/about">About</v-link>
</li>
</ul>
<slot></slot>
</div>
</template>
<script>
import VLink from "./components/Vlink.vue"
export default {
components:{
VLink
}
}
</script>
<style scoped>
.container{
max-width:600px;
margin:0 auto;
padding:15px 0;
background:#f9f7f5;
}
</style>
main.js
import Vue from 'vue'
import routes from './routes'
import About from './views/About'
import Home from './views/Home'
import NotFound from './views/404.vue'
const app = new Vue({
el: '#app',
data: {
currentRoute: window.location.pathname
},
render(h) {
if (routes[this.currentRoute]) {
if (this.currentRoute == "/") {
console.log(this.currentRoute)
return h(Home)
} else if (this.currentRoute == "/about") {
return h(About)
}
} else {
return h(NotFound)
}
}
})
window.addEventListener('popstate', () => {
app.currentRoute = window.location.pathname
})
routes.js
export default {
'/':'Home',
'/about':'About'
}
Vlink.vue
<template>
<a
v-bind:href="href"
v-bind:class="{ active: isActive }"
v-on:click="go"
>
<slot></slot>
</a>
</template>
<script>
import routes from '../routes'
export default {
props: {
href: {
type:String,
required: true
}
},
computed: {
isActive () {
return this.href === this.$root.currentRoute
}
},
methods: {
go (event) {
event.preventDefault()
this.$root.currentRoute = this.href
window.history.pushState(
null,
routes[this.href],
this.href
)
}
}
}
</script>
<style scoped>
.active {
color: cornflowerblue;
}
</style>
404.vue
<template>
<main-layout>
<p>Page not found111</p>
</main-layout>
</template>
<script>
import MainLayout from "../App.vue"
export default {
components:{
MainLayout
}
}
</script>
About.vue
<template>
<main-layout>
<p>Welcome about</p>
</main-layout>
</template>
<script>
import MainLayout from "../App.vue"
export default {
components:{
MainLayout
}
}
</script>
Home.vue
<template>
<main-layout>
<p>Welcome home</p>
</main-layout>
</template>
<script>
import MainLayout from "../App.vue"
export default {
components:{
MainLayout
}
}
</script>
原理:主要是根据currentRoute的值来确定根实例的模板中渲染哪个.vue页面,this.currentRoute的变化是由于执行了Vlink.vue里面的go方法,每个页面都引用了App.vue这个组件,并把内容传递给App.vue里面的slot,App.vue这个组件又引用了Vlink.vue组件,views文件夹中的3个.vue页面都是包含方法的完整页面。
(adsbygoogle = window.adsbygoogle || []).push({});