总结下自己在vue2中的重难点(路由篇)

路由的配置

既然说到了路由,第一步肯定是和组件一样的,需要先进行配置,这里的配置我建议是在router目录下在创建个index.js文件,里面来放置路由的配置内容。

javascript 复制代码
// 0. 导入 Vue 和 VueRouter,要调用 Vue.use(VueRouter)
import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

// 1. 定义 (路由) 组件。
// 可以从其他文件 import 进来
//注意哈,这里路由组件不是在component目录下的,而是在vies目录下。
import Foo from "./views/Foo.vue";
import Bar from "./views/Bar.vue";

// 2. 定义路由
// 每个路由应该映射一个组件。 其中"component" 可以是
// 通过 Vue.extend() 创建的组件构造器,
// 或者,只是一个组件配置对象。
// 我们晚点再讨论嵌套路由。
const routes = [
  { path: '/foo', component: Foo },
  { path: '/bar', component: Bar }
]

// 3. 创建 router 实例,然后传 `routes` 配置
// 你还可以传别的配置参数, 不过先这么简单着吧。
export default new VueRouter({
  mode:'history', // 这个history作用说白了就是路径不用加'#'了。
  routes // (缩写) 相当于 routes: routes
})

另外,我们还需要在main.js文件里面注入路由,即:

xml 复制代码
<template>
  <div id="app">
    <h1>Hello App!</h1>
    <p>
      <!-- 使用 router-link 组件来导航. -->
      <!-- 通过传入 `to` 属性指定链接. -->
      <!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
      <router-link to="/foo">Go to Foo</router-link>
      <router-link to="/bar">Go to Bar</router-link>
    </p>
    <!-- 路由出口 -->
    <!-- 路由匹配到的组件将渲染在这里 -->
    <!-- App.vue 中的 <router-view></router-view> 是路由的最高级出口 -->
    <router-view></router-view>
  </div>
</template>

添加路由

我们写网页时,肯定还需要添加更多的路由,那么添加路由非常简单,看下图即可:

javascript 复制代码
// 1. 将要用到的组件从其他文件 import 进来
import Foo from './views/Foo.vue';
import Bar from './views/Bar.vue';
import User from './views/User.vue';

// 2. 定义路由,每个路由应该映射一个组件
// 添加路径即在 routes 数组中增加新的成员
const routes = [
  { path: '/foo', component: Foo },
  { path: '/bar', component: Bar },
  // 新增一项
  { path: '/user', component: User }
];

// 3. 创建 Router 实例,然后传 `routes` 配置
export default new VueRouter({
  mode:'history', // 这个history作用说白了就是路径不用加'#'了。
  routes // (缩写) 相当于 routes: routes
})

当然啦,嫌弃上面麻烦我们还有更简单的方法,看代码:

javascript 复制代码
const routes = [
  { path: '/foo', component: () => import('./views/Foo.vue') },
  { path: '/bar', component: () => import('./views/Bar.vue') },
  { path: '/user', component: () => import('./views/User.vue') }
];

命名路由

有时候我们在<router-link to="/foo"></router-link>标签中会发现使用to属性太过于麻烦,我们可以给某个路由设置名称:

javascript 复制代码
// 0. 导入 Album、List、Add、Empty 三个组件

// 1. 定义路由
const routes = [
  { path: '/foo',
    name: 'fooName',
    component: () => import('./views/Foo.vue')
  }
];

通过命名跳转:

xml 复制代码
<!-- to 的值是一个对象而不是字符串,所以要在 to 前加 : -->
<!-- 这里依旧是外双内单 -->
<router-link :to="{name: 'fooName'}">Go to Foo</router-link>

路由布局的管理

我们在写项目有的时候只有功能区的组件发生了变化:

首先,我们肯定是需要先定义嵌套路由

yaml 复制代码
// 0. 导入 Album、List、Add 三个组件
const routes = [
  {
    path: '/album',
    component: Album,
    // children 属性可以用来配置下一级路由(子路由)
    children: [
      { path: 'list', component: List },
      { path: 'add', component: Add }
    ]
  }
];

我们看下例子,配合<router-view></router-view>使用即可:

App.vue 组件:

xml 复制代码
<template>
  <div id="app">
    <h1>Hello App!</h1>
    <p>
      <router-link to="/album/list">Go to Album List</router-link>
      |
      <router-link to="/album/add">Go to Album Add</router-link>
    </p>
    <!-- 路由匹配到的组件将渲染在这里 -->
    <!-- 在本例中为 Album.vue 组件 -->
    <!-- 在本例子中对应的是第一层路由-->
    <router-view></router-view>
  </div>
