vue(一)

VUE-Router

VUE-Router 主要和Vue搭配创建单页应用使用的,用vuer-router要将components映射到routes,并告知在哪里渲染组件

动态路由传参

const routes = [
    {
    name: 'detail',
    // 路径中携带参数
    path: '/detail/:id',
    component: detail
    }
] 

// detail 组件中接收路由参数
$route.params.id
const routes = [
    {
    name: 'detail',
    // 路径中携带参数
    path: '/detail/:id',
    component: detail,
    props: true  //设置为true,可在组件中props接收
    }
] 

// detail 组件中接收路由参数
const detail = {
    props: ['id'],
    template: '<div>Detail ID: {{ id }}</div>'
}  

vue-router 核心

// 注册插件
// Vue.use() 内部调用传入对象的 install 方法

Vue.use(VueRouter)
// 创建路由对象
const router = new VueRouter({
routes: [
{ name: 'home', path: '/', component: homeComponent }
]
})
// 创建 Vue 实例,注册 router 对象
new Vue({
router,
render: h => h(App)
}).$mount('#app')

hash模式实现

Vue Router 默认使用的是 hash 模式,使用 hash 来模拟一个完整的 URL,通过
onhashchange 监听路径的变化

  • 1-创建 LVueRouter 插件

    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
            }
          },
        })
      }
    }
    
    
  • 2-实现 VueRouter 类 - 构造函数

    constructor(options) {
        this.options = options
        this.routerMap = {} //记录组件和路由映射数据
        this.data = _Vue.observable({
          current: '/', //响应式对象,当前路径
        })
      }
    
  • 3- 实现 LVueRouter 类 - initRouteMap()

     initRouteMap() {
        // routes => [{ name: '', path: '', component: }]
        // 遍历所有的路由信息,记录路径和组件的映射
        this.options.routes.forEach((route) => {
          // 记录路径和组件的映射关系
          this.routeMap[route.path] = route.component
        })
      }
    
  • 4- 实现 LVueRouter 类 - 注册事件

    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) || '/'
    }
    
  • 5- 实现 LVueRouter 类 - 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

        module.exports = {
          runtimeCompiler: true
        }
        
  • 6- 实现 LVueRouter 类 - 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()
    }
    

history模式实现

https://developer.mozilla.org/zh-CN/docs/Web/API/History_API

实现思路

  • 创建 LVueRouter 插件,静态方法 install
    • 判断插件是否已经被加载
    • 当 Vue 加载的时候把传入的 router 对象挂载到 Vue 实例上(注意:只执行一次)
  • 创建 LVueRouter 类
    • 初始化,options、routeMap、app(简化操作,创建 Vue 实例作为响应式数据记录当前路
      径)
    • initRouteMap() 遍历所有路由信息,把组件和路由的映射记录到 routeMap 对象中
    • 注册 popstate 事件,当路由地址发生变化,重新记录当前的路径
    • 创建 router-link 和 router-view 组件
    • 当路径改变的时候通过当前路径在 routerMap 对象中找到对应的组件,渲染 router-view

代码实现

  • 1-; 2-; 3-;同hash

  • 4-实现 LVueRouter 类 - 注册事件

    initEvent(){
            window.addEventListener("popstate",()=>{
                this.data.current = window.location.pathname
            })
    }
    
上一篇:2021-05-13


下一篇:React-Native不同屏幕之间基本路由跳转