前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >路由原理 原

路由原理 原

作者头像
tianyawhl
发布2019-04-04 10:52:49
5650
发布2019-04-04 10:52:49
举报
文章被收录于专栏:前端之攻略前端之攻略

官方路由:对于大多数单页面应用,都推荐使用官方支持的vue-router库,可能在使用vue-router的时候,我们并不了解其原理,官网也提供的一个完整的例子如下:

代码语言:javascript
复制
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

代码语言:javascript
复制
<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

代码语言:javascript
复制
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

代码语言:javascript
复制
export default {
  '/':'Home',
  '/about':'About'
}

Vlink.vue

代码语言:javascript
复制
<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

代码语言:javascript
复制
<template>
	<main-layout>
		<p>Page not found111</p>
	</main-layout>
</template>
<script>
	import MainLayout from "../App.vue"

	export default {
		components:{
			MainLayout
		}
	}
</script>

About.vue

代码语言:javascript
复制
<template>
	<main-layout>
		<p>Welcome about</p>
	</main-layout>
</template>

<script>
	import MainLayout from "../App.vue"
	export default {
		components:{
			MainLayout
		}
	}
</script>

Home.vue

代码语言:javascript
复制
<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({});

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018/08/28 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档