精华内容
下载资源
问答
  • vue 自动注册路由

    2020-06-28 21:41:43
    // 插件-路由 ...//自动注册路由- page目录下的一级vue文件 require.context('./page', true, /\.vue$/).keys().forEach(fileName => { let componentName = fileName.replace(/^\.\//,'').replace.

    main.js中 

    // 插件-路由
    import VueRouter from 'vue-router'
    Vue.use(VueRouter)
    import {routes} from "./routes";
    
    //自动注册路由- page目录下的一级vue文件
    require.context('./page', true, /\.vue$/).keys().forEach(fileName => {
      let componentName = fileName.replace(/^\.\//,'').replace(/\.vue$/,'');
      let  temp = {
        path: '/'+componentName,
        component:resolve => require(["@/page/"+componentName], resolve)
      }
      routes.push(temp)
    });
    
    const router = new VueRouter({
      routes
    })

    page文件夹和main.js同级

    展开全文
  • 我们在用 Vue 开发过实际项目的时候都会用到 Vue-Router 这个官方插件来帮我们解决路由的问题。Vue-Router 的能力十分强大,它支持 hash、history、abstract 三种路由方式,提供了 <router-link> 和 <...

    一、Vue-Router

    1. 路由,它的作用就是根据不同的路径映射到不同的视图。我们在用 Vue 开发过实际项目的时候都会用到 Vue-Router 这个官方插件来帮我们解决路由的问题。Vue-Router 的能力十分强大,它支持 hashhistoryabstract 三种路由方式,提供了 <router-link><router-view> 两种组件,还提供了简单的路由配置和一系列好用的 API

    2. 大部分人已经掌握了路由的基本使用,但使用的过程中也难免会遇到一些坑,那么这里我们就来深挖 Vue-Router 的实现细节,一旦我们掌握了它的实现原理,那么就能在开发中对路由的使用更加游刃有余。同样我们也会通过一些具体的示例来配合讲解,先来看一个最基本使用例子:

    <div id="app">
      <h1>Hello App!</h1>
      <p>
        <!-- 使用 router-link 组件来导航. -->
        <!-- 通过传入 `to` 属性指定链接. -->
        <!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
        <router-link to="/foo">Go to Foo</router-link>
        <router-link to="/bar">Go to Bar</router-link>
      </p>
      <!-- 路由出口 -->
      <!-- 路由匹配到的组件将渲染在这里 -->
      <router-view></router-view>
    </div>
    
    import Vue from 'vue'
    import VueRouter from 'vue-router'
    import App from './App'
    
    Vue.use(VueRouter)
    
    // 1. 定义(路由)组件。
    // 可以从其他文件 import 进来
    const Foo = { template: '<div>foo</div>' }
    const Bar = { template: '<div>bar</div>' }
    
    // 2. 定义路由
    // 每个路由应该映射一个组件。 其中"component" 可以是
    // 通过 Vue.extend() 创建的组件构造器,
    // 或者,只是一个组件配置对象。
    // 我们晚点再讨论嵌套路由。
    const routes = [
      { path: '/foo', component: Foo },
      { path: '/bar', component: Bar }
    ]
    
    // 3. 创建 router 实例,然后传 `routes` 配置
    // 你还可以传别的配置参数, 不过先这么简单着吧。
    const router = new VueRouter({
      routes // (缩写)相当于 routes: routes
    })
    
    // 4. 创建和挂载根实例。
    // 记得要通过 router 配置参数注入路由,
    // 从而让整个应用都有路由功能
    const app = new Vue({
      el: '#app',
      render(h) {
        return h(App)
      },
      router
    })
    

    这是一个非常简单的例子,接下来我们先从 Vue.use(VueRouter) 说起。

    二、路由注册

    1. Vue 从它的设计上就是一个渐进式 JavaScript 框架,它本身的核心是解决视图渲染的问题,其它的能力就通过插件的方式来解决。Vue-Router 就是官方维护的路由插件,在介绍它的注册实现之前,我们先来分析一下 Vue 通用的插件注册原理。

    2. Vue.useVue 提供了 Vue.use 的全局 API 来注册这些插件,所以我们先来分析一下它的实现原理,定义在 vue/src/core/global-api/use.js 中:

    export function initUse (Vue: GlobalAPI) {
      Vue.use = function (plugin: Function | Object) {
        const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))
        if (installedPlugins.indexOf(plugin) > -1) {
          return this
        }
    
        const args = toArray(arguments, 1)
        args.unshift(this)
        if (typeof plugin.install === 'function') {
          plugin.install.apply(plugin, args)
        } else if (typeof plugin === 'function') {
          plugin.apply(null, args)
        }
        installedPlugins.push(plugin)
        return this
      }
    }
    
    1. Vue.use 接受一个 plugin 参数,并且维护了一个 _installedPlugins 数组,它存储所有注册过的 plugin;接着又会判断 plugin 有没有定义 install 方法,如果有的话则调用该方法,并且该方法执行的第一个参数是 Vue;最后把 plugin 存储到 installedPlugins 中。

    2. 由此可以看到 Vue 提供的插件注册机制很简单,每个插件都需要实现一个静态的 install 方法,当我们执行 Vue.use 注册插件的时候,就会执行这个 install 方法,并且在这个 install 方法的第一个参数我们可以拿到 Vue 对象,这样的好处就是作为插件的编写方不需要再额外去import Vue 了。

    3. 路由安装,Vue-Router 的入口文件是 src/index.js,其中定义了 VueRouter 类,也实现了 install 的静态方法:VueRouter.install = install,它的定义在 src/install.js 中,如下所示:

    export let _Vue
    export function install (Vue) {
      if (install.installed && _Vue === Vue) return
      install.installed = true
    
      _Vue = Vue
    
      const isDef = v => v !== undefined
    
      const registerInstance = (vm, callVal) => {
        let i = vm.$options._parentVnode
        if (isDef(i) && isDef(i = i.data) && isDef(i = i.registerRouteInstance)) {
          i(vm, callVal)
        }
      }
    
      Vue.mixin({
        beforeCreate () {
          if (isDef(this.$options.router)) {
            this._routerRoot = this
            this._router = this.$options.router
            this._router.init(this)
            Vue.util.defineReactive(this, '_route', this._router.history.current)
          } else {
            this._routerRoot = (this.$parent && this.$parent._routerRoot) || this
          }
          registerInstance(this, this)
        },
        destroyed () {
          registerInstance(this)
        }
      })
    
      Object.defineProperty(Vue.prototype, '$router', {
        get () { return this._routerRoot._router }
      })
    
      Object.defineProperty(Vue.prototype, '$route', {
        get () { return this._routerRoot._route }
      })
    
      Vue.component('RouterView', View)
      Vue.component('RouterLink', Link)
    
      const strats = Vue.config.optionMergeStrategies
      strats.beforeRouteEnter = strats.beforeRouteLeave = strats.beforeRouteUpdate = strats.created
    }
    
    1. 用户执行 Vue.use(VueRouter) 的时候,实际上就是在执行 install 函数,为了确保 install 逻辑只执行一次,用了 install.installed 变量做已安装的标志位。另外用一个全局的 _Vue 来接收参数 Vue,因为作为 Vue 的插件对 Vue 对象是有依赖的,但又不能去单独去 import Vue,因为那样会增加包体积,所以就通过这种方式拿到 Vue 对象。

    2. Vue-Router 安装最重要的一步就是利用 Vue.mixin 去把 beforeCreatedestroyed 钩子函数注入到每一个组件中。Vue.mixin 的定义,在 vue/src/core/global-api/mixin.js 中:

    export function initMixin (Vue: GlobalAPI) {
      Vue.mixin = function (mixin: Object) {
        this.options = mergeOptions(this.options, mixin)
        return this
      }
    }
    
    1. 它的实现实际上非常简单,就是把要混入的对象通过 mergeOptions 合并到 Vueoptions 中,由于每个组件的构造函数都会在 extend 阶段合并 Vue.options 到自身的 options 中,所以也就相当于每个组件都定义了 mixin 定义的选项。

    2. 回到 Vue-Routerinstall 方法,先看混入的 beforeCreate 钩子函数,对于根 Vue 实例而言,执行该钩子函数时定义了 this._routerRoot 表示它自身;this._router 表示 VueRouter 的实例 router,它是在 new Vue 的时候传入的;另外执行了 this._router.init() 方法初始化 router,这个逻辑之后介绍,然后用 defineReactive 方法把 this._route 变成响应式对象,这个作用我们之后会介绍。而对于子组件而言,由于组件是树状结构,在遍历组件树的过程中,它们在执行该钩子函数的时候 this._routerRoot 始终指向的离它最近的传入了 router 对象作为配置而实例化的父实例。

    3. 对于 beforeCreatedestroyed 钩子函数,它们都会执行 registerInstance 方法。接着给 Vue 原型上定义了 $router$route 两个属性的 get 方法,这就是为什么我们可以在组件实例上可以访问 this.$router 以及 this.$route。接着又通过 Vue.component 方法定义了全局的 <router-link><router-view> 两个组件,这也是为什么我们在写模板的时候可以使用这两个标签。最后定义了路由中的钩子函数的合并策略,和普通的钩子函数一样。

    4. 总结:我们分析了 Vue-Router 的安装过程,Vue 编写插件的时候通常要提供静态的 install 方法,我们通过 Vue.use(plugin) 时候,就是在执行 install 方法。Vue-Routerinstall 方法会给每一个组件注入 beforeCreatedestoryed 钩子函数,在 beforeCreate 做一些私有属性定义和路由初始化工作,接下来我们就来分析一下 VueRouter 对象的实现和它的初始化工作。

    三、VueRouter 对象

    1. VueRouter 的实现是一个类,我们先对它做一个简单地分析,它的定义在 src/index.js 中:
    export default class VueRouter {
      static install: () => void;
      static version: string;
    
      app: any;
      apps: Array<any>;
      ready: boolean;
      readyCbs: Array<Function>;
      options: RouterOptions;
      mode: string;
      history: HashHistory | HTML5History | AbstractHistory;
      matcher: Matcher;
      fallback: boolean;
      beforeHooks: Array<?NavigationGuard>;
      resolveHooks: Array<?NavigationGuard>;
      afterHooks: Array<?AfterNavigationHook>;
    
      constructor (options: RouterOptions = {}) {
        this.app = null
        this.apps = []
        this.options = options
        this.beforeHooks = []
        this.resolveHooks = []
        this.afterHooks = []
        this.matcher = createMatcher(options.routes || [], this)
    
        let mode = options.mode || 'hash'
        this.fallback = mode === 'history' && !supportsPushState && options.fallback !== false
        if (this.fallback) {
          mode = 'hash'
        }
        if (!inBrowser) {
          mode = 'abstract'
        }
        this.mode = mode
    
        switch (mode) {
          case 'history':
            this.history = new HTML5History(this, options.base)
            break
          case 'hash':
            this.history = new HashHistory(this, options.base, this.fallback)
            break
          case 'abstract':
            this.history = new AbstractHistory(this, options.base)
            break
          default:
            if (process.env.NODE_ENV !== 'production') {
              assert(false, `invalid mode: ${mode}`)
            }
        }
      }
    
      match (
        raw: RawLocation,
        current?: Route,
        redirectedFrom?: Location
      ): Route {
        return this.matcher.match(raw, current, redirectedFrom)
      }
    
      get currentRoute (): ?Route {
        return this.history && this.history.current
      }
    
      init (app: any) {
        process.env.NODE_ENV !== 'production' && assert(
          install.installed,
          `not installed. Make sure to call \`Vue.use(VueRouter)\` ` +
          `before creating root instance.`
        )
    
        this.apps.push(app)
    
        if (this.app) {
          return
        }
    
        this.app = app
    
        const history = this.history
    
        if (history instanceof HTML5History) {
          history.transitionTo(history.getCurrentLocation())
        } else if (history instanceof HashHistory) {
          const setupHashListener = () => {
            history.setupListeners()
          }
          history.transitionTo(
            history.getCurrentLocation(),
            setupHashListener,
            setupHashListener
          )
        }
    
        history.listen(route => {
          this.apps.forEach((app) => {
            app._route = route
          })
        })
      }
    
      beforeEach (fn: Function): Function {
        return registerHook(this.beforeHooks, fn)
      }
    
      beforeResolve (fn: Function): Function {
        return registerHook(this.resolveHooks, fn)
      }
    
      afterEach (fn: Function): Function {
        return registerHook(this.afterHooks, fn)
      }
    
      onReady (cb: Function, errorCb?: Function) {
        this.history.onReady(cb, errorCb)
      }
    
      onError (errorCb: Function) {
        this.history.onError(errorCb)
      }
    
      push (location: RawLocation, onComplete?: Function, onAbort?: Function) {
        this.history.push(location, onComplete, onAbort)
      }
    
      replace (location: RawLocation, onComplete?: Function, onAbort?: Function) {
        this.history.replace(location, onComplete, onAbort)
      }
    
      go (n: number) {
        this.history.go(n)
      }
    
      back () {
        this.go(-1)
      }
    
      forward () {
        this.go(1)
      }
    
      getMatchedComponents (to?: RawLocation | Route): Array<any> {
        const route: any = to
          ? to.matched
            ? to
            : this.resolve(to).route
          : this.currentRoute
        if (!route) {
          return []
        }
        return [].concat.apply([], route.matched.map(m => {
          return Object.keys(m.components).map(key => {
            return m.components[key]
          })
        }))
      }
    
      resolve (
        to: RawLocation,
        current?: Route,
        append?: boolean
      ): {
        location: Location,
        route: Route,
        href: string,
        normalizedTo: Location,
        resolved: Route
      } {
        const location = normalizeLocation(
          to,
          current || this.history.current,
          append,
          this
        )
        const route = this.match(location, current)
        const fullPath = route.redirectedFrom || route.fullPath
        const base = this.history.base
        const href = createHref(base, fullPath, this.mode)
        return {
          location,
          route,
          href,
          normalizedTo: location,
          resolved: route
        }
      }
    
      addRoutes (routes: Array<RouteConfig>) {
        this.matcher.addRoutes(routes)
        if (this.history.current !== START) {
          this.history.transitionTo(this.history.getCurrentLocation())
        }
      }
    }
    
    1. VueRouter 定义了一些属性和方法,我们先从它的构造函数看,当我们执行 new VueRouter 的时候做了哪些事情,如下所示:
    constructor (options: RouterOptions = {}) {
      this.app = null
      this.apps = []
      this.options = options
      this.beforeHooks = []
      this.resolveHooks = []
      this.afterHooks = []
      this.matcher = createMatcher(options.routes || [], this)
    
      let mode = options.mode || 'hash'
      this.fallback = mode === 'history' && !supportsPushState && options.fallback !== false
      if (this.fallback) {
        mode = 'hash'
      }
      if (!inBrowser) {
        mode = 'abstract'
      }
      this.mode = mode
    
      switch (mode) {
        case 'history':
          this.history = new HTML5History(this, options.base)
          break
        case 'hash':
          this.history = new HashHistory(this, options.base, this.fallback)
          break
        case 'abstract':
          this.history = new AbstractHistory(this, options.base)
          break
        default:
          if (process.env.NODE_ENV !== 'production') {
            assert(false, `invalid mode: ${mode}`)
          }
      }
    }
    
    1. 构造函数定义了一些属性,其中 this.app 表示根 Vue 实例,this.apps 保存持有 $options.router 属性的 Vue 实例,this.options 保存传入的路由配置,this.beforeHooks
      this.resolveHooksthis.afterHooks 表示一些钩子函数,我们之后会介绍,this.matcher 表示路由匹配器,我们之后会介绍,this.fallback 表示在浏览器不支持 history.pushState 的情况下,根据传入的 fallback 配置参数,决定是否回退到 hash 模式,this.mode 表示路由创建的模式,this.history 表示路由历史的具体的实现实例,它是根据 this.mode 的不同实现不同,它有 History 基类,然后不同的 history 实现都是继承 History

    2. 实例化 VueRouter 后会返回它的实例 router,我们在 new Vue 的时候会把 router 作为配置的属性传入,beforeCreate 混入的时候有这么一段代码:

    beforeCreate() {
      if (isDef(this.$options.router)) {
        // ...
        this._router = this.$options.router
        this._router.init(this)
        // ...
      }
    }  
    

    所以组件在执行 beforeCreate 钩子函数的时候,如果传入了 router 实例,都会执行 router.init 方法:

    init (app: any) {
      process.env.NODE_ENV !== 'production' && assert(
        install.installed,
        `not installed. Make sure to call \`Vue.use(VueRouter)\` ` +
        `before creating root instance.`
      )
    
      this.apps.push(app)
    
      if (this.app) {
        return
      }
    
      this.app = app
    
      const history = this.history
    
      if (history instanceof HTML5History) {
        history.transitionTo(history.getCurrentLocation())
      } else if (history instanceof HashHistory) {
        const setupHashListener = () => {
          history.setupListeners()
        }
        history.transitionTo(
          history.getCurrentLocation(),
          setupHashListener,
          setupHashListener
        )
      }
    
      history.listen(route => {
        this.apps.forEach((app) => {
          app._route = route
        })
      })
    }
    
    1. init 的逻辑很简单,它传入的参数是 Vue 实例,然后存储到 this.apps 中;只有根 Vue 实例会保存到 this.app 中,并且会拿到当前的 this.history,根据它的不同类型来执行不同逻辑,由于我们平时使用 hash 路由多一些,所以我们先看这部分逻辑,先定义了 setupHashListener 函数,接着执行了 history.transitionTo 方法,它是定义在 History 基类中,代码在 src/history/base.js
    transitionTo (location: RawLocation, onComplete?: Function, onAbort?: Function) {
      const route = this.router.match(location, this.current)
      // ...
    }
    
    1. 我们先不着急去看 transitionTo 的具体实现,先看第一行代码,它调用了 this.router.match 函数:
    match (
      raw: RawLocation,
      current?: Route,
      redirectedFrom?: Location
    ): Route {
      return this.matcher.match(raw, current, redirectedFrom)
    }
    

    实际上是调用了 this.matcher.match 方法去做匹配,所以接下来我们先来了解一下 matcher 的相关实现。

    1. 总结:我们大致对 VueRouter 类有了大致了解,知道了它的一些属性和方法,同时了解到在组件的初始化阶段,执行到 beforeCreate 钩子函数的时候会执行 router.init 方法,然后又会执行 history.transitionTo 方法做路由过渡,进而引出了 matcher 的概念,接下来我们先研究一下 matcher 的相关实现。
    展开全文
  • vue3.0路由注册

    2021-04-21 14:28:24
    vue3.0基础路由注册使用 注:使用vue-cli搭建起来的项目架构在引入vue-router时可能会因为默认的vue-router版本过低而导致报错 解决方法:cnpm install vue-router@next --save 第一步创建router.js文件 import { ...

    vue3.0基础路由注册使用

    注:使用vue-cli搭建起来的项目架构在引入vue-router时可能会因为默认的vue-router版本过低而导致报错

    解决方法:cnpm install vue-router@next --save

    第一步创建router.js文件

    import { createRouter, createWebHashHistory } from 'vue-router'
    
    const routes = [
      {
        path: '/test1',
        name: '/test1',
        component: () => import('@/views/test1.vue')
      }
    ]
    
    const router = createRouter({
      history: createWebHashHistory(),
      routes
    })
    
    export default router
    
    

    第二步在main.js中注册使用

    import { createApp, h } from 'vue'
    import App from './App.vue'
    import router from './router/index.js'
    
    const app = createApp(App)
    
    app.use(router)
    
    app.mount('#app')
    
    

    这样就在vue3.0中可以实现最基本的路由注册了

    展开全文
  • Vue路由

    千次阅读 多人点赞 2020-12-09 21:19:13
    Vue路由Vue路由基础嵌套路由路由重定向路由传参params形式传参query形式传参params方式与query方式的区别编程式路由利用JS实现路由跳转通过watch实现路由监听导航守卫 Vue路由基础 Vue属于单页应用(SPA),即整个...

    Vue路由基础

    Vue属于单页应用(SPA),即整个应用程序中只有一个html页面。
    在单页应用中(SPA),由于只是更改DOM来模拟多页面,所以页面浏览历史记录的功能就丧失了。此时,就需要前端路由来实现浏览历史记录的功能。

    样例代码:

    <!DOCTYPE html>
    <html>
    	<head>
    		<meta charset="utf-8" />
    		<title></title>
    		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    		<script src="https://cdn.jsdelivr.net/npm/vue-router/dist/vue-router.js"></script>
    
    
    	</head>
    	<body>
    		<div id="app">
    			<router-link to="/home">home</router-link>
    			<router-link to="/news">news</router-link>
    
    			<router-view></router-view>
    
    		</div>
    
    
    		<script>
    			const Home = {
    				template: '<div>首页</div>'
    			}
    			const News = {
    				template: '<div>新闻</div>'
    			}
    
    			var router = new VueRouter({
    				// mode: 'hash',
    				mode: 'history',
    				routes: [{
    					path: '/home',
    					component: Home
    				}, {
    					path: '/news',
    					component: News
    				}]
    			});
    
    
    
    			var vm = new Vue({
    				el: '#app',
    				data: {},
    				// 将路由添加到Vue中
    				router,
    			});
    		</script>
    
    	</body>
    </html>
    
    

    效果截图:

    点击home时:

    在这里插入图片描述

    点击new时:

    在这里插入图片描述

    嵌套路由

    实际应用界面,通常由多层嵌套的组件组合而成。 比如,我们 “新闻”组件中,还嵌套着 “国内”和 “国际”组件,那么URL对应就是/news/guonei和/news/guoji。
    样例代码:

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8" />
            <title></title>
            <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
            <script src="https://cdn.jsdelivr.net/npm/vue-router/dist/vue-router.js"></script>
    
    
        </head>
        <body>
            <div id="app">
                <p>
                    <!-- 使用 router-link 组件来导航. to属性指定导航地址-->
                    <router-link to="/home">home</router-link>
                    <router-link to="/news">news</router-link>
                </p>
                <!-- 路由出口(路由匹配到的组件将渲染在这里) -->
                <router-view></router-view>
            </div>
    
    
            <script>
                // 1. 定义(路由)组件。
                const Home = {
                    template: `<div>首页</div>`
                }
    
                const News = {
                    template: `<div>
                        <p>
                            <router-link to="/news/guonei">国内新闻</router-link>
                            <router-link to="/news/guoji">国际新闻</router-link>
                        </p>
                        <router-view></router-view>
                    </div>`
                }
    
                const GuoNeiNews = {
                    template: `<div>这里显示国内新闻</div>`
                }
                const GuoJiNews = {
                    template: `<div>这里显示国际新闻。。。。</div>`
                }
    
                // 2. 定义路由规则对象(每个路由应该映射一个组件)
                const routes = [{
                        path: '/home',
                        component: Home,
                    }, {
                        path: '/news',
                        component: News,
                        children: [{
                                path: '/news/guonei',
                                component: GuoNeiNews
                            }, {
                                path: '/news/guoji',
                                component: GuoJiNews
                            }
    
                        ]
                    },
    
    
                ]
    
                // 3. 创建 router 实例,然后传 `routes` 配置
                const router = new VueRouter({
                    //如果路由规则对象名也为routes,那么就可以简写为 routes
                    routes: routes
                })
    
                var vm = new Vue({
                    el: '#app',
                    data: {},
                    // 将路由添加到Vue中
                    router,
                });
            </script>
    
        </body>
    </html>
    

    效果动图:
    在这里插入图片描述

    路由重定向

    路由重定向表示将你原来在转发列表中发向一台路由的路径改成另外一条路径,也就相当于让你的数据走另外一条路到服务器。

    样例代码:

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8" />
            <title></title>
            <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
            <script src="https://cdn.jsdelivr.net/npm/vue-router/dist/vue-router.js"></script>
    
    
        </head>
        <body>
            <div id="app">
                <p>
                    <!-- 使用 router-link 组件来导航. to属性指定导航地址-->
                    <router-link to="/home">home</router-link>
                    <router-link to="/news">news</router-link>
                </p>
                <!-- 路由出口(路由匹配到的组件将渲染在这里) -->
                <router-view></router-view>
            </div>
    
    
            <script>
                // 1. 定义(路由)组件。
                const Home = {
                    template: `<div>首页</div>`
                }
    
                const News = {
                    template: `<div>
                        <p>
                            <router-link to="/news/guonei">国内新闻</router-link>
                            <router-link to="/news/guoji">国际新闻</router-link>
                        </p>
                        <router-view></router-view>
                    </div>`
                }
    
                const GuoNeiNews = {
                    template: `<div>这里显示国内新闻</div>`
                }
                const GuoJiNews = {
                    template: `<div>这里显示国际新闻。。。。</div>`
                }
    
    
                // 2. 定义路由规则对象(每个路由应该映射一个组件)
                const routes = [
                    /* {
                        path:'/',
                        redirect:'/home'
                    }, */
                    {
                        path: '/',
                        redirect: {
                            name: 'MyHome'
                        }
                    },
                    {
                        path: '/home',
                        name: 'MyHome',
                        component: Home,
                    }, {
                        path: '/news',
                        component: News,
                        children: [{
                                path: '/news/guonei',
                                component: GuoNeiNews
                            }, {
                                path: '/news/guoji',
                                component: GuoJiNews
                            }
    
    
                        ]
                    },
    
    
                ]
    
                // 3. 创建 router 实例,然后传 `routes` 配置
                const router = new VueRouter({
                    //如果路由规则对象名也为routes,那么就可以简写为 routes
                    routes: routes
                })
    
                var vm = new Vue({
                    el: '#app',
                    data: {},
                    // 将路由添加到Vue中
                    router,
                });
            </script>
    
        </body>
    </html>
    

    当我们访问#/时会自动帮我们跳转到#/home这也就是重定向。

    效果截图:
    在这里插入图片描述

    路由传参

    路由传参有多种方式,常用的有两种:params与query。

    params形式传参

    注意:

    • 使用v-bind绑定to属性。
    • to属性的值是一个json对象,此对象有两个属性:name属性和params属性。
    • name属性就是要路由的对象。所以,在路由规则列表中,每一个路由规则都应用有一个name值。
    • params属性就是要传递的参数。也是一个json对象。
    • 组件接收参数时,使用 this.$route.params.参数名 的形式。

    样例代码:

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8" />
            <title></title>
            <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
            <script src="https://cdn.jsdelivr.net/npm/vue-router/dist/vue-router.js"></script>
    
    
        </head>
        <body>
            <div id="app">
                <p>
                    <router-link :to="{name:'News',params:{msg:'国内'}}">点击这里会把国内传过去</router-link>
                </p>
    
                <router-view></router-view>
            </div>
    
    
            <script>
                const News = {
                    data(){
                        return {
                            msg:''
                        }
                    },
                    template: `<div> {{msg}}新闻</div>`,
                    created(){
                        this.msg = this.$route.params.msg;
                        console.log(this.$route.params)
                    }
                }
    
    
                // 2. 定义路由规则对象(每个路由应该映射一个组件)
                const routes = [
                    {
                        path: '/news',
                        name: 'News',
                        component: News,
                    }
                ]
    
                // 3. 创建 router 实例,然后传 `routes` 配置
                const router = new VueRouter({
                    //如果路由规则对象名也为routes,那么就可以简写为 routes
                    routes: routes
                })
    
                var vm = new Vue({
                    el: '#app',
                    data: {},
                    // 将路由添加到Vue中
                    router,
                });
            </script>
    
        </body>
    </html>
    

    效果动图:
    在这里插入图片描述

    query形式传参

    注意:

    • to属性的值仍然是一个json对象,但是两个属性变了,一个是path,一个是query。
    • path属性就是路由地址,对应路由规则中的path值。
    • query属性就是要传递的参数。也是一个json对象。
    • 组件接收参数时,使用 this.$route.query.参数名 的形式。

    样例代码:

    <!DOCTYPE html>
    <html>
    	<head>
    		<meta charset="utf-8">
    		<title></title>
    	</head>
    	<body>
    		<div id="app">
    		    <p>
    		        <router-link :to="{path:'/home',query:{msg:'hello world!'}}">home</router-link>
    		        <router-link :to="{path:'/news',query:{id:id,name:name}}">news</router-link>
    		    </p>
    		    <router-view></router-view>
    		</div>
    		
    		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    		<script src="https://cdn.jsdelivr.net/npm/vue-router/dist/vue-router.js"></script>
    		
    		<script type="text/javascript">
    		    const Home = {
    		        template: '<div>首页内容: {{this.$route.query.msg}} </div>'
    		    }
    		    const News = {
    		        template: `<div>新闻 </br>
    		                        参数id:{{this.$route.query.id}}</br>
    		                        参数name:{{this.$route.query.name}}
    		                    </div>`
    		    }
    		
    		    const routes = [{
    		        path: '/home',
    		        component: Home
    		    }, {
    		        path: '/news',
    		        component: News
    		    }]
    		
    		    const router = new VueRouter({
    		        routes
    		    })
    		
    		    var vm = new Vue({
    		        el: '#app',
    		        data: {
    		            id:666,
    		            name:'Keafmd'
    		        },
    		        router
    		    })
    		</script>
    	</body>
    </html>
    
    

    效果动图:
    在这里插入图片描述

    params方式与query方式的区别

    query方式传值:
    在这里插入图片描述
    params方式传值:
    在这里插入图片描述

    总结:params方式与query方式的区别:

    1. query方式:
    • 类似于get方式,参数会在路由中显示,可以用做刷新后仍然存在的参数。
    • 利用路由规则中的path跳转。
    1. params方式:
    • 类似于post方式,参数不会在路由中显示,页面刷新后参数将不存在。
    • 利用路由规则中的name跳转。

    编程式路由

    利用JS实现路由跳转

    router-link标签可以实现页面超链接形式的路由跳转。但是实际开发中,在很多情况下,需要通过某些逻辑判断来确定如何进行路由跳转。也就是说:需要在js代码中进行路由跳转。此时可以使用编程式路由。

    1. 使用this.$router.push方法可以实现路由跳转,方法的第一个参数可为string类型的路径,或者可以通过对象将相应参数传入。
    2. 通过this.$router.go(n)方法可以实现路由的前进后退,n表示跳转的个数,正数表示前进,负数表示后退。
    3. 如果只想实现前进后退可以使用this.$router.forward()(前进一页),以及this.$router.back()(后退一页)。

    样例代码:

    <!DOCTYPE html>
    <html>
    	<head>
    		<meta charset="utf-8">
    		<title></title>
    	</head>
    	<body>
    		<div id="app">
    		    <p>
    		        <button @click="toHome">首页</button>
    		        <button @click="toNews">新闻</button>
    		        <button @click="toLogin">登陆</button>
    		        <button @click="doForward1">前进</button>
    		        <button @click="doForward2">前进</button>
    		        <button @click="doBack1">后退</button>
    		        <button @click="doBack2">后退</button>
    		    </p>
    		    <router-view></router-view>
    		</div>
    		
    		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    		<script src="https://cdn.jsdelivr.net/npm/vue-router/dist/vue-router.js"></script>
    		
    		<script type="text/javascript">
    		    const Home = {
    		        template: '<div>首页</div>'
    		    }
    		    const News = {
    		        template: '<div>新闻</div>'
    		    }
    		    const Login = {
    		        template: '<div>登陆</div>'
    		    }
    		
    		    const routes = [{
    		        path: '/',
    		        component: Home
    		    }, {
    		        path: '/home',
    		        component: Home
    		    }, {
    		        path: '/news',
    		        component: News
    		    }, {
    		        path: '/login',
    		        component: Login
    		    }]
    		
    		    const router = new VueRouter({
    		        routes
    		    })
    		
    		    var vm = new Vue({
    		        el: '#app',
    		        data: {},
    		        router,
    		        methods:{
    		            toHome(){
    		                //无参数时,push方法中直接写路由地址
    		                this.$router.push('/home');
    		            },
    		            toNews(){
    		                //有参数时,push方法中写一个json对象
    		                this.$router.push({path:'/news',query:{name:'zhangsan'}});
    		            },
    		            toLogin(){
    		                this.$router.push('/login');
    		            },
    		            doForward1(){
    		                this.$router.forward();
    		            },
    		            doForward2(){
    		                this.$router.go(1);
    		            },
    		            doBack1(){
    		                this.$router.back();
    		            },
    		            doBack2(){
    		                this.$router.go(-1);
    		            }
    		        }
    		    })
    		</script>
    	</body>
    </html>
    
    

    效果动图:
    在这里插入图片描述

    通过watch实现路由监听

    通过watch属性设置监听$route变化,达到监听路由跳转的目的。
    在上面代码中添加watch监听:

    watch: {
        // 监听路由跳转。
        $route(newRoute, oldRoute) {
            console.log('watch', newRoute, oldRoute)
        }
    }
    

    完整代码:

    <!DOCTYPE html>
    <html>
    	<head>
    		<meta charset="utf-8">
    		<title></title>
    	</head>
    	<body>
    		<div id="app">
    		    <p>
    		        <button @click="toHome">首页</button>
    		        <button @click="toNews">新闻</button>
    		        <button @click="toLogin">登陆</button>
    		        <button @click="doForward1">前进</button>
    		        <button @click="doForward2">前进</button>
    		        <button @click="doBack1">后退</button>
    		        <button @click="doBack2">后退</button>
    		    </p>
    		    <router-view></router-view>
    		</div>
    		
    		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    		<script src="https://cdn.jsdelivr.net/npm/vue-router/dist/vue-router.js"></script>
    		
    		<script type="text/javascript">
    		    const Home = {
    		        template: '<div>首页</div>'
    		    }
    		    const News = {
    		        template: '<div>新闻</div>'
    		    }
    		    const Login = {
    		        template: '<div>登陆</div>'
    		    }
    		
    		    const routes = [{
    		        path: '/',
    		        component: Home
    		    }, {
    		        path: '/home',
    		        component: Home
    		    }, {
    		        path: '/news',
    		        component: News
    		    }, {
    		        path: '/login',
    		        component: Login
    		    }]
    		
    		    const router = new VueRouter({
    		        routes
    		    })
    			
    			
    		
    		    var vm = new Vue({
    		        el: '#app',
    		        data: {},
    		        router,
    		        methods:{
    		            toHome(){
    		                //无参数时,push方法中直接写路由地址
    		                this.$router.push('/home');
    		            },
    		            toNews(){
    		                //有参数时,push方法中写一个json对象
    		                this.$router.push({path:'/news',query:{name:'zhangsan'}});
    		            },
    		            toLogin(){
    		                this.$router.push('/login');
    		            },
    		            doForward1(){
    		                this.$router.forward();
    		            },
    		            doForward2(){
    		                this.$router.go(1);
    		            },
    		            doBack1(){
    		                this.$router.back();
    		            },
    		            doBack2(){
    		                this.$router.go(-1);
    		            }
    		        },
    				watch: {
    				    // 监听路由跳转。
    				    $route(newRoute, oldRoute) {
    				        console.log('watch', newRoute, oldRoute)
    				    }
    				}
    		    })
    		</script>
    	</body>
    </html>
    
    

    效果动图:
    在这里插入图片描述

    导航守卫

    路由跳转前做一些验证,比如登录验证,是网站中的普遍需求。 对此,vue-route 提供了实现导航守卫(navigation-guards)的功能。
    你可以使用 router.beforeEach 注册一个全局前置守卫:

    const router = new VueRouter({ ... })
    
    router.beforeEach((to, from, next) => {
        // ...
    })
    

    每个守卫方法接收三个参数:

    1. to:即将要进入的目标路由对象(去哪里),可以使用 to.path 获取即将要进入路由地址。
    2. from:当前导航正要离开的路由对象(从哪来),可以使用 from.path 获取正要离开的路由地址。
    3. next:一个函数,表示继续执行下一个路由。(如果没有next,将不会进入到下一个路由)。

    下面例子中实现了如下功能:

    1. 列举需要判断登录状态的 “路由集合”,当跳转至集合中的路由时,如果“未登录状态”,则跳转到登录页面。
    2. 当直接进入登录页面LoginPage时,如果“已登录状态”,则跳转到首页HomePage。

    样例代码:

    <!DOCTYPE html>
    <html>
    	<head>
    		<meta charset="utf-8">
    		<title></title>
    	</head>
    	<body>
    		<div id="box">
    		    <p>
    		        <router-link to="/home">home</router-link>
    		        <router-link to="/news">news</router-link>
    		        <router-link to="/music">music</router-link>
    		        <router-link to="/login">login</router-link>
    		    </p>
    		    <router-view></router-view>
    		</div>
    		
    		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    		<script src="https://cdn.jsdelivr.net/npm/vue-router/dist/vue-router.js"></script>
    		
    		<script type="text/javascript">
    		    const Home = {
    		        template: '<div>首页</div>'
    		    }
    		    const News = {
    		        template: '<div>新闻</div>'
    		    }
    		    const Music = {
    		        template: '<div>音乐</div>'
    		    }
    		    const Login = {
    		        template: '<div>登录</div>'
    		    }
    		
    		    const routes = [{
    		        path: '/',
    		        component: Home
    		    }, {
    		        path: '/home',
    		        component: Home
    		    }, {
    		        path: '/news',
    		        component: News
    		    }, {
    		        path: '/music',
    		        component: Music
    		    }, {
    		        path: '/login',
    		        component: Login
    		    }]
    		
    		    const router = new VueRouter({
    		        routes // (缩写)相当于 routes: routes
    		    })
    		
    		    var vm = new Vue({
    		        el: '#box',
    		        data: {},
    		        router
    		    })
    		
    		    // 添加全局路由守卫
    		    router.beforeEach((to, from, next) => {
    		        //创建守卫规则集合(这里表示'/news'与'/music'路径是需要权限验证的)
    		        const nextRoute = ['/news', '/music'];
    		        // 使用isLogin来模拟是否登录
    		        let isLogin = false;
    		        // let isLogin = true;
    		        // 判断to.path(要跳转的路径)是否是需要权限验证的
    		        if (nextRoute.indexOf(to.path) >= 0) {
    		            if (!isLogin) {
    		                router.push({
    		                    path: '/login'
    		                })
    		                location.reload(); //必须要有
    		            }
    		        }
    		        // 已登录状态;当路由到login时,跳转至home
    		        if (to.path === '/login') {
    		            if (isLogin) {
    		                router.push({
    		                    path: '/home'
    		                });
    		                location.reload();
    		            }
    		        }
    		        next(); //必须要有
    		    });
    		</script>
    	</body>
    </html>
    
    

    isLogin = false效果动图:
    在这里插入图片描述

    我们可以看出当我们点击 news 和 music 时,因为isLogin = false,所以会自动跳转到 login 界面。

    isLogin = true效果动图:
    在这里插入图片描述

    我们可以看出当我们点击 news 和 music 时,因为isLogin = true,所以会显示相应的界面。

    看完如果对你有帮助,感谢点赞支持!
    如果你是电脑端,看到右下角的 “一键三连” 了吗,没错点它[哈哈]

    在这里插入图片描述
    加油!

    共同努力!

    Keafmd

    展开全文
  • vue 路由

    2021-01-08 14:30:08
    vue 路由 什么是路由 后端路由: 对于普通的网站,所有的超链接都是URL地址,所有的URL地址都对应服务器上对应的资源; 前端路由: 对于单页面应用程序来说,主要通过URL中的hash(#号)来实现不同页面之间的切换,...
  • vue路由自动注册

    2020-12-08 17:44:59
    根据src/views文件夹的路径自动注册路由,文件结构如下: src |--view |----page1 // 页面一 |------components // 页面一的组件 |------index.vue // 页面一的入口组件 |----page2 // 页面2 |------components // ...
  • Vue 单页、路由

    2020-06-13 14:50:47
    传统的页面调转是浏览器请求新页面,单页是把原本的多个页面以组件的形式集成在一个页面中,页面跳转时由vue路由到目标页面,因为目标页面是当前页面的一部分,切换到指定部分即可,浏览器不用发起新请求。...
  • vue的跳转路由

    千次阅读 2020-12-15 11:59:54
    vue路由跳转 准备工作 /router/index.js import VueRouter from 'Vue-router' import Vue from 'vue' Vue.use(VueRouter) const routes = [] //route对象(填写路由) const router = new VueRouter({routes}) ...
  • 另外项目中的路由权限也是依据后台给前端的数据,因此对应的路由注册,也是如果当前用户有这个系统的权限,根据系统管理的配置也可以配置到某个菜单的权限,服务端将当前用户的菜单权限给到前端,前端再进行动态的...
  • Vue 路由

    千次阅读 多人点赞 2019-08-03 10:35:17
    Vue 路由 SPA 1. SPA是什么? 单页Web应用(single page application,SPA),就是只有一个Web页面的应用, 是加载单个HTML页面,并在用户与应用程序交互时动态更新该页面的Web应用程序 单页面应用程序: 只有 第一次...
  • Vue路由获取路由参数

    千次阅读 2018-09-05 23:55:00
    vue路由设置路由参数有2种方式: 1.通过query配置: &lt;router-link :to="{ name:'login',query:{id:1} }"&gt;登录&lt;/router-link&gt; 通过query配置的路径显示如下:   2.通过...
  • vue之手写路由

    2020-09-28 11:30:44
    vue之手写路由1准备一个没有路由的项目2检测3安装指令 npm i vue-router4添加router和views1在创建router文件并在其中添加index.js文件。2在src下创建视图文件夹views并添加home页和about页5配置app.vue和main.js根...
  • Vue中的路由 VueRouter 路由:根据请求的路径按照一定的路由规则 进行的请求转发 从而帮助我们实现请求的管理 作用:在vue中实现组件的动态切换 在线引入路由的cdn: ` ` <!DOCTYPE html> <html lang="en">...
  • 将一级路由注册 import Vue from 'vue' import VueRouter from 'vue-router' const routes = [ //这里是一级路由 { path:'/index', name:'index', //路由懒加载 component:()=>import('../component/index....
  • vue-router 路由

    2020-06-10 09:17:32
    vue-router 路由库 一、第一个 vue-router 路由 本节视频 【视频】Vue 渐进式 JavaScript 框架-VueRouter-第一个路由 概述 Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用...
  • vue中的路由

    2021-05-02 22:58:33
    vue中的路由能够实现其他组件的相互切换,实现路由的步骤分为安装,设置路由组件,创建路由表,注册路由表。 路由之间的切换可以使用<router-link to="/去哪个路由">首页</router-link>切换<router...
  • 在写vue的项目中,一般情况下我们每添加一个新页面都得添加一个新路由。为此我们在项目中会专门的一个文件夹来管理路由,如下图所示 那么有没有一种方案,能够实现我们在文件夹中新建了一个vue文件,就自动帮我们...
  • VUE的hash路由模式

    2020-12-09 10:02:19
    router-view标签就是确定路由位置的 一般放置在APP.vue文件里 路由位置 vue-router 路由模式分为三种 hash history abstract hash路由就是: 跳转的位置是#加上后面的字符 类似于 可以通过控制台location.hash查看...
  • Vue.js框架入门之组件创建、注册、使用 现在来续写第六期——Vue Router路由管理器 一、什么是路由 1、后端路由:对于普通的网站,所有的超链接都是URL地址,所有的URL地址都对应服务器上对应的资源; 2、前端路由:...
  • // 使用children属性实现路由嵌套,子路由path前不要加/,否则永远以根路径开始请求 children: [{ path: 'login', name: 'login', component: Login }, { path: 'regist/:username/:...
  • VUE路由实现注册登陆功能

    千次阅读 2020-03-19 13:46:52
    VUE实现注册登录功能 首先使用vue-cli创建一个vue项目,需要用到vue.js 路由,可以先命令行输入”npm install vue-router“进行安装。 (关于创建项目前那些工具内容介绍等这里不再赘述) 在这里我们每个组件都放在...
  • import {createRouter, createWebHistory} ...// 路由自动化注册 const requireComponent = require.context('@/modules', true, /\.vue$/) // 找到 modules 路径下的所有文件 const dynamic_route = requireComp.
  • vue中的路由及嵌套路由

    千次阅读 2018-03-19 16:24:43
    路由是vue的核心。使用npm install --save vue-router中来使用。在文件夹下将vue-router导入,并且声明要使用vue-router;import Vue from 'vue' ...那么我们在注册路由的使用需要定义一下内容。path为...
  • 建立一个 router.js 文件 ...然后注册 Vue.use(VueRouter); const router = new VueRouter({ mode : 'history', base: __dirname, routes: [ { path: historyUrl + '/', component: Home, name : '主页'
  • vue 中的路由路由嵌套以及钩子函数 什么是路由呢? 在网络原理中路由(routing)是指分组从源到目的地时,决定端到端路径的网络范围的进程。 而在web开发中,路由就是URL到函数的映射。 使用Vue开发项目,我们需要...
  • vue-router 路由守卫(路由生命周期)

    千次阅读 2019-08-10 17:31:03
    vue-router 路由生命周期(路由守卫) 1.全局&路由 使用 beforeEach((to,from,next)=>{…}) 发生路由 跳转时 立即执行 router.beforeEach((to,from,next)=>{ console.log('跳转到',to); ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 22,930
精华内容 9,172
关键字:

vue重新注册路由

vue 订阅