vue中的嵌套路由、动态路由以及命名路由

1.vue路由:

  vue SSR(Vue Server Side Rander)服务端渲染
        Vue CLI 默认客户端(浏览器)渲染,JS 发送用户浏览器中,占用用户资源渲染生成 HTML

  element UI

2.SPA(Single Page Application)

 定义:     SPA 中存在多个组件,多个组件构成一个试图(view)不同的数据与视图使用不同的 URL 表示,
        1.根据不同 URL 显示不同的视图。
        2.一个 view  由多个组件构成, 每个视图有自己的 URL。
        3.单页面 VS 多个页面。
        4.Vue 主要针对于单页面。
        5.路由 ---》 URL 的改变。
        6.一个页面,出现多个 URL,每个 URL 一个视图(特定的数据资源 + 几个组件),
            显示的资源改变了 URL 发生相应的改变,页面只有一个。


  



3. views 与 components 文件夹的区别

SPA -- Page(HTML) --> URL(view) --> components


4.工程结构如图


index.html 

<!doctype html>
<html lang="en">
  <head>
    <title>SPA</title>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
  </head>
  <body>
    <div id="app"></div>
    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
  </body>
</html>

Nav.vue

// Nav.vue
<template>
    <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
        <a class="navbar-brand" href="#">路由</a>
        <button class="navbar-toggler d-lg-none" type="button" data-toggle="collapse" data-target="#collapsibleNavId" aria-controls="collapsibleNavId"
            aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="collapsibleNavId">
            <ul class="navbar-nav mr-auto mt-2 mt-lg-0">

                <!--router-link渲染成超链接  -->
                <li class="nav-item active">
                    <router-link class="nav-link" to="/">首页</router-link>
                    <!-- <a  href="#">首页 <span class="sr-only">(current)</span></a> -->
                </li>
                <li class="nav-item">
                    <!-- <a class="nav-link" href="#">Link</a> -->
                    <router-link class="nav-link" to="/class">班级</router-link>
                </li>
                <li class="nav-item">
                    <!-- <a  href="#">Link</a> -->
                    <router-link class="nav-link" to="/member">学员</router-link>
                </li>
               
            </ul>
           
        </div>
    </nav>
</template>


<script>
export default {
    name:'Nav'
}
</script>

router的index.js

import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
import HomeShow from '../views/HomeShow.vue'
import ClassHome from '../views/class/ClassHome.vue'
import ClassShow from '../views/class/ClassShow.vue'
import MemberHome  from '../views/member/MemberHome.vue'
import Detail  from '../views/member/Detail.vue'

Vue.use(VueRouter)

// 定义路由规则
const routes = [
  {

    // 映射的URL路径---必须
    path: '/',
    // 路由的名称---可选
    name: 'Home',
    // 路由视图要挂载的组件(views文件夹的组件)
    // component: Home
    components:{
      default:Home,
      show:HomeShow
    }
  },


  {
    path:'/class',
    components:{
      default:ClassHome,
      show:ClassShow
    }
  },


  {
    path:'/member',
    // 学员的Url中,show这个路由视图无内容
    // component:MemberHome
    components:{
      default:MemberHome,
      // 学员页面的展示区显示首页的展示内容
      show:HomeShow
    },

    
  },


  {
    // 动态路由
    path:'/member/:id',
    name:'memberDetail',
    component:Detail,
    // components:{
    //   // default:MemberHome,
    //   // show:Home,
    //   detail:Detail
    // },
    // 路由参数通过组件的属性方式传递进去
    props:true
  }
  // {
  //   path: '/about',
  //   name: 'About',
  //   // route level code-splitting
  //   // this generates a separate chunk (about.[hash].js) for this route
  //   // which is lazy-loaded when the route is visited.

  //   // 箭头函数导入对应的组件(lazy-loaded ,懒加载/延迟加载)
  //   component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
  // }
]

// 创建路由
const router = new VueRouter({
  // 指定路由规则
  routes,
  // 移除路径的#
  mode:'history'

  // 路径的#,默认的
  // mode:'hash'


})


// 导出路由
export default router

store下的index.js

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    members:[
      {
        id:1000,
        name:'king'
      },
      {
        id:2000,
        name:'bob'
      },
      {
        id:3000,
        name:'jack'
      },
    ]
  },
  mutations: {
  },
  actions: {
  },
  modules: {
  }
})

ClassHome.vue

<template>
  <div class="container-fluid">
      <div class="row">
          <div class="col-lg-4">
              <ul class="list-group">
                  <li class="list-group-item active">班级菜单</li>
                  <li class="list-group-item">Item</li>
                  <li class="list-group-item disabled">Disabled item</li>
              </ul>
          </div>
      </div>
  </div>
</template>

ClassShow.vue

<template>
   <div class="jumbotron">
       <h1 class="display-3">Class Show</h1>
       <p class="lead">Jumbo helper text</p>
      
   </div>
</template>

Detail.vue

<template>
  <div class="card text-white bg-danger">
  
    <div class="card-body">
      <h4 class="card-title">学员信息:{{id}}</h4>
      <p class="card-text">Text</p>
    </div>
  </div>
</template>


<script>
export default {
    name:'Detail',
    props:['id']
}
</script>

MemberHome.vue

<template>

<div>
  <table class="table">
    <thead>
      <tr>
        <th>学员编号</th>
        <th>学员姓名</th>
        <th>学员信息</th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="(item, index) in members" :key="index">
        <td>{{item.id}}</td>
        <td>{{item.name}}</td>
        <td>
            <!-- 路由的名字找到对应的路由的路径 -->
            <router-link :to="{name:'memberDetail',params:{id:item.id}}">详细信息</router-link>

        </td>
      </tr>
    </tbody>
  </table>


  </div>
</template>


<script>
import { mapState } from "vuex";
export default {
    name:'MemberHome',
    computed: {
        ...mapState([
            'members'
        ])
    },
}
</script>

Home.vue

<template>
 <div class="jumbotron">
   <h1 class="display-3">首页展示内容</h1>
   <p class="lead">Jumbo helper text</p>
  
 </div>
</template>

<script>

export default {
  name: 'Home',
  components: {
  }
}
</script>

HomeShow.vue

<template>
    <div class="jumbotron">
        <h1 class="display-3">首页展示区</h1>
        <p class="lead">Jumbo helper text</p>
        
    </div>
</template>

App.vue

<template>
  <div id="app">
    <!-- 导航 -->
    <Nav />
    <hr />
    <!-- router-view -->
    <!-- 路由视图:命名 -->
    <div class="container">
      <router-view name="show" />
    </div>

    <hr />

    <!-- 路由视图:默认-->
    <div class="container-fluid">
      <router-view />

      <!-- 路由视图 -->
      <router-view name="detail" />
    </div>

    <!-- 页尾 -->
    <h1 class="text-center">版权信息|公共</h1>
  </div>
</template>


<script>
import Nav from "./components/Nav";
export default {
  name: "App",
  components: {
    Nav
  }
};
</script>


main.js

import Vue from 'vue'
import App from './App.vue'
import store from './store'

//导入路由模块
import router from './router'

Vue.config.productionTip = false

new Vue({
  // 注入到vue实例中,该实例的所有组件中都可以访问 $router,$route
  store,
  router,
  render: h => h(App)
}).$mount('#app')

界面如图所示:

发布了113 篇原创文章 · 获赞 130 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_44364444/article/details/104950127