VueRouter——編程式導航-動態路由匹配(三)

1.編程式的導航

image.png

1.1 兩個屬性

image.png

1.2 使用場景

不少web應用都會在header區域的左邊放置一個LOGO,一般狀況點擊這個LOGO就會使頁面跳轉到首頁。接下來實現它:vue

<template>
  <div id="app">
    <div class="header">
      <div class="nav">
        <!-- <div class="left-title">我的博客</div> -->
        <router-link to="/" tag="div">我的博客</router-link>
        <div class="right-nav">
          <router-link to="/">首頁</router-link>
          <router-link to="/article">文章</router-link>
          <router-link to="/hot">近期熱門</router-link>
          <router-link to="/hy">行業相關</router-link>
          <router-link :to="{ name: 'new' }">最新發布</router-link>
          <router-link to="/about">關於</router-link>
        </div>
      </div>
    </div>
    <div class="container">
      <router-view />
    </div>
  </div>
</template>

來看效果:
image
那麼編程式怎麼作呢,先來看看$router是個什麼:web

<template>
  <div id="app">
    <div class="header">
      <div class="nav">
        <div class="left-title" @click="handleClick">我的博客</div>
        <div class="right-nav">
          <router-link to="/">首頁</router-link>
          <router-link to="/article">文章</router-link>
          <router-link to="/hot">近期熱門</router-link>
          <router-link to="/hy">行業相關</router-link>
          <router-link :to="{ name: 'new' }">最新發布</router-link>
          <router-link to="/about">關於</router-link>
        </div>
      </div>
    </div>
    <div class="container">
      <router-view />
    </div>
  </div>
</template>

<script>
export default {
  methods: {
    handleClick() {
      console.log(this.$router)
    }
  }
}
</script>

點擊事件觸發後,看看輸出:
image.png
能夠看到,$router是一個路由實例對象。而且它身上有不少方法如push,replace,go,本章只講push方法:編程

<template>
  <div id="app">
    <div class="header">
      <div class="nav">
        <div class="left-title" @click="handleClick">我的博客</div>
        <div class="right-nav">
          <router-link to="/">首頁</router-link>
          <router-link to="/article">文章</router-link>
          <router-link to="/hot">近期熱門</router-link>
          <router-link to="/hy">行業相關</router-link>
          <router-link :to="{ name: 'new' }">最新發布</router-link>
          <router-link to="/about">關於</router-link>
        </div>
      </div>
    </div>
    <div class="container">
      <router-view />
    </div>
  </div>
</template>

<script>
export default {
  methods: {
    handleClick() {
      this.$router.push('/')
    }
  }
}
</script>

很簡單,只須要將路徑寫在push裏便可。app

1.3 $route

image.png
$route其實包含的是當前路由下的所有信息,輸出一下看看:
image.png
看看query:
image.png
image.pngide

動態路由匹配

image.png
看文字老是有點懵,舉個例子:
image
能夠看到相似這種結構相同的組件的渲染,一般使用的是一個組件,只是其中的內容不一樣。這種場景下咱們使用動態路徑參數來實現。ui

{
  path: '/new',
  name: 'new',
  children: [
    {
      path: '231578',
      component: () => import("../components/news/news.vue"),
    },
    {
      path: '331578',
      component: () => import("../components/news/news.vue"),
    }
  ],
},

首先咱們能夠使用這種方式來實現,但觀察路由配置,若是一個課程配一個路由,那麼代碼會很是的冗餘,若是今天有十種課程,明天有一百種課程,還須要咱們不停的去配置。。。想一想就很麻煩,因此這種方式並不可取。this

那麼有沒有什麼更好的方式呢,首先須要肯定一個模式:spa

{
  path: '/new/:id',
  component: () => import("../components/new.vue"),
},

上面代碼中的/new/:id就是一個模式,意思是相似/new/123,/new/234這樣的路徑都將使用new.vue這個組件去渲染。看看效果:
image
能夠看到/new/123和/new/234都可以渲染出來,而/new卻不行,由於/new並不符合上述的模式,即/new/:idcode

下面重要的環節開始了,先來看看$route.params:
image.pngcomponent

<template>
  <div class="new">
    最新發布
  </div>
</template>

<script>
export default {
  mounted () {
    console.log(this.$route.params)
  }
}
</script>

看看結果:
image.png
若是改變模式:

{
  path: '/new/:userId',
  component: () => import("../components/new.vue"),
},

看看結果:
image.png
這就是所謂的動態路由。

使用動態路由作個小demo

router.js:

