天天看點

vue頂部加左側路由

vue頂部加左側路由

效果特别簡單,點選首頁,會顯示首頁左側的清單,預設加載第一項,加載頁加載到右側,點選左側或上側,右下角首頁面都會找出對應的頁進行加載。此例子是我用來練習vue的,效果顔色仿了csdn的配色,就這個小例子反複修改做了很久。

1.幾個基本概念

1-1路由

這個一定要懂,不懂這個亂寫,導緻走了很多彎路,此處先貼代碼,然後慢慢解釋。webstorm的vue項目,路由配置預設在src/router/index.js,内容如下:

import Vue from 'vue'
import Router from 'vue-router'
import MainPage from '@/components/MainPage'
import tabHomeIndex from '@/components/top/tab-home-index'
import tabHomeDetail from '@/components/top/tab-home-detail'
import tabHomeChart from '@/components/top/tab-home-chart'

import tabAboutIndex from '@/components/top/tab-about-index'
import tabAboutAuthor from '@/components/top/tab-about-author'
import tabAboutHonor from '@/components/top/tab-about-honor'

import tabOtherIndex from '@/components/top/tab-other-index'
import tabOtherStory from '@/components/top/tab-other-story'
import tabOtherBackground from '@/components/top/tab-other-background'

Vue.use(Router)


const router =  new Router({
  mode: 'history',
  routes: [
   {
      path:'/home',
      component: MainPage,
children:[{
       path:'detail',
       name:'home-detail',
       component:tabHomeDetail,
       meta:{currentTab: 'home',leftTab:'detail'},
     },{
       path:'chart',
       name:'home-chart',
       component:tabHomeChart,
       meta:{currentTab: 'home',leftTab:'chart'},
     }]
    },{
      path:'/about',
      component: MainPage,
      children:[{
        path:'/',
        name:'about-index',
        component:tabAboutIndex,
        meta:{currentTab: 'about',leftTab:'index'},
      },{
        path:'author',
        name:'about-author',
        component:tabAboutAuthor,
        meta:{currentTab: 'about',leftTab:'author'},
      },{
        path:'honor',
        name:'about-honor',
        component:tabAboutHonor,
        meta:{currentTab: 'about',leftTab:'honor'},
      }]
    },{
      path:'/other',
      component: MainPage,
      children:[{
        path:'/',
        name:'other-index',
        component:tabOtherIndex,
        meta:{currentTab: 'other',leftTab:'index'},
      },{
        path:'story',
        name:'other-story',
        component:tabOtherStory,
        meta:{currentTab: 'other',leftTab:'story'},
      },{
        path:'background',
        name:'other-background',
        component:tabOtherBackground,
        meta:{currentTab: 'other',leftTab:'background'},
      }]
    }, {
      path: '/',
      component: MainPage,
      meta:{currentTab: 'home',leftTab:'index'},
      children:[{
        path:'/',
        name:'home-index',
        component:tabHomeIndex,
        meta:{currentTab: 'home',leftTab:'index'},
      }]
    }
  ]
});
export default router      
  • 1:​

    ​mode: 'history'​

    此處為必須,如果不配置,路徑上會有#符号

  • 2:路由
  • path以斜杠開頭,不以斜杠結尾

    例如:/a

  • 外層的component是要跳轉的以為外層标簽的元件
<template><div></div></template>      
  • 内層的component是在外層component使用為标簽的替換
<template>
    <div>
        <!--此處router-view替換為内層component-->
        <router-view></router-view>
    </div>
</template>      
  • 3:vue單頁跳轉
<router-link :to="{name:home-index}">

</router-link>      
  • 此處設定的name和路由配置的name相同
  • 并不等于普通的window.location.href的a标簽跳轉

    如果這麼天真的方式寫完代碼,那麼你會郁悶的發現,上方标簽點了,上方位址變了,可是很不幸,按鈕資料和左側菜單并沒有重新整理

    吐槽:此處無敵坑,但是從邏輯的角度可以了解,加載的快必然是要付出代價

  • 如何重新整理?
