这里写图片描述

效果特别简单,点击首页,会显示首页左侧的列表,默认加载第一项,加载页加载到右侧,点击左侧或上侧,右下角主页面都会找出对应的页进行加载。此例子是我用来练习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>
  import tabHomeIndex from './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>
  export 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>
    export default {
        name: "tab-about-author"
    }
</script>

<style scoped>

</style>

补充小知识:

vue.js首次在chrome访问http://localhost:10101/#/这种网址后,改mode为histroy,之后此网址谷歌默认必须带#否则跳入搜索问题,贴个图:
这里写图片描述
这样就必须用键盘下移动到下方带#号网址,然后shift+del把它删掉。然后就可用不带#的地址访问了。

Logo

前往低代码交流专区

更多推荐