</template>

Album.vue 组件:

xml 复制代码
<template>
  <div id="album">
    <div class="banner">banner</div>
    <!-- 路由匹配到的组件将渲染在这里 -->
    <!-- 在本例中为 List.vue 组件或 Add.vue 组件 -->
    <!-- 在本例子中对应的是第二层路由-->
    <router-view></router-view>
  </div>
</template>

根路径

在上面的定义嵌套路由例子中,我们可以将子路由更改为以下效果也是一样的:

lua 复制代码
//下面的两种情况其实是一样的。
path: 'list'
path: '/album/list'

空的子路由

如果我们在/album的路径下依旧想要渲染一些东西,那么我们就可以在嵌套路由里面再添加一个空的子路由,如下所示:

yaml 复制代码
// 0. 导入 Album、List、Add、Empty 三个组件
const routes = [
  {
    path: '/album',
    component: Album,
    // children 属性可以用来配置下一级路由(子路由)
    children: [
      // 空的子路由
      { path: '', component: Empty },
      { path: 'list', component: List },
      { path: 'add', component: Add }
    ]
  }
];

动态路由

动态路由说白了就是多个路径都映射到了同一个组件中。像/user/123/user/456等等,后面的id就是添加的参数,我们看个例子就懂了:

javascript 复制代码
import User from "./views/User.vue";

const routes = [
  // id 就是路径参数,别忘记加冒号
  { path: '/user/:id', component: User }
]

我们可以用this.$route.params.参数名称来获取路径参数值。

访问404页面

如果用户输入的url不属于我们注册的任意一个路由,那么我们可以写一个 404 NotFound 组件渲染。

javascript 复制代码
import NotFound from "./views/NotFound.vue";

const routes = [
  {
    // 使用通配符(*)会匹配所有路径
    path: '*',
    component: NotFound
  }
]

另外,要确保上述含有通配符的路由放在了最后。

使用$route读取匹配到的路径值

我们可以在使用通配符(*)的路由下使用$route.params.pathMatch来获取当前路径,比如我们这里输入的URL是http://localhost:8081/non-existing/file,那么结果就如下所示:

csharp 复制代码
this.$route.params.pathMatch // '/non-existing/file'

页面跳转

我们之前的编程式导航中都是使用<router-link>来创建导航链接外,还可以写在JS用router.push()来实现页面跳转,直接看代码:

arduino 复制代码
router.push('user')
router.push('/user')

注意哈,里面是有根路径/的,所以这两种方法实现的功能完全不一样。

router.push()的参数为描述地址的对象

php 复制代码
// 对象
// 这种写法和字符串类型的参数一样
router.push({ path: 'home' })

// 命名的路由
router.push({ name: 'user', params: { userId: '123' }})

// 带查询参数,变成 /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})

另外,第三个参数与其说是增加,不如说是修改,例如localhost:8080/?plan=A,而我们使用 router.push({ path: 'register', query: { plan: 'B' }}),它会变成:localhost:8080/?plan=B。而不是像前面两者直接增加。

看着不是很容易理解,我们可以将下面的参数形式改成:

css 复制代码
router.push({ path: 'user/123'})

router.push({ path: 'user?plan=private'})

这里的方法同样也适用于<router-link>:to属性哦。

页面跳转后如何获取参数

假设我们访问本地工程的一个地址http://localhost:8080/user/123?name=userName#abc,对应的$route如下:

csharp 复制代码
// $route
{
  // 路由名称
  name: "user",
  meta: {},
  // 路由path
  path: "/user/123",
  // 网页位置指定标识符
  hash: "#abc",
  // window.location.search
  query: {name: "userName"},
  // 路径参数 user/:userId
  params: {userId: "123"},
  fullPath: "/user/123?name=userName#abc"
}

这样一来,我们就可以通过$route.name$route.path等来获取了。

别名和重定向

我们只需要搞定两个概念,首先什么是别名,别名就是两个名字都指向同一个路由,看代码:

css 复制代码
const routes: [
  {
    path: '/layout',
    // 别名定为 /
    alias: '/',
    component: ()=> import('@/pages/nest/Layout.vue'),
    children: [
      { path: 'home', component: Home },
      { path: 'courseall', component: CourseAll },
      { path: 'coursedetail/:courseId', component: CourseDetail }
    ]
  }
];

那么接下来我们将使用重定向将/home改成/

这个概念不好说,我们直接看代码:

