Vue代码学习笔记06

vue-router

vue-router是Vue框架的另一个强大工具。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。

哈希路由

单页应用路由,我们有一些url,想把他们映射到组件。即使组件和这些url有一一对应的关系,并能够实现跳转。

<div id="app">
  <component :is="url"></component>
  <a @click="routeTo('#foo')" href="#foo">foo</a>
  <a @click="routeTo('#bar')" href="#bar">bar</a>
</div>

<script>
	//一个基于哈希的路由解决方案
	/*
		浏览器有两种方式进行路由,可以使用哈希,也可以使用HTML5 History API。
		从某种意义上说,Html5 History APi更好,它支持弹出状态,你的URL看起来会更好,但是他需要某种服务器配置
		为了更方便的展示,这里使用哈希方式访问。
	*/
window.addEventListener('hashchange', () => {
  app.url = window.location.hash.slice(1)
})

const app = new Vue({
  el: '#app',
  data: {
    url: 'foo'
  },
  components: {
    foo: { template: `<div>foo</div>`},
    bar: { template: `<div>bar</div>`},
  },
  methods: {
    routeTo (route) {
      window.location.hash = route
    }
  }
})
</script>

路由表

完成了基础路由跳转的实现,那么我们能不能把基础路由和组件的对应关系维护起来,形成一张表,这样当我们需要跳转的时候查询路由表再跳转对应组件就好了。

<div id="app">
  <component :is="matchedComponent"></component>
  <a href="#foo">foo</a>
  <a href="#bar">bar</a>
</div>

<script>
// '#/foo' -> Foo
// '#/bar' -> Bar
// '#/404' -> NotFound

const Foo = { template: `<div>foo</div>` }
const Bar = { template: `<div>bar</div>` }
const NotFound = { template: `<div>not found!</div>` }

//路由表,维护组件和路径的对应关系
const routeTable = {
  foo: Foo,
  bar: Bar
}

window.addEventListener('hashchange', () => {
  app.url = window.location.hash.slice(1)
})

const app = new Vue({
  el: '#app',
  data: {
    url: 'foo'
  },
  //两种视图实现方式,render渲染函数和html模板
  render (h) {
	  return h('div', [
		  h(routeTable[this.url] || NotFound),
		  h('a',{ attrs:{ href:'#foo'}}, 'foo'),
		  ' | ',
		  h('a',{ attrs:{ href:'#bar'}}, 'bar')
	  ])
  }
  // computed: {
  //   matchedComponent () {
  //     return routeTable[this.url] || NotFound
  //   }
  // }
})
</script>

正则匹配动态路由

正则匹配

使用path-to-regexp工具库中的pathToRegexp函数处理url中的地址和参数

动态路由的匹配

<div id="app"></div>

<script>
// '#/foo/123' -> foo with id: 123
// '#/bar' -> Bar
// '#/404' -> NotFound

// path-to-regexp usage:
// const regex = pathToRegexp(pattern)
// const match = regex.exec(path)

//根据路由展现的组件
const Foo = {
  props: ['id'],
  template: `<div>foo with id: {{ id }}</div>`
}
const Bar = { template: `<div>bar</div>` }
const NotFound = { template: `<div>not found!</div>` }

//正则捕获的路由表
const routeTable = {
  '/foo/:id': Foo,
  '/bar': Bar
}

//编译完成后的数组,就是经过正则匹配后的数组
const compiledRoutes = []
//取出路由表中的所有匹配规则
Object.keys(routeTable).forEach(key => {
  const dynamicSegments = []
  //工具库函数pathToRegexp,用于处理url中的地址和参数
  const regex = pathToRegexp(key, dynamicSegments)
  const component = routeTable[key]
  compiledRoutes.push({
	//对应规则映射组件
    component,
	//匹配规则
    regex,
	//解析动态匹配部分
    dynamicSegments
  })
})

window.addEventListener('hashchange', () => {
  app.url = window.location.hash.slice(1)
})

const app = new Vue({
  el: '#app',
  data: {
    url: window.location.hash.slice(1)
  },
  render (h) {
    const path = '/' + this.url

    let componentToRender
    let props = {}
	//检查是否有匹配上的路由
    compiledRoutes.some(route => {
      const match = route.regex.exec(path)
      componentToRender = NotFound
	  //判断匹配是否成功
      if (match) {
        componentToRender = route.component
        route.dynamicSegments.forEach((segment, index) => {
          props[segment.name] = match[index + 1]
        })
        return true
      }
    })

    return h('div', [
      h(componentToRender, { props }),
      h('a', { attrs: { href: '#foo/123' }}, 'foo 123'),
      ' | ',
      h('a', { attrs: { href: '#foo/234' }}, 'foo 234'),
      ' | ',
      h('a', { attrs: { href: '#bar' }}, 'bar'),
      ' | ',
      h('a', { attrs: { href: '#garbage' }}, 'garbage')
    ])
  }
})
</script>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值