基础回顾
- 基本使用
- 创建路由组件
- vue.use()注册vue-router
- 注册router-view
- 创建链接 router-link
动态路由
$route.params.id
const routes = [
{
name: 'detail',
// 路径中携带参数
path: '/detail/:id',
component: detail
}
]
// detail 组件中接收路由参数
$route.params.id
props:true ——推荐
const routes = [
{
name: 'detail',
// 路径中携带参数
path: '/detail/:id',
component: detail,
props: true
}
]
// detail 组件中接收路由参数
const detail = {
props: ['id'],
template: '<div>Detail ID: {{ id }}</div>'
}
路由嵌套
index组件和details组件嵌套layout组件
{
path: '/',
component: layout,
children: [
{
name: 'index',
path: '/',
component: index
},
{
name: 'details',
path: '/details/:id',
component: details
}
]
}
编程式导航
// 跳转到指定路径
router.push('/login')
// 命名的路由
router.push({ name: 'user', params: { id: '5' }})
router.replace()
router.go()
Hash模式和History模式的区别
HTML5 HIstory模式的使用
- History需要服务器的支持
- 单应用中,服务端不存在http://www.testurl.com/login这样的地址会返回找不到该页面
- 在服务端应除了静态资源外都返回单页应用的 index.html
- Node.js环境
const history = require('connect-history-api-fall-back')
app.use(history())
nginx中配置
- 从官网下载nginx的压缩包
- 把压缩包解压到c盘根目录,c:\nginx-1.18.0文件夹
修改 conf\nginx.conf文件
location / {
root html;
index index.html index.htm;
#新添加内容
#尝试读取$uri(当前请求的路径),如果读取不到读取$uri/这个文件夹下的首页
#如果都获取不到返回根目录中的 index.html
try_files $uri $uri/ /index.html;
}
打开命令行,切换到目录c:\nginx-1.18.0
- nginx启动、重启和停止
# 启动
start nginx
# 重启
nginx -s reload
# 停止
nginx -s stop
Vue Router模拟实现
前置知识:插件、solt插槽、混入、render函数、运行时和完整版的Vue实现思路
创建VueRouter插件,静态方法install
- 判断插件是否已经被加载
- 当Vue加载的时候把传入的router对象挂载到Vue实例上(注意:只执行一次)
创建VueRouter类
创建VueRouter插件
export default class VueRouter {
static install (Vue) {
// 如果插件已经安装直接返回
if (VueRouter.install.installed && _Vue === Vue) return
VueRouter.install.installed = true
_Vue = Vue
Vue.mixin({
beforeCreate () {
// 判断 router 对象是否已经挂载了 Vue 实例上
if (this.$options.router) {
// 把 router 对象注入到 Vue 实例上
_Vue.prototype.$router = this.$options.router
}
}
})
}
}
实现VueRouter类-构造函数
constructor (options) {
this.options = options
// 记录路径和对应的组件
this.routeMap = {}
this.app = new _Vue({
data: {
// 当前的默认路径
current: '/'
}
})
}
实现VueRouter类-initRouteMap()
initRouteMap () {
// routes => [{ name: '', path: '', component: }]
// 遍历所有的路由信息,记录路径和组件的映射
this.options.routes.forEach(route => {
// 记录路径和组件的映射关系
this.routeMap[route.path] = route.component
})
}
实现VueRouter类-注册事件
initEvents () {
// 当路径变化之后,重新获取当前路径并记录到 current
window.addEventListener('hashchange', this.onHashChange.bind(this))
window.addEventListener('load', this.onHashChange.bind(this))
}
onHashChange () {
this.app.current = window.location.hash.substr(1) || '/'
}
实现VueRouter类-router-link和router-view组件
initComponents () {
_Vue.component('RouterLink', {
props: {
to: String
},
// 需要带编译器版本的 Vue.js
// template: "<a :href='\"#\" + to'><slot></slot></a>"
// 使用运行时版本的 Vue.js
render (h) {
return h('a', {
attrs: {
href: '#' + this.to
}
}, [this.$slots.default])
}
})
const self = this
_Vue.component('RouterView', {
render (h) {
// 根据当前路径找到对应的组件,注意 this 的问题
const component = self.routeMap[self.app.current]
return h(component)
}
})
}
注意:
- vue-cli创建的项目默认使用的是运行版本的Vue.js
- 如果想切换成带编译器版本的Vue.js,需要修改vue-cli配置
- 项目根目录创建vue.config.js文件,添加runtimeCompiler
modele.exports = {
runtimeCompile:true
}
- 项目根目录创建vue.config.js文件,添加runtimeCompiler
实现VueRouter类-init()
init () {
this.initRouteMap()
this.initEvents()
this.initComponents()
}
// 插件的 install() 方法中调用 init() 初始化
if (this.$options.router) {
_Vue.prototype.$router = this.$options.router
// 初始化插件的时候,调用 init
this.$options.router.init()
}