(03)Vue 实战准备——③ 单文件组件与 Vue 中的“路由” | Vue.js 项目实战: 移动端“旅游网站”开发

1,212 阅读6分钟
转载请注明出处,未经同意,不可修改文章内容。

🔥🔥🔥“前端一万小时”两大明星专栏——“从零基础到轻松就业”、“前端面试刷题”,已于本月大改版,合二为一,干货满满,欢迎点击公众号菜单栏各模块了解。


涉及面试题:
1. 单文件组件解决了哪些问题?
2. Vue-router 跳转和 location.href 有什么区别?
3. Vue 里面 router-link 在电脑上有用,在安卓上没反应怎么解决?
4. Vue2 中注册在 router-link 上事件无效解决方法?
5. 什么是 Vue Router 和它的特性?
6. 使用 Vue Router 路由器的步骤是什么并给出一个例子?
7. 什么是路线匹配优先级?
8. 什么是嵌套路由?

编号:[vue_03]

1 单文件组件

打开项目,进入 src 目录,这里面放的是整个项目的源代码。

打开 main.js ,它是整个项目的“入口文件”: travel03-01.png

// ❗️删除了多余的注释,弄清每一行代码的用途。

import Vue from 'vue'  

import App from './App' /*
												3️⃣-②:这个“组件”是从当前目录下的 App.vue 引入的一个组件;
                        ❗️❗️❗️后边的 ./App 其实是 ./App.vue 的缩写。后缀可以省略,
                        因为 webpack 会优先自动寻找后缀为 .vue 的 App 文件,并引入。
                         */

import router from './router'

Vue.config.productionTip = false

new Vue({ // 1️⃣创建一个 Vue 实例;
  
  el: '#app', // 2️⃣“挂载点”在 id 为 app 的节点上;
  
  router, // 5️⃣router 后文会重点提到,这里先不用关注;
  
  components: { App },  /*
  											3️⃣
                        3️⃣-①:注册了一个“局部组件”;
                         */
  
  template: '<App/>'  // 4️⃣“模板”是 App 组件的内容;
})

/*
6️⃣总结:这个 Vue 实例所展示出来的内容,就是注册进来的(步骤3️⃣)这个 App 组件。
即页面所展示内容,是 App 这个组件。
 */

验证一下:页面所展示内容是否是 App 这个组件? 7️⃣打开终端,依次输入命令行后,打开 http://localhost:8080 查看效果:

cd Desktop
cd qdywxs-travel
npm run dev

travel03-02.png

8️⃣打开 App.vue 对代码进行删减后,返回页面查看效果:

<template>

  <div id="app"> <!-- 8️⃣-①:删除 #app 下的 <img>; -->
    <router-view/>
  </div>

</template>

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

<style> /* 8️⃣-②:删除 <style> 中的样式。 */
</style>

travel03-03.png

App.vue 这样以 .vue 为后缀的是什么文件? 答:当一个文件以 .vue 为结尾时,这类文件就是“单文件组件”。

  • 单文件组件与之前我们定义的组件完全不一样,之前我们这样定义组件: Vue.component("组件名", {组件的模版、逻辑等})

  • 而在 App.vue 中,仔细查看其代码可以发现,代码其实分为 3 个部分: <template> 标签包裹的模板部分、 <script> 标签包裹的逻辑部分和 <style> 标签包裹的样式部分。

travel03-04.png

❗️刚才已经把 App.vue 里的内容几乎删光了,为什么页面上还会有内容展示? 这就涉及到接下来的内容——路由

2 路由

❓什么是路由? 答:路由可以直接理解为根据网址的不同,返回不同的内容给用户(这也是路由的功能)。

再仔细查看 App.vue 代码:

<template>
  <div id="app">
    <router-view/> <!-- ❗️只多出这一个标签。注释此标签后查看页面效果! -->
  </div>
</template>

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

<style>

</style>

travel03-05.png

<router-view/> 标签是什么? 答: <router-view/> 标签显示的是当前路由地址所对应的内容

取消对 <router-view/> 的注释后,可以看到内容展示。这时的“当前路由地址”就是 localhost 下的根路径: travel03-06.png

❓根路径所对应的内容为什么是显示在页面上的这些? 答:因为这些内容就是在路由中配置显示内容的。

打开 main.js 文件,Vue 实例里边的 router 就是项目的路由配置部分的内容:

import Vue from 'vue'
import App from './App'
import router from './router' /*
															1️⃣引入 router 变量;
															Vue 会去找当前目录下的 router 文件夹,
                              并自动引入 router 文件夹下的 index.js 文件;
                               */

Vue.config.productionTip = false

new Vue({
  el: '#app',
  
  router, // 2️⃣创建根实例时使用了 router 变量。
  
  components: { App },
  template: '<App/>'
})

根据上面的序号 1️⃣的指引,我们打开 index.js 这个文件:

import Vue from 'vue'
import Router from 'vue-router'

// 4️⃣HelloWorld 组件到 src 目录下的 components 文件夹引入;❗️@ 符指的是 src 目录。
import HelloWorld from '@/components/HelloWorld'