需要重新整理的元件下方增加對$route的watch,也就是路由變化時,調用method對應方法,重新整理這些變量,進而重新整理頁面
watch:{
      "$route": "refreshTopTab"
},methods:{
refreshTopTab(){
    this.currentTab = nowTab;      

貼一下首頁面,側邊欄,和一個代表的内頁(内頁現在做的很簡單,都是寫對應頁的文字,除了裡面的字變化,其他都一樣)

首頁面:MainPage.vue

<template>
  <div style="width: 100%;height: 100%;background: #f4f4f4">
    <div style="width: 100%;background: white">
      <table style="height:50px;border-spacing: 0;">
        <tr>
          <td  v-for="tab in tabs" style="padding: 0">
            <router-link :to='{name:getLinkUrl(tab.index)}'  style="padding:10px;width: 100%;height: 50px;margin: 0;" v-bind:class="['tab-button',{active:tab.index===currentTab}]"{{tab.name}}</router-link>

          </td>
        </tr>
      </table>
    </div>

    <component v-bind:is="getLeft" :topPos="getTop" class="leftTabs"></component>
    <router-view class="tab"></router-view>
  </div>
</template>

<script>'./top/tab-home-index.vue'
  import tabHomeDetail from './top/tab-home-detail.vue'
  import tabHomeChart from './top/tab-home-chart.vue'

  import tabAboutIndex from './top/tab-about-index.vue'
  import tabAboutAuthor from './top/tab-about-author.vue'
  import tabAboutHonor from './top/tab-about-honor.vue'

  import tabOtherIndex from './top/tab-other-index.vue'
  import tabOtherStory from './top/tab-other-story.vue'
  import tabOtherBackground from './top/tab-other-background.vue'

  import leftPage from './top/leftPage.vue'
  export default {
    name: 'MainPage',
    data() {
      return {
        currentTab: nowTab,
        leftTab:lTab,
        tabs: [{
          'index':'home',
          'name':'首頁',
        },{
          'index':'about',
          'name':'關于',
        },{
          'index':'other',
          'name':'其他',
        }
         ],
      }

    },
    components: {
      leftPage
    }, computed: {
      getLeft:function(){
        return "leftPage";
      },
      getTop(){
        return this.currentTab;
      }

    },methods:{

      getLinkUrl(tab){
        return tab+'-index'
      },refreshTopTab(){
        this.currentTab = nowTab;
      }
    },watch:{
      "$route": "refreshTopTab"</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>.tab-button {
    padding:6px 10px;
    border-top-left-radius:3px;
    border-top-right-radius:3px;
    cursor: pointer;
    margin-bottom:1px;
    margin-right:1px;
    color:black;
    text-decoration: none;
  }

  .tab-button:hover {
    color:red;
  }

  .tab-button.active {
    color:red;
  }

  .leftTabs{
    position: absolute;
    top:55px;
    bottom:5px;
    left:5px;
    width:100px }

  .tab {
    position: absolute;
    top:55px;
    left:110px;
    right:5px;
    bottom:5px }
</style>      

側邊欄leftPage.vue:

<template>
  <div>
    <div s style="width: 100%;height:100%;">
      <div style="width: 100%;height:100%;background: white">
        <table id="tableLeft" style="border-spacing: 0;border:0;width: 100%"
          <tr style="width: 100%" v-for="item in getLeftList(topPos)" :class="['tabItem',{active:leftSelectedTab===item.tabName}]">
            <td style="padding:0;margin:0;width:100%;height:100%"><router-link style="margin: 0;padding: 0;"  :to="{name:getLink(topPos,item.tabName)}" :class="['tabChildLink',{active:leftSelectedTab===item.tabName}]">{{item.name}}</router-link></td>
          </tr>
        </table>
      </div>

    </div>
  </div>


</template>

<script>default {

    name: "leftPage",
    props:{
      'topPos':{
        type:String,
        require:true
      }
    },
    data(){
      return {
        leftSelectedTab:lTab,
        lefts:{
          home:[
          {
            name:'首頁-描述',
            tabName:'index'
          },{
            name:'首頁-詳情',
            tabName:'detail'
          },{
            name:'首頁-圖解',
            tabName:'chart'
          }
        ],
         about: [
          {
            name:'關于-網站',
            tabName:'index'
          },{
            name:'關于-作者',
            tabName:'author'
          },{
            name:'關于-榮譽',
            tabName:'honor'
          }
        ],
         other: [
          {
            name:'其他-合作',
            tabName:'index'
          },{
            name:'其他-故事',
            tabName:'story'
          },{
            name:'其他-背景',
            tabName:'background'
          }
        ]
      },
      };
    },methods:{
      getLeftList:function(pTab){
        return this.lefts[pTab];
      },getLink(parentTab,itemTab){
        return parentTab+"-"+itemTab;
      },refreshLeftTab(){
        this.leftSelectedTab = lTab;
      }
    },computed:{


    },watch:{
      "$route": "refreshLeftTab"</script>

<style scoped>.tabItem{
    background: white;
    color: black;
  }
  .tabItem:hover{
    color: white;
    background:#f44444;
  }
  .tabItem.active{
    color: white;
    background:#f44444;
  }

  .tabChildLink{
    color: black;
    text-decoration: none;
  }
  .tabChildLink:hover{
    color: white;
    text-decoration: none;
  }
  .tabChildLink.active{
    color: white;
    text-decoration: none;
  }</style>      

内頁:

<template>
  <div  style="background: white">about-author</div>
</template>

<script>default {
        name: "tab-about-author"</script>

<style scoped>

</style>      

補充小知識:

vue.js首次在chrome通路​​http://localhost:10101/#/​​這種網址後,改mode為histroy,之後此網址谷歌預設必須帶#否則跳入搜尋問題,貼個圖: