zoukankan      html  css  js  c++  java
  • Vue Router高级

    路由组件传参

    通过props解耦

    const User = {
      props: ['id'],
      template: '<div>User {{ id }}</div>'
    }
    const router = new VueRouter({
      routes: [
        { path: '/user/:id', component: User, props: true },
    
        // 对于包含命名视图的路由,你必须分别为每个命名视图添加 `props` 选项:
        {
          path: '/user/:id',
          components: { default: User, sidebar: Sidebar },
          props: { default: true, sidebar: false }
        }
      ]
    })

    布尔模式

    如果props被设置为true,route.params参数将被设置为组件属性

    对象模式

    const router = new VueRouter({
      routes: [
        { path: '/promotion/from-newsletter', component: Promotion, props: { newsletterPopup: false } }
      ]
    })

    函数模式

    /search?q=vue 会将{query:vue}传递给组件SearchUser

    const router = new VueRouter({
      routes: [
        { path: '/search', component: SearchUser, props: (route) => ({ query: route.query.q }) }
      ]
    })

    History模式

    vue-router默认使用hash模式

    const router = new VueRouter({
      mode: 'history',
      routes: [...]
    })

    如果使用history模式,URL就像正常url,http://mysite.com/user/id

    这种模式需要后台配置

    警告:所有路径都会返回index.html,因此需要配置一个404页面

    const router = new VueRouter({
      mode: 'history',
      routes: [
        { path: '*', component: NotFoundComponent }
      ]
    })

    导航守卫

    全局前置守卫

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

    三个参数

    to:即将进入的Route

    from:当前导航离开的Route

    next:

    next()进行管道中的下一个钩子

    next(false)中断当前导航

    next('/')或next({path:'/'}) 中断当前导航,跳转到下一个导航

    一个登陆案例,根据用户是否登录判断路由跳转

    router.beforeEach((to, from, next) => {
      // 如果不是登录页
      if (to.name !== 'login') {
        if (HAS_LOGIN) next()
        else next({ name: 'login' })
      } else {
        if (HAS_LOGIN) next({ name: 'home' })
        else next()
      }
    })

     全局后置钩子

    router.afterEach((to, from) => {
      // ...
    })

    一个页面加载的案例。loading设置

    路由独享守卫

    const router = new VueRouter({
      routes: [
        {
          path: '/foo',
          component: Foo,
          beforeEnter: (to, from, next) => {
            // ...
          }
        }
      ]
    })

    组件内的守卫

    const Foo = {
      template: `...`,
      beforeRouteEnter (to, from, next) {
        // 在渲染该组件的对应路由被 confirm 前调用
        // 不!能!获取组件实例 `this`
        // 因为当守卫执行前,组件实例还没被创建
      },
      beforeRouteUpdate (to, from, next) {
        // 在当前路由改变,但是该组件被复用时调用
        // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
        // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
        // 可以访问组件实例 `this`
      },
      beforeRouteLeave (to, from, next) {
        // 导航离开该组件的对应路由时调用
        // 可以访问组件实例 `this`
      }
    }

    完整的导航流出

    https://router.vuejs.org/zh/guide/advanced/navigation-guards.html#组件内的守卫

    路由元信息

    定义路由可以配置meta字段

    const router = new VueRouter({
      routes: [
        {
          path: '/foo',
          component: Foo,
          children: [
            {
              path: 'bar',
              component: Bar,
              // a meta field
              meta: { requiresAuth: true }
            }
          ]
        }
      ]
    })

    我们在全局导航守卫中调用

    case

    router.beforeEach((to, from, next) => {
      console.log(to)
    })
    fullPath:
    "/foo/bar" hash: "" matched: (2) [{…}, {…}] meta: {requireAuth: true} name: "bar" params: {} path: "/foo/bar" query: {} __proto__: Object

    我们能从to中获得meta中数据

    router.beforeEach((to, from, next) => {
      const requireAuth = to.meta.requireAuth
    
      if (requireAuth) {
        if (HAS_LOGIN) next()
        else next({ 'name': 'login' })
      } else {
        next()
      }
    })

    过渡效果

    <transition>
      <router-view></router-view>
    </transition>

    单个路由过渡

    const Foo = {
      template: `
        <transition name="slide">
          <div class="foo">...</div>
        </transition>
      `
    }
    
    const Bar = {
      template: `
        <transition name="fade">
          <div class="bar">...</div>
        </transition>
      `
    }

    数据获取

    导航完成后获取数据

    $router.params.id获得文章数据

    <template>
      <div class="post">
        <div class="loading" v-if="loading">
          Loading...
        </div>
    
        <div v-if="error" class="error">
          {{ error }}
        </div>
    
        <div v-if="post" class="content">
          <h2>{{ post.title }}</h2>
          <p>{{ post.body }}</p>
        </div>
      </div>
    </template>
    export default {
      data () {
        return {
          loading: false,
          post: null,
          error: null
        }
      },
      created () {
        // 组件创建完后获取数据,
        // 此时 data 已经被 observed 了
        this.fetchData()
      },
      watch: {
        // 如果路由有变化,会再次执行该方法
        '$route': 'fetchData'
      },
      methods: {
        fetchData () {
          this.error = this.post = null
          this.loading = true
          // replace getPost with your data fetching util / API wrapper
          getPost(this.$route.params.id, (err, post) => {
            this.loading = false
            if (err) {
              this.error = err.toString()
            } else {
              this.post = post
            }
          })
        }
      }
    }

    在导航完成前获得数据beforeRouterEnter

    export default {
      data () {
        return {
          post: null,
          error: null
        }
      },
      beforeRouteEnter (to, from, next) {
        getPost(to.params.id, (err, post) => {
          next(vm => vm.setData(err, post))
        })
      },
      // 路由改变前,组件就已经渲染完了
      // 逻辑稍稍不同
      beforeRouteUpdate (to, from, next) {
        this.post = null
        getPost(to.params.id, (err, post) => {
          this.setData(err, post)
          next()
        })
      },
      methods: {
        setData (err, post) {
          if (err) {
            this.error = err.toString()
          } else {
            this.post = post
          }
        }
      }
    }

    滚动行为

    const router = new VueRouter({
      routes: [...],
      scrollBehavior (to, from, savedPosition) {
        // return 期望滚动到哪个的位置
      }
    })

    当切换到新的路由时候,想要页面滚动到顶部,或者原先的位置

    scrollBehavior (to, from, savedPosition) {
      return { x: 0, y: 0 }
    }

    路由懒加载

    const Foo = () => import('./Foo.vue')
    const router = new VueRouter({
      routes: [
        { path: '/foo', component: Foo }
      ]
    })
  • 相关阅读:
    (打包报错)AS打包报错:Generate Signed APK: Errors while building APK. You can find the errors in the 'Messages' view.
    NABCD
    石家庄地铁站项目最终总结报告
    团队冲刺2.7
    团队冲刺2.6
    团队冲刺2.5
    团队冲刺2.4
    团队冲刺2.3
    用户体验评价——win10自带微软拼音输入法
    团队冲刺2.2
  • 原文地址:https://www.cnblogs.com/sonwrain/p/10806166.html
Copyright © 2011-2022 走看看