Vue.use(Router)

// 1️⃣导出的内容是一组路由配置项;
export default new Router({
  routes: [
    {
      // 2️⃣当用户访问根路径 / 时;
      path: '/',
      name: 'HelloWorld',  
      
      /*
      3️⃣根路径对应的组件是 HelloWorld(即当我们访问根路径 / 时,
      就给用户展示 HelloWorld 组件的内容);
       */
      component: HelloWorld
    }
  ]
})

❓遗留问题: App.vue 里的内容几乎删光了,为什么页面上还会有内容展示呢? 答:根据上面对路由的了解我们知道,** App.vue 根组件里的 <router-view/> 标签里展示的是 HelloWorld 这个小组件的内容**。

打开 HelloWorld 组件对其代码做一些修改后,查看网页效果:

<template> <!-- 1️⃣删除模板中内容; -->
  <div></div>
</template>

<script>
export default {
  name: 'HelloWorld'
  // 2️⃣删除逻辑;
}
</script>

<style scoped> /* 3️⃣删除样式。 */

</style>

travel03-07.png

HelloWorld.vue 小组件里写入一些内容后,查看效果:

<template>
  <div>hello, qdywxs.</div>
</template>

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

<style scoped>
</style>

travel03-08.png

简单梳理一下:

  • 路由的配置都放在 router 文件夹下的 index.js 里面;

  • App.vue 是整个应用的根组件:

    • 这里面的 <router-view/> 标签显示的内容是当前路由地址所对应的路由内容;
    • 当前路由地址所对应的路由内容,在 router 文件夹下的 index.js 里,通过配置项的对应关系来找到。比如在这里,当访问根路径 / 的时候,展示的是 HelloWorld.vue 组件的内容。

3 优化项目代码结构

现在,根据我们“旅游网站”项目,来优化项目代码的结构:

  • 访问根路径展示首页 Home 而不是 HelloWorld
  • 访问 list 路径展示 List 列表页。

1️⃣由于项目中会有多个页面及不同组件,所以删除 src 目录下的 components 文件夹及其文件 HelloWorld.vue新建 pages 文件夹用以存放所有网页;

2️⃣在 pages 中新建 “home 文件夹”(即“首页”),并在 home 文件夹中新建 Home.vue 组件: travel03-09.png

Home.vue 组件如何写? 根据单文件组件的“三个部分”写出 Home.vue 组件:

<!-- 2️⃣-①:<template> 标签包裹的模板部分; -->
<template>

  <!-- ❗️首页内容暂时为字符串 Home; -->
  <div>Home</div>

</template>

<!-- 2️⃣-②:<script> 标签包裹的逻辑部分; -->
<script>
export default {

  // ❗️给组件命名为 Home,逻辑暂时不写;
  name: 'Home'
}
</script>

<!-- 2️⃣-③:<style> 标签包裹的样式部分,暂时不写; -->
<style>

</style>

3️⃣要让首页展示出“Home”字符串,我们需要配置 router 文件夹中 index.js 里的路由项:

import Vue from 'vue'
import Router from 'vue-router'

/*
3️⃣-①:删除不需要的引入 HelloWorld 组件的代码;
import HelloWorld from '@/components/HelloWorld'
 */

// 3️⃣-②:从 src 目录的 pages 下的 home 文件夹中引入 Home.vue 组件;
import Home from '@/pages/home/Home'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',

      name: 'Home', // 3️⃣-③:组件名更改为 Home;

      component: Home // 3️⃣-④:组件为 Home。
    }
  ]
})

改写后的首页效果: travel03-10.png

4️⃣在 pages 文件夹内新建 “list 文件夹”(即“列表页”),并在 list 文件夹中新建 List.vue 组件:

<!-- ❗️复制 Home.vue 的内容,把 Home 改为 List! -->
<template>
  <div>List</div>
</template>

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

<style>

</style>

5️⃣在 router 文件夹下的 index.js 中配置列表页的路由项:

import Vue from 'vue'
import Router from 'vue-router'
import Home from '@/pages/home/Home'

// 5️⃣-①:从 src 目录的 pages 下的 list 文件夹中引入 List.vue;
import List from '@/pages/list/List'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'Home',
      component: Home
    }, {

      path: '/list', // 5️⃣-②:路径改为 /list;

      name: 'List', // 5️⃣-③:组件名改为 List;

      component: List // 5️⃣-④:组件改为 List。
    }
  ]
})

🚀最终效果:当访问 http://localhost:8080 下的根路径时,页面展示首页的“Home”;当访问 /list 路径时,页面展示列表页的“List”。 travel_03-11.gif

❓如何得以实现这个功能的? 答:因为我们在 App.vue 上写有 <router-view/> 标签。它的意思是,这里显示的内容是当前路由所对应的组件”。

所以当访问根路径时,其对应的组件是 Home.vue ,显示“Home”;当访问根目录下的 list 路径时,对应的组件是 List.vue ,显示“List”。

祝好,qdywxs ♥ you!