css 复制代码
const routes: [
  {
    path: '/layout',
    alias: '/',
    // 重定向到 /home
    redirect: '/home',
    component: ()=> import('@/pages/nest/Layout.vue'),
    children: [
      { path: 'home', component: Home },
      { path: 'courseall', component: CourseAll },
      { path: 'coursedetail/:courseId', component: CourseDetail }
    ]
  }
];

这样子一来,现在的路由就变了:

这里我们需要知道,当我们路径使用path/layout时,url会显示成重定向后的url:/home,如果在URL输入的是别名/,那么依旧会重定向,但是url不变。

监听路由

说到监听路由,我可以让大家先看下下面这张图:

从图片中我们可以看出,肯定是需要通过监听路由的变化来实现对应的效果。

监听路由$route的变化

监听的话,绝对就需要用到我们的侦听器watch了,下面代码里面的$route就表示当前路由。

css 复制代码
//当前路由发生了变化,那么触发侦听器。
watch: {
  $route(to,from){
    console.log(to, from);
  }
}

// 或者
watch: {
  $route: {
    handler: function(to,from) {
      console.log(to,from);
    },
    // 深度观察监听
    deep: true
  }
},

网络请求async与await

我们在JS里面使用fetch来请求数据,看代码:

javascript 复制代码
fetch(
  'https://www.done.kim/api/m/f4-11-1-1'
)
  .then(function(response) {
    return response.json();
  })
  .then(function(myJson) {
    console.log(myJson);
  });

因为fetch返回的是一个promise对象,所以我们请求数据的时候使用了then来采用平铺式回调的方式,这样一来就允许我们在数据返回之后再进行response.json()处理。

但是问题也来了,因为每个步骤都是异步的,并且依赖上一个步骤的结果,那么then链会非常长。这时候,就需要我们的asyncawait出马了。

"异步"async

javascript 复制代码
async function asyncFn() {
  return {
    "company": "优课达",
    "slogan": "学的比别人好一点"
  };
}

const result = asyncFn();
console.log(result);

上面的代码返回的也是一个promise对象,那这和fetch区别是什么。关键就在于await关键字。

"等待异步"await

await关键字的作用就是等待异步任务的完成,并会阻塞后面的代码。

scss 复制代码
async function getAsyncFn() {
  //await关键字只能出现在async修饰的函数中,否则会报错。
  const result = await asyncFn();
  console.log(result);
}

getAsyncFn();

多个请求并发执行Promise.all

如果要完成多个请求并发执行,那么就可以使用Promise.all

javascript 复制代码
async function asyncFn1() {
  return "优课达";
}

async function asyncFn2() {
  return "学的比别人好一点";
}

async function getAsyncFn() {
  const result = await Promise.all([asyncFn1(), asyncFn2()]);
  console.log(result);
}

getAsyncFn();

vue中的async和await的使用以及api的传参

xml 复制代码
<script>
export default {
  data: function() {
    return {
      course: []
    };
  },
  //mouted钩子函数作用就是初始化页面完成后,再对DOM节点进行相关操作。
  async mounted() {
    await this.getCourse();
  },
  methods: {
    async getCourse() {
      // 从路径中获取课程 id
      const courseId = this.$route.params.courseId
      // 在接口地址后传入参数 id
      const res = await fetch('https://www.done.kim/api/m/getcourse?id=' + courseId);
      const myJson = await res.json();
      this.course = myJson.data;
    }
  }
}
</script>

到此,基本整理完毕。

相关推荐
潜意识起点15 分钟前
精通 CSS 阴影效果:从基础到高级应用
前端·css
奋斗吧程序媛19 分钟前
删除VSCode上 origin/分支名,但GitLab上实际上不存在的分支
前端·vscode
IT女孩儿29 分钟前
JavaScript--WebAPI查缺补漏(二)
开发语言·前端·javascript·html·ecmascript
m0_748256563 小时前
如何解决前端发送数据到后端为空的问题
前端
请叫我飞哥@3 小时前
HTML5适配手机
前端·html·html5
@解忧杂货铺5 小时前
前端vue如何实现数字框中通过鼠标滚轮上下滚动增减数字
前端·javascript·vue.js
F-2H6 小时前
C语言:指针4(常量指针和指针常量及动态内存分配)
java·linux·c语言·开发语言·前端·c++
苹果酱05676 小时前
「Mysql优化大师一」mysql服务性能剖析工具
java·vue.js·spring boot·mysql·课程设计
gqkmiss7 小时前
Chrome 浏览器插件获取网页 iframe 中的 window 对象
前端·chrome·iframe·postmessage·chrome 插件
m0_748247559 小时前
Web 应用项目开发全流程解析与实战经验分享
开发语言·前端·php