{
  path: '/new',
  component: () => import("../components/new.vue"),
},
{
  path: '/news/:id',
  component: () => import("../components/news/news.vue"),
},

new.vue:

<template>
  <div class="new">
    <ul>
      <li 
        @click="handleClick" 
        v-for="item in list" 
        :key="item.index"
      >
        {{ `${item.index + 1}. ${item.content}` }}
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  data () {
    return {
      list: [
        {index: 0, content: "Lorem ipsum, dolor sit amet consectetur adipisicing elit. Earum, quos."},
        {index: 1, content: "Lorem ipsum dolor sit, amet consectetur adipisicing."},
        {index: 2, content: "Lorem ipsum dolor sit amet."},
        {index: 3, content: "Lorem ipsum dolor sit amet consectetur, adipisicing elit."},
        {index: 4, content: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Quidem."},
      ]
    }
  },
  methods: {
    handleClick (e) {
      let id = e.target.innerHTML.split(".")[0].trim()
      this.$router.push(`/news/${id}`)
    },
  },
}
</script>

news.vue:

<template>
  <div class="news">
    {{ index }}
  </div>
</template>

<script>
export default {
  data () {
    return {
      index: undefined,
    }
  },
  mounted () {
    this.index = this.$route.params.id
  },
}
</script>

看看效果:
image
再來豐富一下:
news.vue:

<template>
  <div class="news">
    <div class="wrapper clearfix">
      <div class="article">
        <div class="title">{{ currentArt.title }}</div>
        <div class="content">{{ currentArt.content }}</div>
      </div>
      <div class="bottom-left" @click="handlePrev">{{ currentArt.prev }}</div>
      <div class="bottom-right" @click="handleNext">{{ currentArt.next }}</div>
    </div>
  </div>
</template>

<script>
export default {
  data () {
    return {
      index: undefined,
      articles: [
        {index: 1, title: "Lorem ipsum, dolor sit amet consectetur adipisicing elit. Earum, quos.", content: "文章1", prev: "", prevId: "", next: "Lorem ipsum dolor sit, amet consectetur adipisicing.", nextId: "2"},
        {index: 2, title: "Lorem ipsum dolor sit, amet consectetur adipisicing.", content: "文章2", prev: "Lorem ipsum, dolor sit amet consectetur adipisicing elit. Earum, quos.", prevId: "1", next: "Lorem ipsum dolor sit amet.", nextId: "3"},
        {index: 3, title: "Lorem ipsum dolor sit amet.", content: "文章3", prev: "Lorem ipsum dolor sit, amet consectetur adipisicing.", prevId: "2", next: "Lorem ipsum dolor sit amet consectetur, adipisicing elit.", nextId: "4"},
        {index: 4, title: "Lorem ipsum dolor sit amet consectetur, adipisicing elit.", content: "文章4", prev: "Lorem ipsum dolor sit amet.", prevId: "3", next: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Quidem.", nextId: "5"},
        {index: 5, title: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Quidem.", content: "文章5", prev: "Lorem ipsum dolor sit amet consectetur, adipisicing elit.", prevId: "4", next: "", nextId: ""},
      ],
      currentArt: {},
    }
  },
  methods: {
    getCurrentArt () {
      this.articles.forEach(ele => {
        if (ele.index == this.index) {
          this.currentArt = ele
        }
      })
    },
    handlePrev(e) {
      this.articles.forEach(ele => {
        if (ele.prev == e.target.innerHTML) {
          this.$router.push(`/news/${parseInt(ele.prevId)}`)
        }
      })
    },
    handleNext(e) {
      this.articles.forEach(ele => {
        if (ele.next == e.target.innerHTML) {
          this.$router.push(`/news/${parseInt(ele.nextId)}`)
        }
      })
    },
  },
  mounted () {
    this.index = this.$route.params.id
    this.getCurrentArt()
  },
  watch: {
    '$route' () {
      this.index = this.$route.params.id
      this.getCurrentArt()
    }
  }
}
</script>

看看效果:
image

總結

動態路由相對來講是一個很簡單的知識點,但在實際開發中又常常會用到。像一些場景,結構同樣,只須要改變數據,這個時候就能夠使用動態路由,在結構上咱們只須要編寫出一個骨架,而在切換時去請求對應的數據進來就能夠。這樣就能夠避免重複的開發相同的結構,而且內容是會增長或減小的。好比上面舉出的課程的例子,咱們不可能爲每個課程都編寫一個結構,因此動態路由很好的解決類諸如此類的問題。


Keep foolish, keep hungry.

相關文章
相關標籤/搜索