使用vue-router不期望的结构将路由添加到Vue应用程序

时间:2017-11-20 17:22:29

标签: javascript vuejs2 vue-router

按照一些教程,我创建了一个简单的菜单,如下所示:

HTML

Vue.component('main-menu', {
  template: `
            <div>
                <ul class="uk-tab uk-margin-bottom">
                    <li v-for="tab in tabs" :class="{ 'uk-active': tab.selected }">
                        <a @click="selectTab(tab.name)" href="#">{{ tab.name }}</a>
                    </li>
                </ul>
                <slot></slot>
            </div>
        `,
  data() {
    return {
      tabs: []
    }
  },
  created() {
    this.tabs = this.$children
  },
  methods: {
    selectTab(name) {
      for (tab of this.tabs) {
        tab.selected = (tab.name == name)
      }
    }
  },
})

Vue.component('tab', {
  props: {
    name,
    active: {
      default: false
    },
  },
  template: `
    <div v-show="selected">
        <ul v-show="subTabs.length > 1" class="uk-subnav uk-subnav-pill">
            <li v-for="subTab in subTabs" :class="{ 'uk-active': subTab.selected }">
                <a @click="selectSubTab(subTab.name)" href="#">{{ subTab.name }}</a>
            </li>
        </ul>
        <slot></slot>
    </div>
        `,
  data() {
    return {
      selected: false,
      subTabs: []
    }
  },
  created() {
    this.selected = this.active
    this.subTabs = this.$children
    this.selected = this.active
  },
  methods: {
    selectSubTab(name) {
      for (subTab of this.subTabs) {
        subTab.selected = (subTab.name == name)
      }
    }
  },
})

Vue.component('sub-tab', {
  props: {
    name,
    active: {
      default: false
    },
  },
  template: `
            <div v-show="selected">
                <slot></slot>
            </div>
        `,
  data() {
    return {
      selected: false
    }
  },
  created() {
    this.selected = this.active
  },
})

new Vue({
  el: '#root',
})
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>Static title for now</title>

  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/uikit/2.27.4/css/uikit.gradient.min.css">

  <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.5/vue.js"></script>
</head>

<body class="uk-margin uk-margin-left uk-margin-right">
  <div id="root">

    <main-menu>
      <tab name="Tab 1" :active="true">
        <sub-tab name="Sub 1A" :active="true">
          <div>1A</div>
        </sub-tab>
        <sub-tab name="Sub 1B">
          <div>1B</div>
        </sub-tab>
      </tab>
      <tab name="Tab 2">
        <sub-tab name="Sub 2A" :active="true">
          <div>2A</div>
        </sub-tab>
      </tab>
      <tab name="Tab 3">
        <sub-tab name="Sub 3A" :active="true">
          <div>3A</div>
        </sub-tab>
        <sub-tab name="Sub 3B">
          <div>3B</div>
        </sub-tab>
      </tab>
    </main-menu>

  </div>

  <script src="main.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/uikit/2.27.4/js/uikit.min.js"></script>
</body>

</html>

我想添加一些路由,所以每当我点击tab或sub-tab时,它都会更新地址,以及其他方式,每当我更改地址时,它都会更新页面状态并显示正确的div。

我已经阅读了vue-router的官方文档,并查了更多教程,但我无法弄清楚如何做到这一点。它的设计似乎是在不同链接上显示不同组件的方式。

我错过了什么?

1 个答案:

答案 0 :(得分:0)

我使用的设置使用vuexroutevuex-router-sync组合在一起。它似乎是相当多的代码,虽然我从笔记中抓取的示例不包括子/子类别,但添加它们并不太难。

// ::::: main.js :::::
import Vue from 'vue';
import store from './store'; // 1 - load vuex
import router from './router'; // 2 - load router
import App from './App.vue';
import { sync } from 'vuex-router-sync'; // 3 - load vuex-router-sync

sync(store, router) // 4 - call synch on vuex and route

new Vue({
  el: '#app',
  store, // 5 - add vuex to app
  router, // 5 - add router to app
  components: {
   App
  }
})
// ::::: store.js :::::
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const store = new Vuex.Store({
  state: {
    menu: [{
        name: 'Home',
        path: '/',
        component: require('./routes/home')
      },
      {
        name: 'Page1',
        path: '/page1',
        component: require('./routes/page1')
      },
      {
        name: 'Page2',
        path: '/page2',
        component: require('./routes/page2')
      },
    ]
  },
  getters: {
    menu: state => {
      return state.menu || []
    }
  }
})

export default store
// ::::: router.js :::::
import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

import HomePage from './routes/home.vue'
import Page1 from './routes/page1.vue'
import Page2 from './routes/page2.vue'

const routes = [{
    path: '/',
    component: HomePage
  },
  {
    path: '/page1',
    component: Page1
  },
  {
    path: '/page2',
    component: Page2
  }
]

const router = new VueRouter({
  // mode: 'history',
  mode: 'hash',
  linkActiveClass: 'is-active',
  scrollBehavior: () => ({
    y: 0
  }),
  routes
})

export default router
<!-- App.vue -->
<template>
<div id="App">
  <navigation></navigation> 
  <router-view class="animated"></router-view> 
</div>
</template>

<script>
  import Navigation from './components/Navigation'

  export default {
    components: {
      Navigation
    }
  }
</script>

导航

import store from '../store'
import {
  mapGetters
} from 'vuex'

export default {
  data: function() {
    return {
      error: {}
    }
  },
  computed: {
    ...mapGetters([
      'routePath'
    ]),
    menu() {
      return store.getters.menu
    },
  }
}
<template>
  <div>
    NAVIGATION
    <ul class="navbar_wrap">
      <li v-for="(item, index) in menu" :key="index" :class="routePath === item.path ? 'selected' : 'not-selected'">
        <router-link :to="item.path" :exact="true" v-if="item.path">
          {{item.name}}
        </router-link>
      </li>
    </ul>
  </div>
</template>

routePath getter在商店

中定义
routePath: state => {
   return state.route.path
}