vue2学习笔记

文章目录


Vue基础

前置储备

必备前提

  • HTML + CSS + JavaScript
  • WebAPI(DOM + BOM)
  • Ajax

可选前提

  • Node.js

1. 前端工程化

1.1 前端开发

  • 模块化(js 的模块化、css 的模块化、资源的模块化)
  • 组件化(复用现有的 UI 结构、样式、行为)
  • 规范化(目录结构的划分、编码规范化、接口规范化、文档规范化、 Git 分支管理)
  • 自动化(自动化构建、自动部署、自动化测试)

1.2 前端工程化概念

前端工程化指的是:在企业级的前端项目开发中,把前端开发所需的工具、技术、流程、经验等进行规范化、

标准化。

企业中的 Vue 项目和 React 项目,都是基于工程化的方式进行开发的。

好处:前端开发自成体系,有一套标准的开发方案和流程。

1.3 前端工程化解决方案

早期的前端工程化解决方案:

  • grunt( https://www.gruntjs.net/ )
  • gulp( https://www.gulpjs.com.cn/ )

目前主流的前端工程化解决方案:

  • webpack( https://www.webpackjs.com/ )
  • parcel( https://zh.parceljs.org/ )

2. webpack使用

2.1 概念

概念:webpack 是前端项目工程化的具体解决方案

主要功能:它提供了友好的前端模块化开发支持,以及代码压缩混淆、处理浏览器端 JavaScript 的兼容性、性

能优化等强大的功能。

好处:让程序员把工作的重心放到具体功能的实现上,提高了前端开发效率和项目的可维护性

注意:目前 Vue,React 等前端项目,基本上都是基于 webpack 进行工程化开发的。

2.2 创建列表隔行变色项目

① 新建项目空白目录,并运行 npm init –y 命令,初始化包管理配置文件 package.json

② 新建 src 源代码目录

③ 新建 src -> index.html 首页和 src -> index.js 脚本文件

④ 初始化首页基本的结构

⑤ 运行 npm install jquery –S 命令,安装 jQuery

⑥ 通过 ES6 模块化的方式导入 jQuery,实现列表隔行变色效果

2.3 在项目中安装 webpack

在终端运行如下的命令,安装 webpack 相关的两个包:

npm install webpack@5.42.1 webpack-cli@4.9.0 -D 
  • -S(–save) :存放在dependencies中,开发和上线后都会使用的包
  • -D(–save -dev):存放在devDependencies中,只在开发中使用

2.4 在项目中配置 webpack

① 在项目根目录中,创建名为 webpack.config.js 的 webpack 配置文件,并初始化如下的基本配置:

// 使用Node.js 中的语法,向外导出一个 webpack 对象
module.exports = {
    // 代表 webpack 运行模式,可选值有两个 development 和 production
    mode: 'development'
}

② 在 package.json 的 scripts 节点下,新增 dev 脚本如下:

"scripts": {
    "dev": "webpack"
}

③ 在终端中运行 npm run dev 命令,启动 webpack 进行项目的打包构建

2.5 mode 的可选值

mode 节点的可选值有两个,分别是:

① development

  • 开发环境
  • 不会对打包生成的文件进行代码压缩和性能优化
  • 打包速度快,适合在开发阶段使用

② production

  • 生产环境
  • 会对打包生成的文件进行代码压缩和性能优化
  • 打包速度很慢,仅适合在项目发布阶段使用

2.6 webpack.config.js 文件的作用

webpack.config.js 是 webpack 的配置文件。webpack 在真正开始打包构建之前,会先读取这个配置文件,

从而基于给定的配置,对项目进行打包。

注意:由于 webpack 是基于 node.js 开发出来的打包工具,因此在它的配置文件中,支持使用 node.js 相关

的语法和模块进行 webpack 的个性化配置。

2.7 webpack 中的默认约定

在 webpack 4.x 和 5.x 的版本中,有如下的默认约定:

​ ① 默认的打包入口文件为 src -> index.js

​ ② 默认的输出文件路径为 dist -> main.js

注意:可以在 webpack.config.js 中修改打包的默认约定

2.7 自定义打包的入口与出口

在 webpack.config.js 配置文件中,通过 entry 节点指定打包的入口。通过 output 节点指定打包的出口。

示例代码如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BAueYxA1-1650958920151)(D:\A_study\Vue\study_image\3.3自定义打包的入口与出口.png)]

3. webpack中的插件

3.1 webpack 插件的作用

通过安装和配置第三方的插件,可以拓展 webpack 的能力,从而让 webpack 用起来更方便。最常用的

webpack 插件有如下两个:

① webpack-dev-server

  • 类似于 node.js 阶段用到的 nodemon 工具
  • 每当修改了源代码,webpack 会自动进行项目的打包和构建

② html-webpack-plugin

  • webpack 中的 HTML 插件(类似于一个模板引擎插件)
  • 可以通过此插件自定制 index.html 页面的内容

webpack-dev-server 可以让 webpack 监听项目源代码的变化,从而进行自动打包构建。

3.2 安装 webpack-dev-server

运行如下的命令,即可在项目中安装此插件:

npm install webpack-dev-server@3.11.2 -D

3.3 配置 webpack-dev-server

① 修改 package.json -> scripts 中的 dev 命令如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iRPdDlhJ-1650958920153)(D:\A_study\Vue\study_image\2. 配置webpack-server.png)]

② 再次运行 npm run dev 命令,重新进行项目的打包

③ 在浏览器中访问 http://localhost:8080 地址,查看自动打包效果

注意:webpack-dev-server 会启动一实时打包的 http 服务器,webpack-cli的版本一定要@4.9.0,太低无法运行

3.4 打包生成的文件哪儿去了?

① 不配置 webpack-dev-server 的情况下,webpack 打包生成的文件,会存放到实际的物理磁盘上

  • 严格遵守开发者在 webpack.config.js 中指定配置
  • 根据 output 节点指定路径进行存放

② 配置了 webpack-dev-server 之后,打包生成的文件存放到了内存中

  • 不再根据 output 节点指定的路径,存放到实际的物理磁盘上
  • 提高了实时打包输出的性能,因为内存比物理磁盘速度快很多
<!-- 加载和引用内存中的 main.js,在根目录上下的,看不见但实际存在 -->
<script src="/bundle.js"></script>

3.5 生成到内存中的文件该如何访问?

webpack-dev-server 生成到内存中的文件,默认放到了项目的根目录中,而且是虚拟的、不可见的。

  • 可以直接用 / 表示项目根目录,后面跟上要访问的文件名称,即可访问内存中的文件
  • 例如 /bundle.js 就表示要访问 webpack-dev-server 生成到内存中的 bundle.js 文件

3.6 html-webpack-plugin

html-webpack-plugin 是 webpack 中的 HTML 插件,可以通过此插件自定制 index.html 页面的内容。

需求:通过 html-webpack-plugin 插件,将 src 目录下的 index.html 首页,复制到项目根目录中一份

3.7 安装 html-webpack-plugin

运行如下的命令,即可在项目中安装此插件:

npm install html-webpack-plugin@5.3.2 -D

3.8 配置 html-webpack-plugin

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-X0eaucBQ-1650958920153)(D:\A_study\Vue\study_image\3. 配置 html-webpack-plugin.png)]

// 导入html-webpack-plugin插件,得到插件的构造函数
const HtmlPlugin = require('html-webpack-plugin')
const htmlPlugin = new HtmlPlugin({
    // 指定要复制哪个页面
    template: './src/index.html',
    // 指定赋值出来的文件名和存放路径
    filename: './index.html'
})

// 使用Node.js 中的语法,向外导出一个 webpack 对象
module.exports = {
    // 插件的数组,将来 webpack 在运行时,会加载并调用这个插件
    plugins: [htmlPlugin]
}

3.9 解惑 html-webpack-plugin

① 通过 HTML 插件复制到项目根目录中的 index.html 页面,也被放到了内存中

② HTML 插件在生成的 index.html 页面,自动注入了打包的 bundle.js 文件

3.10 devServer 节点

在 webpack.config.js 配置文件中,可以通过 devServer 节点对 webpack-dev-server 插件进行更多的配置,

示例代码如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Pw0SqaDz-1650958920154)(D:\A_study\Vue\study_image\4. devServer 节点.png)]

注意:凡是修改了 webpack.config.js 配置文件,或修改了 package.json 配置文件,必须重启实时打包的服

务器,否则最新的配置文件无法生效!

4. webpack 中的 loader

4.1 loader 概述

在实际开发过程中,webpack 默认只能打包处理以 .js 后缀名结尾的模块。其他非 .js 后缀名结尾的模块,

webpack 默认处理不了,需要调用 loader 加载器才可以正常打包,否则会报错!

loader 加载器的作用:协助 webpack 打包处理特定的文件模块。比如:

  • css-loader 可以打包处理 .css 相关的文件
  • less-loader 可以打包处理 .less 相关的文件
  • babel-loader 可以打包处理 webpack 无法处理的高级 JS 语法

4.2 打包处理 css 文件

① 运行 npm i style-loader@3.0.0 css-loader@5.2.6 -D 命令,安装处理 css 文件的 loader

② 在 webpack.config.js 的 module -> rules 数组中,添加 loader 规则如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bTA3d7pK-1650958920154)(D:\A_study\Vue\study_image\5. 打包处理 css 文件.png)]

其中,test 表示匹配的文件类型, use 表示对应要调用的 loader

注意:

  • use 数组中指定的 loader 顺序是固定的
  • 多个 loader 的调用顺序是:从后往前调用

4.3 打包处理 less 文件

① 运行 npm i less-loader@10.0.1 less@4.1.1 -D 命令

② 在 webpack.config.js 的 module -> rules 数组中,添加 loader 规则如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D1RKdB2W-1650958920155)(D:\A_study\Vue\study_image\6.打包处理 less 文件.png)]

4.4 打包处理样式表中与 url 路径相关的文件

① 运行 npm i url-loader@4.1.1 file-loader@6.2.0 -D 命令

② 在 webpack.config.js 的 module -> rules 数组中,添加 loader 规则如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3eWuFW2q-1650958920155)(D:\A_study\Vue\study_image\7.打包处理样式表中与 url 路径相关的文件.png)]

其中 ? 之后的是 loader 的参数项:

  • limit 用来指定图片的大小,单位是字节(byte)
  • 只有 ≤ limit 大小的图片,才会被转为 base64 格式的图片

4.5 打包处理 js 文件中的高级语法

webpack 只能打包处理一部分高级的 JavaScript 语法。对于那些 webpack 无法处理的高级 js 语法,需要借

助于 babel-loader 进行打包处理。例如 webpack 无法处理下面的 JavaScript 代码:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BnF2bO2l-1650958920156)(D:\A_study\Vue\study_image\8.打包处理 js 文件中的高级语法.png)]

4.6 安装 babel-loader 相关的包

运行如下的命令安装对应的依赖包:

npm i babel-loader@8.2.2 @babel/core@7.14.6 @babel/plugin-proposal-decorators@7.14.5 -D

在 webpack.config.js 的 module -> rules 数组中

4.7 配置 babel-loader

在项目根目录下,创建名为 babel.config.js 的配置文件,定义 Babel 的配置项如下:

module.exprots = {
  plugins: [['@babel/plugin-proposal-decorators ',{ legacy: true }]]
}

5. 打包发送

5.1 为什么要打包发布

项目开发完成之后,需要使用 webpack 对项目进行打包发布,主要原因有以下两点:

① 开发环境下,打包生成的文件存放于内存中,无法获取到最终打包生成的文件

② 开发环境下,打包生成的文件不会进行代码压缩和性能优化

为了让项目能够在生产环境中高性能的运行,因此需要对项目进行打包发布。

5.2 配置 webpack 的打包发布

在 package.json 文件的 scripts 节点下,新增 build 命令如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Mb3nVJX2-1650958920156)(D:\A_study\Vue\study_image\9.配置 webpack 的打包发布.png)]

–model 是一个参数项,用来指定 webpack 的运行模式。production 代表生产环境,会对打包生成的文件

进行代码压缩和性能优化。

注意:通过 --model 指定的参数项,会覆盖 webpack.config.js 中的 model 选项。

5.3 把 JavaScript 文件统一生成到 js 目录中

在 webpack.config.js 配置文件的 output 节点中,进行如下的配置:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vgsBivJ9-1650958920157)(D:\A_study\Vue\study_image\10.把 JavaScript 文件统一生成到 js 目录中.png)]

5.4 把图片文件统一生成到 image 目录中

修改 webpack.config.js 中的 url-loader 配置项,新增 outputPath 选项即可指定图片文件的输出路径:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6ihzQTxb-1650958920157)(D:\A_study\Vue\study_image\11.把图片文件统一生成到 image 目录中.png)]

5.5 自动清理 dist 目录下的旧文件

为了在每次打包发布时自动清理掉 dist 目录中的旧文件,可以安装并配置 clean-webpack-plugin 插件:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hQZgIurQ-1650958920158)(D:\A_study\Vue\study_image\12.自动清理 dist 目录下的旧文件.png)]

6. Source Map

6.1 概念

Source Map 就是一个信息文件,里面储存着位置信息。也就是说,Source Map 文件中存储着压缩混淆后的

代码,所对应的转换前的位置。

有了它,出错的时候,除错工具将直接显示原始代码,而不是转换后的代码,能够极大的方便后期的调试。

6.2 webpack 开发环境下的 Source Map

开发环境下默认生成的 Source Map,记录的是生成后的代码的位置。会导致运行时报错的行数与源代码的行

数不一致的问题。示意图如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SLqwRswC-1650958920158)(D:\A_study\Vue\study_image\13.默认 Source Map 的问题.png)]

6.3 解决默认 Source Map 的问题

开发环境下,推荐在 webpack.config.js 中添加如下的配置,即可保证运行时报错的行数与源代码的行数

保持一致:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2VsA40rX-1650958920158)(D:\A_study\Vue\study_image\14.解决默认 Source Map 的问题.png)]

6.4 webpack 生产环境下的 Source Map

在生产环境下,如果省略了 devtool 选项,则最终生成的文件中不包含 Source Map。这能够防止原始代码通

过 Source Map 的形式暴露给别有所图之人。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Pc7l6IEq-1650958920159)(D:\A_study\Vue\study_image\15.webpack 生产环境下的 Source Map.png)]

6.5 只定位行数不暴露源码

在生产环境下,如果只想定位报错的具体行数,且不想暴露源码。此时可以将 devtool 的值设置为

nosources-source-map。实际效果如图所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-erMdoouS-1650958920159)(D:\A_study\Vue\study_image\16. 只定位行数不暴露源码.png)]

6.6 定位行数且暴露源码

在生产环境下,如果想在定位报错行数的同时,展示具体报错的源码。此时可以将 devtool 的值设置为

source-map。实际效果如图所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Cy9W01EW-1650958920160)(D:\A_study\Vue\study_image\17.定位行数且暴露源码.png)]

采用此选项后:你应该将你的服务器配置为,不允许普通用户访问 source map 文件!

6.7 Source Map 的最佳实践

① 开发环境下:

  • 建议把 devtool 的值设置为 eval-source-map
  • 好处:可以精准定位到具体的错误行

② 生产环境下:

  • 建议关闭 Source Map 或将 devtool 的值设置为 nosources-source-map
  • 好处:防止源码泄露,提高网站的安全性

7. 总结

① 能够掌握 webpack 的基本使用

  • 安装、webpack.config.js、修改打包入口

② 了解常用的 plugin 的基本使用

  • webpack-dev-server、html-webpack-plugin

③ 了解常用的 loader 的基本使用

  • loader 的作用、loader 的调用过程

④ 能够说出 Source Map 的作用

  • 精准定位到错误行并显示对应的源码
  • 方便开发者调试源码中的错误

Vue基础入门

1. 简介

1.1 概念

官方给出的概念:Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的前端框架

  1. 构建用户界面
    • 用 vue 往 html 页面中填充数据,非常的方便
  2. 框架
    • 框架是一套现成的解决方案,程序员只能遵守框架的规范,去编写自己的业务功能!
    • 要学习 vue,就是在学习 vue 框架中规定的用法!
    • vue 的指令、组件(是对 UI 结构的复用)、路由、Vuex、vue 组件库

1.2 vue特性

vue 框架的特性,主要体现在如下两方面:

​ ① 数据驱动视图

​ ② 双向数据绑定

  1. 数据驱动视图:

    • 数据的变化会驱动视图自动更新
    • 好处:程序员只管把数据维护好,那么页面结构会被 vue 自动渲染出来!
  2. 双向数据绑定:

    在网页中,form 表单负责采集数据,Ajax 负责提交数据

    • js 数据的变化,会被自动渲染到页面上
    • 页面上表单采集的数据发生变化的时候,会被 vue 自动获取到,并更新到 js 数据中
  • 注意:数据驱动视图和双向数据绑定的底层原理是 MVVM(Mode 数据源、View 视图、ViewModel 就是 vue 的实例)
1. 数据驱动视图

在使用了 vue 的页面中,vue 会监听数据的变化,从而自动重新渲染页面的结构。示意图如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wQI1dtYx-1650958920162)(D:\A_study\Vue\study_image\b1.数据驱动视图.png)]

好处:当页面数据发生变化时,页面会自动重新渲染!

注意:数据驱动视图是单向的数据绑定

2. 双向数据绑定

在填写表单时,双向数据绑定可以辅助开发者在不操作 DOM 的前提下,自动把用户填写的内容同步到数据源

中。

好处:开发者不再需要手动操作 DOM 元素,来获取表单元素最新的值!

3. MVVM

MVVM 是 vue 实现数据驱动视图和双向数据绑定的核心原理。MVVM 指的是 Model、View 和 ViewModel,

它把每个 HTML 页面都拆分成了这三个部分

在 MVVM 概念中:

  • Model 表示当前页面渲染时所依赖的数据源。
  • View 表示当前页面所渲染的 DOM 结构。
  • ViewModel 表示 vue 的实例,它是 MVVM 的核心。
4. MVVM 的工作原理

ViewModel 作为 MVVM 的核心,是它把当前页面的数据源(Model)和页面的结构(View)连接在了一起。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oi1tTj5b-1650958920163)(D:\A_study\Vue\study_image\b2.MVVM 的工作原理.png)]

当数据源发生变化时,会被 ViewModel 监听到,VM 会根据最新的数据源自动更新页面的结构

当表单元素的值发生变化时,也会被 VM 监听到,VM 会把变化过后最新的值自动同步到 Model 数据源中

1.3 vue 的版本

当前,vue 共有 3 个大版本,其中:

  • 2.x 版本的 vue 是目前企业级项目开发中的主流版本
  • 3.x 版本的 vue 于 2020-09-19 发布,生态还不完善,尚未在企业级项目开发中普及和推广
  • 1.x 版本的 vue 几乎被淘汰,不再建议学习与使用

总结:

  • 3.x 版本的 vue 是未来企业级项目开发的趋势;
  • 2.x 版本的 vue 在未来(1 ~ 2年内)会被逐渐淘汰;

2. vue基本使用

1. 基本使用步骤

① 导入 vue.js 的 script 脚本文件

② 在页面中声明一个将要被 vue 所控制的 DOM 区域

③ 创建 vm 实例对象(vue 实例对象)

<body>
    <!-- 希望 Vue 能够控制下面的这个div, 帮助我们在把数据填充到div 内部 -->
    <div id="app">{{username}}</div>

    <!-- 1. 导入Vue 的库文件 -->
    <script src="./lib/vue-2.6.12.js"></script>
    <!-- 2. 创建vue 实例对象 -->
    <script>
        const vm = new Vue({
            // el 属性时固定写法,表示当前vm 实例要控制页面上的哪个区域,接受的值是一个选择器
            el: '#app',
            // data 对象就是要渲染到页面上的数据
            data: {
                username: 'zhangsan',
                age: 20
            }

        })
    </script>
</body>
2. 基本代码与 MVVM 的对应关系

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TUuQWw3Y-1650958920163)(D:\A_study\Vue\study_image\b3. 基本代码与 MVVM 的对应关系.png)]

3. vue 的指令与过滤器

3.1 指令的概念

指令(Directives)是 vue 为开发者提供的模板语法,用于辅助开发者渲染页面的基本结构。

vue 中的指令按照不同的用途可以分为如下 6 大类:

​ ① 内容渲染指令

​ ② 属性绑定指令

​ ③ 事件绑定指令

​ ④ 双向绑定指令

​ ⑤ 条件渲染指令

​ ⑥ 列表渲染指令

注意:指令是 vue 开发中最基础、最常用、最简单的知识点。

3.2 内容渲染指令

内容渲染指令用来辅助开发者渲染 DOM 元素的文本内容。常用的内容渲染指令有如下 3 个:

  • v-text
  • {{ }}
  • v-html
1. v-text

内容渲染指令

<p v-text="username"></p>
<p v-text="gender">性别</p>	//页面仅显示gender的值,没有'性别'

注意:v-text 指令会覆盖元素内默认的值。

2. {{ }} 语法

vue 提供的{{ }} 语法,专门用来解决 v-text 会覆盖默认文本内容的问题。这种 {{ }} 语法的专业名称是插值表达式(英文名为:Mustache)

<p>姓名:{{username}}</p>	//姓名:zhangsan
<p>性别:{{gender}}</p>	//性别:女

注意:相对于 v-text 指令来说,插值表达式在开发中更常用一些!因为它不会覆盖元素中默认的文本内容。在实际开发中用的最多,只是内容的占位符,不会覆盖原有的内容!

3. v-html

v-text 指令和插值表达式只能渲染纯文本内容。如果要把包含 HTML 标签的字符串渲染为页面的 HTML 元素,

则需要用到 v-html 这个指令:

<div v-html="info"></div>

作用:可以把带有标签的字符串,渲染成真正的 HTML 内容!

4. el属性的使用注意点

尽量在一个大div下,使用

如果el只指定一个p标签,仅选择第一个p标签,其他不会发生变化

3.3 属性绑定指令

属性绑定:用英文 : 来绑定

注意:插值表达式只能用在元素的内容节点中,不能用在元素的属性节点中!

  • 在 vue 中,可以使用 v-bind: 指令,为元素的属性动态绑定值;
  • 简写是英文的 :

如果需要为元素的属性动态绑定属性值,则需要用到 v-bind 属性绑定指令。用法示例如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cdhcI0FU-1650958920164)(D:\A_study\Vue\study_image\b4.属性绑定指令.png)]

3.4 使用 Javascript 表达式

在 vue 提供的模板渲染语法中,除了支持绑定简单的数据值之外,还支持 Javascript 表达式的运算

<div>1 + 2 的结果是: {{1 + 2}}</div> //3
<div>{{tips}} 反转的结果是:{{tips.split('').reverse().join('')}}</div> //名户用入输请
<div :title="'box' + index">这是一个div</div>//title: box3

注意:在使用 v-bind 属性绑定期间,如果绑定内容需要进行动态拼接,则字符串的外面应该包裹单引号

3.6 事件绑定指令

事件绑定:用@来绑定

vue 提供了 v-on 事件绑定指令,用来辅助程序员为 DOM 元素绑定事件监听。语法格式如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c2VUMbvv-1650958920164)(D:\A_study\Vue\study_image\b5.事件绑定指令.png)]

  • 注意:原生 DOM 对象有 onclick、oninput、onkeyup 等原生事件,替换为 vue 的事件绑定形式后
  • 分别为:v-on:click、v-on:input、v-on:keyup
<div id="app">
  <p>count 的值是: {{count}}</p>
  <button v-on:click="add">+1</button>
</div>
// methods 的作用,就是定义事件处理函数
methods: {
	add: function() {
		console.log('ok');
	}
}

// 可以简写
methods: {
	add() {
		console.log('ok');
	}
}

在使用 v-on 指令绑定事件时,可以使用 ( ) 进行传参,示例代码如下:

<button @click="add(1)">+N</button>

注意

  • 通过 v-on 绑定的事件处理函数,需要在 methods 节点中进行声明
  • 由于 v-on 指令在开发中使用频率非常高,因此,vue 官方为其提供了简写形式(简写为英文的 @ )
1. 事件参数对象

在原生的 DOM 事件绑定中,可以在事件处理函数的形参处,接收事件参数对象 event。同理,在 v-on 指令

(简写为 @ )所绑定的事件处理函数中,同样可以接收到事件参数对象 event,示例代码如下:

methods: {
    add(e) {
      this.count += 1
      if (this.count % 2 == 0) {
        // 偶数
        e.target.style.backgroundColor = 'red'
      } else {
        // 奇数
        e.target.style.backgroundColor = ''
    }
  }
}

$event

$event 是 vue 提供的特殊变量,用来表示原生的事件参数对象 event。$event 可以解决事件参数对象 event

被覆盖的问题。示例用法如下

<button @click="add(1,$event)">+N</button>

methods: {
    add(n, e) {
    this.count += n
    if (this.count % 2 == 0) {
      // 偶数
      e.target.style.backgroundColor = 'red'
    } else {
      // 奇数
      e.target.style.backgroundColor = ''
    }
  }
}
2. 事件修饰符

在事件处理函数中调用 event.preventDefault() 或 event.stopPropagation() 是非常常见的需求。因此,

vue 提供了事件修饰符的概念,来辅助程序员更方便的对事件的触发进行控制。常用的 5 个事件修饰符如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FmUt0Nj3-1650958920165)(D:\A_study\Vue\study_image\b6.事件修饰符.png)]

语法格式如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YKb6ZlZW-1650958920166)(D:\A_study\Vue\study_image\b8.事件修饰符语法.png)]

3. 按键修饰符

在监听键盘事件时,我们经常需要判断详细的按键。此时,可以为键盘相关的事件添加按键修饰符,例如

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FMO60Wyq-1650958920167)(D:\A_study\Vue\study_image\b9.按键修饰符.png)]

<input type="text" @keyup.enter="clearInput">

methods: {
  clearInput(e) {
  	e.target.value = ''
  }
}

3.7 双向绑定指令

v-model

vue 提供了 v-model 双向数据绑定指令,用来辅助开发者在不操作 DOM 的前提下,快速获取表单的数据。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-InUO6Yrt-1650958920167)(D:\A_study\Vue\study_image\b10.双向绑定指令.png)]

1. v-model 指令的修饰符

为了方便对用户输入的内容进行处理,vue 为 v-model 指令提供了 3 个修饰符,分别是:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pqFMB7VA-1650958920168)(D:\A_study\Vue\study_image\b11.v-model 指令的修饰符.png)]

2. 指令限制

v-model 指令只能和表单元素使用,因为v-model 底层检测的是value值,且其它标签无法交互

  1. input 输入框
    • type=“radio”
    • type=“checkbox”
    • type=“xxxx”
  2. textarea
  3. select

3.8 条件渲染指令

条件渲染指令用来辅助开发者按需控制 DOM 的显示与隐藏。条件渲染指令有如下两个,分别是:

  • v-if
  • v-show
<div id="app">
        <p v-if="flag">这是被 v-if 控制的元素</p>
        <p v-show="flag">这是被 v-show 控制的元素</p>
</div>
1. v-if 和 v-show 的区别

实现原理不同:

  • v-if 指令会动态地创建或移除 DOM 元素,从而控制元素在页面上的显示与隐藏;
    • 如果刚进入页面的时候,某些元素默认不需要被展示,而且后期这个元素很可能也不需要被展示出来,此时 v-if 性能更好
  • v-show 指令会动态为元素添加或移除 style=“display: none;” 样式,从而控制元素的显示与隐藏;
    • 如果要频繁的切换元素的显示状态,用 v-show 性能会更好

在实际开发中,绝大多数情况,不用考虑性能问题,直接使用 v-if 就好了!!!

性能消耗不同:

v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此:

  • 如果需要非常频繁地切换,则使用 v-show 较好
  • 如果在运行时条件很少改变,则使用 v-if 较好
2. v-else

v-if 可以单独使用,或配合 v-else 指令一起使用:

注意:v-else 指令必须配合 v-if 指令一起使用,否则它将不会被识别!

3. v-else-if

v-else-if 指令,顾名思义,充当 v-if 的“else-if 块”,可以连续使用:

<div v-if="type === 'A'">优秀</div>
<div v-else-if="type === 'B'">良好</div>
<div v-else-if="type === 'C'">一般</div>
<div v-else>差</div>

注意:v-else-if 指令必须配合 v-if 指令一起使用,否则它将不会被识别!

3.9 列表渲染指令

vue 提供了 v-for 列表渲染指令,用来辅助开发者基于一个数组来循环渲染一个列表结构。v-for 指令需要使

用 item in items 形式的特殊语法,其中:

  • items 是待循环的数组
  • item 是被循环的每一项

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CCE2UDoO-1650958920168)(D:\A_study\Vue\study_image\b12.列表渲染指令.png)]

注意:v-for 指令中的 item 项和 index 索引都是形参,可以根据需要进行重命名。例如 (user, i) in userlist

<tr v-for="item in list">
    <td>index</td>
    <td>{{item.id}}</td>
    <td>{{item.name}}</td>
</tr>
1. 使用 key 维护列表的状态

官方对 key 值类型,是有要求的,必须是字符串或者数字型

当列表的数据变化时,默认情况下,vue 会尽可能的复用已存在的 DOM 元素,从而提升渲染的性能。但这种

默认的性能优化策略,会导致有状态的列表无法被正确更新。

为了给 vue 一个提示,以便它能跟踪每个节点的身份,从而在保证有状态的列表被正确更新的前提下,提升渲

染的性能。此时,需要为每项提供一个唯一的 key 属性:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jOhBV1rN-1650958920168)(D:\A_study\Vue\study_image\b13.使用 key 维护列表的状态.png)]

2. key 的注意事项

​ ① key 的值只能是字符串数字类型

​ ② key 的值必须具有唯一性(即:key 的值不能重复)

​ ③ 建议把数据项 id 属性的值作为 key 的值(因为 id 属性的值具有唯一性)

​ ④ 使用 index 的值当作 key 的值没有任何意义(因为 index 的值不具有唯一性)

​ ⑤ 建议使用 v-for 指令时一定要指定 key 的值(既提升性能、又防止列表状态紊乱)

3.10 过滤器

过滤器(Filters)是 vue 为开发者提供的功能,常用于文本的格式化。过滤器可以用在两个地方:插值表达式

和 v-bind 属性绑定

过滤器应该被添加在 JavaScript 表达式的尾部,由“管道符”进行调用,示例代码如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-idBqgvyC-1650958920169)(D:\A_study\Vue\study_image\b14.过滤器.png)]

1. 定义过滤器

在创建 vue 实例期间,可以在 filters 节点中定义过滤器,示例代码如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IFRsdluw-1650958920170)(D:\A_study\Vue\study_image\b15.定义过滤器.png)]

2. 私有过滤器和全局过滤器

在 filters 节点下定义的过滤器,称为“私有过滤器”,因为它只能在当前 vm 实例所控制的 el 区域内使用

如果希望在多个 vue 实例之间共享过滤器,则可以按照如下的格式定义全局过滤器

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9GdHFiwt-1650958920170)(D:\A_study\Vue\study_image\b16.全局过滤器.png)]

3. 连续调用多个过滤器

过滤器可以串联地进行调用,例如:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sKuBrvyt-1650958920171)(D:\A_study\Vue\study_image\b17.连续调用多个过滤器.png)]

4. 过滤器传参

过滤器的本质是 JavaScript 函数,因此可以接收参数,格式如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-g8LDfRJ4-1650958920171)(D:\A_study\Vue\study_image\b18.过滤器传参.png)]

5. 过滤器的兼容性

过滤器仅在 vue 2.x 和 1.x 中受支持,在 vue 3.x 的版本中剔除了过滤器相关的功能。

在企业级项目开发中:

  • 如果使用的是 2.x 版本的 vue,则依然可以使用过滤器相关的功能
  • 如果项目已经升级到了 3.x 版本的 vue,官方建议使用计算属性或方法代替被剔除的过滤器功能

具体的迁移指南,请参考 vue 3.x 的官方文档给出的说明:https://v3.vuejs.org/guide/migration/filters.html#migration-strategy

6. 注意点

过滤器的注意点

  1. 要定义到 filters 节点下,本质是一个函数
  2. 在过滤器函数中,一定要有 return 值
  3. 在过滤器的形参中,可以获取到“管道符”前面待处理的那个值
  4. 如果全局过滤器和私有过滤器名字一致,此时按照“就近原则”,调用的是”私有过滤器“

4. 侦听器 watch

4.1 什么是 watch 侦听器

watch 侦听器允许开发者监视数据的变化,从而针对数据的变化做特定的操作。

语法格式如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-29JcJTQg-1650958920172)(D:\A_study\Vue\study_image\b19.侦听器.png)]

4.2 immediate 选项

默认情况下,组件在初次加载完毕后不会调用 watch 侦听器。如果想让 watch 侦听器立即被调用,则需要使

用 immediate 选项。

watch: {
  // 定义对象格式的侦听器
  username: {
    handler(newVal, oldVal) {
      console.log(newVal, oldVal);
    },
    // 选项的默认值是 false,控制侦听器是否自动触发一次
    immediate: true
  }
}

4.3 deep 选项

如果 watch 侦听的是一个对象,如果对象中的属性值发生了变化,则无法被监听到。此时需要使用 deep 选

项,代码示例如下

watch: {
  // 定义对象格式的侦听器
  info: {
    handler(newVal) {
    	console.log(newVal.username);
    },
    // 开启深度监听,只要对象中任意属性变化了,都会出发侦听器
    deep: true
  }
}

4.4 侦听器两种形式的优缺点

  1. 方法格式的侦听器
    • 缺点1:无法在刚进入页面的时候,自动触发!!!
    • 缺点2:如果侦听的是一个对象,如果对象中的属性发生了变化,不会触发侦听器!!!
  2. 对象格式的侦听器
    • 好处1:可以通过 immediate 选项,让侦听器自动触发!!!
    • 好处2:可以通过 deep 选项,让侦听器深度监听对象中每个属性的变化!!!

4.5 监听对象单个属性的变化

如果只想监听对象中单个属性的变化,则可以按照如下的方式定义 watch 侦听器:

watch: {
  'info.username': {
      handler(newVal) {
          console.log(newVal);
      }
  }
}

5. 计算属性

5.1 什么是计算属性

所有计算属性,都放在computed 节点之下,计算属性在定义的时候,要定义成方法格式

计算属性指的是通过一系列运算之后,最终得到一个属性值。

这个动态计算出来的属性值可以被模板结构或 methods 方法使用。示例代码如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AdcTgtys-1650958920172)(D:\A_study\Vue\study_image\b20.计算属性.png)]

特点

  1. 定义的时候,要被定义为“方法”
  2. 在使用计算属性的时候,当普通的属性使用即可

好处

  1. 实现了代码的复用
  2. 只要计算属性中依赖的数据源变化了,则计算属性会自动重新求值!

6. axios

axios 是一个专注于网络请求的库!

axios 基础语法

 // 调用 axios 方法得到的返回值是 Promise 对象
        axios({
            methods: 'get',
            url: 'http://www.liulongbin.top:3006/api/getbooks',
     		
        }).then((books) => {
            console.log(books);
		})

6.1 发起GET请求

// 调用 axios 方法得到的返回值是 Promise 对象
        axios({
            methods: 'get',
            url: 'http://www.liulongbin.top:3006/api/getbooks',
     		// 调用 axios 方法得到的返回值是 Promise 对象
        axios({
            methods: 'get',
            url: 'http://www.liulongbin.top:3006/api/getbooks',
     		
        }).then((books) => {
            console.log(books);
		})
        }).then((books) => {
            console.log(books);
		})

6.2 发起POST请求

document.querySelector('#btnPost').addEventListener('click', async function() {
                // 如果调用某个方法的返回值是Promise实例,则前面可以添加 await
                // await 只能用在被 async “修饰” 的方法中
                await axios({
                    methods: 'POST',
                    url: 'http://www.liulongbin.top:3006/api/post',
                    // 请求体参数
                    data: {
                        address: '北京',
                        location: '顺义区'
                    }


                }).then((result) => {
                    console.log(result);
                })
            })

6.3 解构赋值

document.querySelector('#btnPost').addEventListener('click', async function() {
            // 解构赋值的时候,使用 : 进行重命名
            // 1. 调用axios 之后,使用 async/await 进行简化
            // 2. 使用解构赋值,从axios 封装的大对象中,把data 属性解构出来
            // 3. 把解构出来的的data属性,使用 冒号 进行重命名

            const { data: res } = await axios({
                methods: 'get',
                url: 'http://www.liulongbin.top:3006/api/getbooks',
                // URL中的查询参数
                params: {
                    id: 1
                },
                // 请求体参数
                data: {}
            })

            console.log(res.data);
        })

6.4 直接使用GET和POST请求

document.querySelector('#btnGET').addEventListener('click', async function() {
            const {
                data: result
            } = await axios.get('http://www.liulongbin.top:3006/api/getbooks')
            console.log(result.data);
        })

        document.querySelector('#btnPOST').addEventListener('click', async function() {
            const {
                data: res
            } = await axios.post('http://www.liulongbin.top:3006/api/post', {
                name: 'zs',
                gender: '女'
            })
            console.log(res);
        })

7. vue-cli

7.1 单页面应用程序

单页面应用程序简称 SPA,顾名思义,指的是一个 Web 网站中只有唯一的一个 HTML 页面,所有的功能与交互都在这唯一的一个页面内完成。

7.2 什么是 vue-cli

vue 实例的 $mount() 方法,作用和 el 属性 完全一致

vue-cli 是 Vue.js 开发的标准工具。它简化了程序员基于 webpack 创建工程化的 Vue 项目的过程。

引用自 vue-cli 官网上的一句话:程序员可以专注在撰写应用上,而不必花好几天去纠结 webpack 配置的问题。

中文官网:https://cli.vuejs.org/zh/

1. 安装和使用

vue-cli 是 npm 上的一个全局包,使用 npm install 命令,即可方便的把它安装到自己的电脑上:

npm install -g @vue/cli

基于 vue-cli 快速生成工程化的 Vue 项目:vue create 项目的名称

  1. 在终端下运行如下的命令,创建指定名称的项目:
vue cerate 项目的名称
  1. 安装过程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VCZZuPIX-1650958920174)(D:\A_study\Vue\study_image\b21.vue_create.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LnECWfv8-1650958920174)(D:\A_study\Vue\study_image\b21.vue_create2.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LyCsp0RM-1650958920175)(D:\A_study\Vue\study_image\b21.vue_create3.png)]

2. vue 项目的运行流程

在工程化的项目中,vue 要做的事情很单纯:通过 main.js 把 App.vue 渲染到 index.html 的指定区域中。

其中:

​ ① App.vue 用来编写待渲染的模板结构

​ ② index.html 中需要预留一个 el 区域

​ ③ main.js 把 App.vue 渲染到了 index.html 所预留的区域中

3. vue 项目中 src 目录的构成
  • assets 文件夹:存放项目中用到的静态资源文件,例如:css 样式表、图片资源
  • components 文件夹:程序员封装的、可复用的组件,都要放到 components 目录下
  • main.js 是项目的入口文件。整个项目的运行,要先执行 main.js
  • App.vue 是项目的根组件。

8. vue组件

8.1 什么是组件化开发

组件化开发指的是:根据封装的思想,把页面上可重用的 UI 结构封装为组件,从而方便项目的开发和维护。

8.2 vue 中的组件化开发

vue 是一个支持组件化开发的前端框架。

vue 中规定:组件的后缀名是 .vue。之前接触到的 App.vue 文件本质上就是一个 vue 的组件

8.3 vue 组件的三个组成部分

每个 .vue 组件都由 3 部分构成,分别是:

  • template -> 组件的模板结构
  • script -> 组件的 JavaScript 行为
  • style -> 组件的样式

其中,每个组件中必须包含 template 模板结构,而 script 行为和 style 样式是可选的组成部分

1. template

vue 规定:每个组件对应的模板结构,需要定义到 <template> 节点中

<template>
    <!-- 当前组件的DOM结构,需要定义到template 标签的内部 -->
</template>

注意:

  • template 是 vue 提供的容器标签,只起到包裹性质的作用,它不会被渲染为真正的 DOM 元素
  • template 中只能包含唯一的根节点
2. script

vue 规定:开发者可以在 <script> 节点中封装组件的 JavaScript 业务逻辑。

<script > 节点的基本结构如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1H4pbyDz-1650958920175)(D:\A_study\Vue\study_image\b22.png)]

.vue 组件中的 data 必须是函数

vue 规定:.vue 组件中的 data 必须是一个函数,不能直接指向一个数据对象。

<script>
export default {
    data() {
        return {
            username: 'zs'
        }
    },
    methods: {
        changeName() {
            // 在组件中,this 就表示当前组件的实例对象
            this.username = '娃哈哈'
            console.log(this);
        }
    },
    // 当前组件中的侦听器
    watch: {

    },
    // 当前组件中的计算属性
    computed: {

    },
    // 当前组件的过滤器
    filters: {

    }
}
</script>
3. style

vue 规定:组件内的 <style> 节点是可选的,开发者可以在<style>节点中编写样式美化当前组件的 UI 结构。

<script > 节点的基本结构如下:

<style>
h1 {
    background-color: pink;
}

</style>
1. 让 style 中支持 less 语法

<style> 标签上添加 lang=“less” 属性,即可使用 less 语法编写组件的样式:

<style lang="less">
h1 {
    background-color: pink;
}

</style>

8.4 组件之间的父子关系

  1. 组件在被封装好之后,彼此之间是相互独立的,不存在父子关系
  2. 在使用组件的时候,根据彼此的嵌套关系,形成了父子关系、兄弟关系
1. 使用组件的三个步骤

@:是内部配置,直接指向 ./src

步骤1:使用 import 语法导入需要的组件

步骤2:使用 components 节点注册组件

步骤3:以标签形式使用刚才注册的组件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7PYRpRXJ-1650958920176)(D:\A_study\Vue\study_image\b23.png)]

2. 通过 components 注册的是私有子组件

例如:

在组件 A 的 components 节点下,注册了组件 F。

则组件 F 只能用在组件 A 中;不能被用在组件 C 中。

3. 注册全局组件

在 vue 项目的 main.js 入口文件中,通过 Vue.component() 方法,可以注册全局组件。示例代码如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NBSEBrCY-1650958920177)(D:\A_study\Vue\study_image\b24.png)]

8.5 组件的 props

props 是组件的自定义属性,在封装通用组件的时候,合理地使用 props 可以极大的提高组件的复用性!

它的语法格式如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l9UX8ewc-1650958920178)(D:\A_study\Vue\study_image\b25.png)]

1. props 是只读的

vue 规定:组件中封装的自定义属性是只读的,程序员不能直接修改 props 的值。否则会直接报错

要想修改 props 的值,可以把 props 的值转存到 data 中,因为 data 中的数据都是可读可写的!

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-M9nciX65-1650958920179)(D:\A_study\Vue\study_image\b27.png)]

2. props 的 default 默认值

在声明自定义属性时,可以通过 default 来定义属性的默认值。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9kAyGcQE-1650958920179)(D:\A_study\Vue\study_image\b26.png)]

3. props 的 type 值类型

在声明自定义属性时,可以通过 type 来定义属性的值类型。示例代码如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XiPP3hAo-1650958920186)(D:\A_study\Vue\study_image\b28.png)]

4. props 的 required 必填项

在声明自定义属性时,可以通过 required 选项,将属性设置为必填项,强制用户必须传递属性的值。示例代

码如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2e9Ef8Yr-1650958920187)(D:\A_study\Vue\study_image\b29.png)]

8.6 组件之间的样式冲突问题

默认情况下,写在 .vue 组件中的样式会全局生效,因此很容易造成多个组件之间的样式冲突问题。

导致组件之间样式冲突的根本原因是:

​ ① 单页面应用程序中,所有组件的 DOM 结构,都是基于唯一的 index.html 页面进行呈现的

​ ② 每个组件中的样式,都会影响整个 index.html 页面中的 DOM 元素

1. 如何解决组件样式冲突的问题

为每个组件分配唯一的自定义属性,在编写组件样式时,通过属性选择器来控制样式的作用域,示例代码如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uejj2JO7-1650958920188)(D:\A_study\Vue\study_image\b30.png)]

2. style 节点的 scoped 属性

为了提高开发效率和开发体验,vue 为 style 节点提供了 scoped 属性,从而防止组件之间的样式冲突问题:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qoXfkkFq-1650958920188)(D:\A_study\Vue\study_image\b31.png)]

3. /deep/ 样式穿透

当时用第三方组件库的时候,如果有修改第三方组件默认样式需要用到 /deep/

如果给当前组件的 style 节点添加了 scoped 属性,则当前组件的样式对其子组件是不生效的。如果想让某些样

式对子组件生效,可以使用 /deep/ 深度选择器。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-E6g3uQ2G-1650958920189)(D:\A_study\Vue\study_image\b32.png)]

生命周期&数据共享

1. 组件的生命周期

1.1 生命周期 & 生命周期函数

  • 生命周期(Life Cycle)是指一个组件从创建 -> 运行 -> 销毁的整个阶段,强调的是一个时间段。
  • 生命周期函数:是由 vue 框架提供的内置函数,会伴随着组件的生命周期,自动按次序执行。
  • 注意:生命周期强调的是时间段,生命周期函数强调的是时间点

1.2 组件生命周期函数的分类

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bsrKI0do-1650958920190)(D:\A_study\Vue\study_image\c1.png)]

1.3 声明周期函数

1. 组件创建阶段

一个组件创建必能执行一次,仅能执行一次

  • beforeCreate() :初始化事件和声明周期函数,组件的prop/data/methods 尚未创建都处于不可用状态
  • created() :组件的prop/data/methods 可用,但是组件模块结构尚未生成 ,不能操作DOM
    • 很重要、常用,最早发起服务器请求
    • 经常在它里面调用 methoeds 中的方法,请求服务器的数据,并且把请求到的数据,转存到 data 中,供 template 模板渲染时候的使用
  • beforeMount() :将要把内存中编译好的 HTML 结构 渲染到浏览器中,此时浏览器中还没有当前组件 DOM 结构
  • mounted() :已经把内存中 HTML 结构,成功渲染到浏览器中,浏览器已包含当前 DOM 结构
    • 最早操作 DOM 元素
2. 组件运行阶段

里面的函数,最少执行 0 次,最多执行 无限次

  • beforeUpdate():将要根据变化后、最新的数据,重新渲染组件的模板结构
    • 页面还没来得及渲染,数据是新的,页面还是旧的
  • updated():已经根据最新的数据,完成了组件 DOM 结构的重新渲染
    • 数据是新的,页面也是新的
3. 组件销毁阶段
  • beforeDestroy():将要销毁此组件,但尚未销毁,组件还处于正常工作的状态
  • destroyed():组件已经被销毁,此组件在浏览器中对应的 DOM 结构已被完全移除

2. 组件之间的数据共享

2.1 组件之间的关系

在项目开发中,组件之间的最常见的关系分为如下两种:

​ ① 父子关系

​ ② 兄弟关系

2.2 父子组件之间的数据共享

父子组件之间的数据共享又分为:

​ ① 父 -> 子共享数据

​ ② 子 -> 父共享数据

1. 父组件向子组件共享数据

父组件向子组件共享数据需要使用自定义属性。示例代码如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9gCZAHe0-1650958920190)(D:\A_study\Vue\study_image\c2.png)]

2. 子组件向父组件共享数据

子组件向父组件共享数据使用自定义事件。示例代码如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mMpdVHmJ-1650958920191)(D:\A_study\Vue\study_image\c3.png)]

3. 兄弟组件之间的数据共享

在 vue2.x 中,兄弟组件之间数据共享的方案是 EventBus

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WjcTV06H-1650958920191)(D:\A_study\Vue\study_image\c4.png)]

4. EventBus 的使用步骤

① 创建 eventBus.js 模块,并向外共享一个 Vue 的实例对象

② 在数据发送方,调用 bus.$emit(‘事件名称’, 要发送的数据) 方法触发自定义事件

③ 在数据接收方,调用 bus.$on(‘事件名称’, 事件处理函数) 方法注册一个自定义事件

3. ref 引用

vue优势:MVVM,在vue中,程序员不需要操作DOM,只需要把数据维护好即可!(数据驱动视图)

结论:在vue中,不建议安装和使用jQuery

3.1 什么是 ref 引用

ref :用来辅助开发者在不依赖于 jQuery 的情况下,获取 DOM 元素或组件的引用。

每个 vue 的组件实例上,都包含一个 $refs 对象,里面存储着对应的 DOM 元素或组件的引用。默认情况下,

组件的 $refs 指向一个空对象

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K9nzH596-1650958920191)(D:\A_study\Vue\study_image\c5.png)]

3.2 使用 ref 引用 DOM 元素

如果想要使用 ref 引用页面上的 DOM 元素,则可以按照如下的方式进行操作:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EWSi1e10-1650958920192)(D:\A_study\Vue\study_image\c6.png)]

3.3 使用 ref 引用组件实例

如果想要使用 ref 引用页面上的组件实例,则可以按照如下的方式进行操作:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YyZfTJGj-1650958920193)(D:\A_study\Vue\study_image\c7.png)]

3.4 控制文本框和按钮的按需切换

通过布尔值 inputVisible 来控制组件中的文本框与按钮的按需切换。示例代码如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-me4Fo2tp-1650958920193)(D:\A_study\Vue\study_image\c8.png)]

3.5 让文本框自动获得焦点

当文本框展示出来之后,如果希望它立即获得焦点,则可以为其添加 ref 引用,并调用原生 DOM 对象的.focus() 方法即可。示例代码如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ITRWCOU4-1650958920194)(D:\A_study\Vue\study_image\C9.png)]

3.6 this.$nextTick(cb) 方法

组件的 $nextTick(cb) 方法,会把 cb 回调推迟到下一个 DOM 更新周期之后执行。通俗的理解是:等组件的

DOM 更新完成之后,再执行 cb 回调函数。从而能保证 cb 回调函数可以操作到最新的 DOM 元素

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0eUkrqaT-1650958920194)(D:\A_study\Vue\study_image\c10.png)]

3.7 数组的一些方法

1. some方法

因为foreach一旦开始就不能停止,所以需要用到some

arr.some((item,index) => {
  if(item === '某个值') {
    console.log(index)
   // 必须return true 才能终止
   return true
  }
})
2. every方法

判断是否所有的值都为true,则返回true,否则返回false

arr = [
  {id: 1,state: true},
  {id: 2,state: true},
  {id: 3,state: true},
]
const result = arr.every(item => item.state)	//result的结果是:true
3. reduce方法

reduce( (累加的结果, 当前循环项) => { },初始值 ),返回一个累加后结果

arr = [
  {id: 1,name: '西瓜',state: true,price: 10,count: 1},
  {id: 2,name: '榴莲',state: true,price: 80,count: 2},
  {id: 3,name: '草莓',state: true,price: 20,count: 3},
]

// 需求:把上述中,state为true 的水果的总价累加起来
// 普通方法
let amt=0
arr.filter(item => item.state).forEach(item => {
  amt += item.price * item.count
})
// reduce方法
const = result = arr.filter(item => item.state).reduce((amt,item) => {
  return amt += item.price * item.count
},0)

4. 总结

① 能够知道 vue 中常用的生命周期函数

  • 创建阶段、运行阶段、销毁阶段
  • created、mounted

② 能够知道如何实现组件之间的数据共享

  • 父 -> 子(自定义属性)
  • 子 -> 父(自定义事件)
  • 兄弟组件(EventBus)

③ 能够知道如何使用 ref 引用 DOM 元素或组件

  • 给元素或组件添加 ref=“xxx” 的引用名称
  • 通过 this.$refs.xxx 获取元素或组件的实例
  • $nextTick() 函数的执行时机

动态组件 & 插槽 & 自定义指令

1. 动态组件

1.1 概念

动态组件指的是动态切换组件的显示与隐藏。

1.2 如何实现动态组件渲染

vue 提供了一个内置的 <component> 组件,专门用来实现动态组件的渲染。示例代码如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AZbjxOxc-1650958920194)(D:\A_study\Vue\study_image\d1.png)]

1.3 使用 keep-alive 保持状态

默认情况下,切换动态组件时无法保持组件的状态。此时可以使用 vue 内置的 <keep-alive> 组件保持动态组

件的状态。示例代码如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZizxDQ3g-1650958920195)(D:\A_study\Vue\study_image\d2.png)]

1.4 keep-alive 对应的生命周期函数

当组件第一次被创建的时候,既会执行created 声明周期函数,也会执行 activated 生命周期函数

当组件别激活时,只会执行 activated 生命周期函数

  • 当组件被缓存时,会自动触发组件的 deactivated 生命周期函数。
  • 当组件被激活时,会自动触发组件的 activated 生命周期函数。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6Ovj8amj-1650958920196)(D:\A_study\Vue\study_image\d3.png)]

1.5 keep-alive 的 include 属性

在使用keep-alive 的时候,可以通过 include 指定那些组件需要被缓存。或者,通过exclude 属性指定那个组件不需要被缓存,但是不要同时使用 include 和 exclude 这两个属性

include 属性用来指定:只有名称匹配的组件会被缓存。多个组件名之间使用英文的逗号分隔

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3CqwWq43-1650958920196)(D:\A_study\Vue\study_image\d4.png)]

  • 组件的“注册名称”的主要应用场景是:以标签的形式,把注册的组件,渲染和使用到页面结构之中
  • 组件声明时候的“name“ 名称主要应用场景,结合 keep-alive 标签实现组件缓存功能,以及在调试工具中看到的组件的 name 名称,name名称首字母应大写

2. 插槽

2.1 什么是插槽

插槽(Slot)是 vue 为组件的封装者提供的能力。允许开发者在封装组件时,把不确定的、希望由用户指定的部分定义为插槽。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wqzmK0Wa-1650958920197)(D:\A_study\Vue\study_image\d5.png)]

可以把插槽认为是组件封装期间,为用户预留的内容的占位符。

2.2 体验插槽的基础用法

vue 官方规定:每一个 slot 插槽,都有一个 name 名称

如果省略了 slot 的 name 属性,则有一个默认名称叫做 default

默认情况下,在使用组件的时候,提供的内容都会被填充到名字为 default 的插槽中

在封装组件时,可以通过 <slot> 元素定义插槽,从而为用户预留内容占位符。示例代码如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LAOBYum6-1650958920197)(D:\A_study\Vue\study_image\d6.png)]

1. 没有预留插槽的内容会被丢弃

如果在封装组件时没有预留任何 <slot> 插槽,则用户提供的任何自定义内容都会被丢弃。示例代码如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ux5zLQO3-1650958920198)(D:\A_study\Vue\study_image\d7.png)]

2. 后备内容

里面存放插槽的后背内容,当用户没有指定插槽内容时使用

封装组件时,可以为预留的 <slot> 插槽提供后备内容(默认内容)。如果组件的使用者没有为插槽提供任何内容,则后备内容会生效。示例代码如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B2KHZn23-1650958920198)(D:\A_study\Vue\study_image\d8.png)]

2.3 具名插槽

tempalte 这个标签,它是一个虚拟的标签,只祈祷包裹性质的作用,但是,不会渲染为任何实质性的 html 元素

如果在封装组件时需要预留多个插槽节点,则需要为每个 <slot> 插槽指定具体的 name 名称。这种带有具体名称的插槽叫做“具名插槽”。示例代码如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Bu0pjNUv-1650958920199)(D:\A_study\Vue\study_image\d9.png)]

注意:没有指定 name 名称的插槽,会有隐含的名称叫做 “default”。

1. 为具名插槽提供内容

v-slot:只能放在template 或者 components 中,放在元素内会报错

在向具名插槽提供内容的时候,我们可以在一个 <template> 元素上使用 v-slot 指令,并以 v-slot 的参数的形式提供其名称。示例代码如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eRXOgrlL-1650958920199)(D:\A_study\Vue\study_image\d10.png)]

2. 具名插槽的简写形式

插槽属性 v-slot ,简写为 #

跟 v-on 和 v-bind 一样,v-slot 也有缩写,即把参数之前的所有内容 (v-slot:) 替换为字符 #。例如 v-slot:header可以被重写为#header:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LWeGnJuZ-1650958920200)(D:\A_study\Vue\study_image\d11.png)]

2.4 作用域插槽

在封装组件的过程中,可以为预留的 <slot> 插槽绑定 props 数据,这种带有 props 数据的 <slot> 叫做“作用域插槽”。示例代码如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kwUK2yaT-1650958920200)(D:\A_study\Vue\study_image\d12.png)]

1. 使用作用域插槽

可以使用 v-slot: 的形式,接收作用域插槽对外提供的数据。示例代码如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0MTuX8DI-1650958920201)(D:\A_study\Vue\study_image\d13.png)]

2. 解构插槽 Prop

作用域插槽对外提供的数据对象,可以使用解构赋值简化数据的接收过程。示例代码如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AIwTK95P-1650958920201)(D:\A_study\Vue\study_image\d14.png)]

3. 自定义指令

3.1 什么是自定义指令

vue 官方提供了 v-text、v-for、v-model、v-if 等常用的指令。除此之外 vue 还允许开发者自定义指令。

3.2 自定义指令的分类

vue 中的自定义指令分为两类,分别是:

  • 私有自定义指令
  • 全局自定义指令

3.3 私有自定义指令

在每个 vue 组件中,可以在 directives 节点下声明私有自定义指令。示例代码如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-s8x4tHkU-1650958920201)(D:\A_study\Vue\study_image\d15.png)]

3.4 使用自定义指令

在使用自定义指令时,需要加上 v- 前缀。示例代码如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7Dw4A965-1650958920202)(D:\A_study\Vue\study_image\d16.png)]

3.5 为自定义指令动态绑定参数值

在 template 结构中使用自定义指令时,可以通过等号(

=)的方式,为当前指令动态绑定参数值:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sgAk5cDQ-1650958920202)(D:\A_study\Vue\study_image\d17.png)]

3.6 通过 binding 获取指令的参数值

在声明自定义指令时,可以通过形参中的第二个参数,来接收指令的参数值:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i9LVmkUW-1650958920203)(D:\A_study\Vue\study_image\d18.png)]

3.7 update 函数

bind 函数只调用 1 次:当指令第一次绑定到元素时调用,当 DOM 更新时 bind 函数不会被触发。 update 函

数会在每次 DOM 更新时被调用。示例代码如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cMySNem0-1650958920203)(D:\A_study\Vue\study_image\d19.png)]

3.8 函数简写

如果 insert 和update 函数中的逻辑完全相同,则对象格式的自定义指令可以简写成函数格式:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aaXPHB0a-1650958920204)(D:\A_study\Vue\study_image\d20.png)]

3.9 全局自定义指令

全局共享的自定义指令需要通过“Vue.directive()”进行声明,示例代码如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zNztB1UO-1650958920204)(D:\A_study\Vue\study_image\d21.png)]

4. 总结

① 能够掌握 keep-alive 元素的基本使用

  • <keep-alive> 标签、include 属性

② 能够掌握插槽的基本用

  • <slot> 标签、具名插槽、作用域插槽、后备内容

③ 能够知道如何自定义指令

  • 私有自定义指令 directives: { }
  • 全局自定义指令 Vue.directive()

路由

1. ESLint

可组装的JavaScript 和 JSX 检查工具

用来约定代码风格

创建项目选择 ESLint

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-To5rtShL-1650958920205)(D:\A_study\Vue\study_image\e1.png)]

1.1 了解 ESLint 常见的语法规则

ESLint 提供了许多校验代码格式的语法规则,常见的语法规则列表如下:

序号规则名称规则约束/默认约束
1quotes默认:字符串需要使用单引号包裹
2key-spacing默认:对象的属性和值之间,需要有一个空格分割
3comma-dangle默认:对象或数组的末尾,不允许出现多余的逗号
4no-multiple-empty-lines不允许出现多个空行
5no-trailing-spaces不允许在行尾出现多余的空格
6eol-last默认:文件的末尾必须保留一个空行
7spaced-comment在注释中的///*后强制使用一致的间距
8indent强制一致的缩进
9import/firstimport 导入模块的语句必须声明在文件的顶部
10space-before-function-paren方法的形参之前是否需要保留一个空格

详细的 ESLint 语法规则列表,请参考官方文档 、https://eslint.org/docs/rules/

1.1 下载插件

  • ESLint
  • Prettler -code formatter

配置文件

// ESLint 开启编译器保存自动格式化功能
    "editor.codeActionsOnSave": {
        "source.fixAll": true
    },
    // prettier-code format 配置
    "prettier.configPath": "C:\\Users\\龙槑\\.prettierrc",
    "eslint.alwaysShowStatus": true,
    "prettier.trailingComma": "none",
    "prettier.semi": false,
    // 每行文字个数超出此限制将会被迫换行
    "prettier.printWidth": 300,
    // 使用单引号替换双引号
    "prettier.singleQuote": true,
    "prettier.arrowParens": "avoid",
    // 设置 .vue 文件中,HTML代码的格式化插件
    "vetur.format.defaultFormatter.html": "js-beautify-html",
    "vetur.ignoreProjectWarning": true,
    "vetur.format.defaultFormatterOptions": {
        "prettier": {
            "semi": false, //不在语句结尾处加分号
            "singleQuote": true,
            "trailingComma": "none", //禁止随时添加逗号
            "arrowParens": "avoid",
            "printWidth": 300
        },
        "js-beautify-html": {
            "wrap_attributes": "auto"
        }
    },

2. axios优化

全局挂载axios

import axios from 'axios'

// 全局配置 axios 的请求路径
axios.defaults.baseURL = 'http://www.liulongbin.top:3006'
// 把 axios 挂载到 Vue.prototype上,供每个 .vue组件实例直接使用
Vue.prototype.$http = axios
// 今后,在每个 .vue 组件要发起请求,直接调用 this.$http.xxx

好处:直接在全局组件中this.%http 就可以发起axios 请求

缺点:不利于 axios 的复用

3. 前端路由的概念与原理

3.1 什么是路由

路由(英文:router)就是对应关系。

3.2 SPA 与前端路由

SPA 指的是一个 web 网站只有唯一的一个 HTML 页面,所有组件的展示与切换都在这唯一的一个页面内完成。此时,不同组件之间的切换需要通过前端路由来实现

结论:在 SPA 项目中,不同功能之间的切换,要依赖于前端路由来完成!

3.3 什么是前端路由

通俗易懂的概念:Hash 地址与组件之间的对应关系。

3.4 前端路由的工作方式

① 用户点击了页面上的路由链接

② 导致了 URL 地址栏中的 Hash 值发生了变化

③ 前端路由监听了到 Hash 地址的变化

④ 前端路由把当前 Hash 地址对应的组件渲染都浏览器中

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Dt2EuR34-1650958920205)(D:\A_study\Vue\study_image\e2.png)]

结论:前端路由,指的是 Hash 地址与组件之间的对应关系!

3.5 实现简易的前端路由

1. 步骤1

步骤1:通过 <component> 标签,结合 comName 动态渲染组件。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gwU1guKC-1650958920206)(D:\A_study\Vue\study_image\e3.png)]

2. 步骤2

步骤2:在 App.vue 组件中,为 <a> 链接添加对应的 hash 值:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-W6mQ5StO-1650958920206)(D:\A_study\Vue\study_image\e4.png)]

3. 步骤3

只要当前 App 组件已被创建,就立即监听 window对象的 onhashchange 事件

步骤3:在 created 生命周期函数中,监听浏览器地址栏中 hash 地址的变化,动态切换要展示的组件的名称:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ztla0Sud-1650958920207)(D:\A_study\Vue\study_image\e5.png)]

4. vue-router 的基本用法

4.1 什么是 vue-router

vue-router 是 vue.js 官方给出的路由解决方案。它只能结合 vue 项目进行使用,能够轻松的管理 SPA 项目

中组件的切换。

vue-router 的官方文档地址:https://router.vuejs.org/zh/

4.2 vue-router 安装和配置的步骤

① 安装 vue-router 包

② 创建路由模块

③ 导入并挂载路由模块

④ 声明路由链接和占位符

1. 在项目中安装 vue-router

在 vue2 的项目中,安装 vue-router 的命令如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iAidObG5-1650958920207)(D:\A_study\Vue\study_image\e6.png)]

2. 创建路由模块

在 src 源代码目录下,新建 router/index.js 路由模块,并初始化如下的代码

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-E8YMBtig-1650958920208)(D:\A_study\Vue\study_image\e7.png)]

// src/router/index.js 就是当前路由模块
import Vue from 'vue'
import VueRouter from 'vue-router'

// 把VueRouter 安装为 vue 项目的插件
Vue.use(VueRouter)

// 创建路由的实例对象
const router = new VueRouter()

export default router
3. 导入并挂载路由模块

在 src/main.js 入口文件中,导入并挂载路由模块。示例代码如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yVOVUiWH-1650958920208)(D:\A_study\Vue\study_image\e8.png)]

import Vue from 'vue'
import router from '@/router/index.js'

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
  // 在vue 项目中,要把路由用起来,必须把路由实例对象,通过下面的方法进行挂载
  // router: 路由的实例对象
  router
}).$mount('#app')

4. 声明路由链接和占位符

在 src/App.vue 组件中,使用 vue-router 提供的 和 <router-view> 声明路由链接和占位符:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-16OSr1Q3-1650958920209)(D:\A_study\Vue\study_image\e9.png)]

5. vue-router 的常见用法

5.1 路由重定向

路由重定向指的是:用户在访问地址 A 的时候,强制用户跳转到地址 C ,从而展示特定的组件页面。

通过路由规则的 redirect 属性,指定一个新的路由地址,可以很方便地设置路由的重定向:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rOUx6rgM-1650958920209)(D:\A_study\Vue\study_image\e10.png)]

Vue.use(VueRouter)

const router = new VueRouter({
  // routes 是一个数组,作用:定义“hash”地址与“组件”的对应关系
  routes: [
    // 重定向路由规则
    { path: '/', redirect: '/Home' },
    // 路由规则
    { path: '/home', component: Home },
    { path: '/movie', component: Movie },
    { path: '/about', component: About },
  ]
})

5.2 嵌套路由

通过路由实现组件的嵌套展示,叫做嵌套路由。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rlf58fWY-1650958920210)(D:\A_study\Vue\study_image\e11.png)]

5.3 子路由声明

默认子路由:如果 children 数字中,某个路由规则的 path 值为空字符串,则这条路由规则,叫做 “默认子路由”

1. 声明子路由链接和子路由占位符

当安装和配置了 vue-router 后,就可以使用 router-link 来代替普通的 a 链接

在 About.vue 组件中,声明 tab1 和 tab2 的子路由链接以及子路由占位符。示例代码如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5uD1iy8x-1650958920210)(D:\A_study\Vue\study_image\e12.png)]

2. 通过 children 属性声明子路由规则

在 src/router/index.js 路由模块中,导入需要的组件,并使用 children 属性声明子路由规则:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oAB4g6uK-1650958920211)(D:\A_study\Vue\study_image\e13.png)]

5.4 动态路由匹配

拓展

  • 注意:在 hash 地址中, / 后面的参数项,叫做 “路径参数”
    • 路由 “参数对象” 中,需要使用 this.$route.params 来访问路径参数
  • 注意2: 在 hash 地址中,? 后面的参数项 叫做 “查询参数”
    • 在路由 “参数对象” 中,需要使用 this.$rote.query 来访问 查询参数
  • 注意3:在 this.$route 中,path 知识路径部分;fullPath 是完整的地址
1. 动态路由的概念

动态路由指的是:把 Hash 地址中可变的部分定义为参数项从而提高路由规则的复用性

在 vue-router 中使用英文的冒号 : 来定义路由的参数项。示例代码如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OBG7m1VO-1650958920211)(D:\A_study\Vue\study_image\e14.png)]

2. $route.params 参数对象

在动态路由渲染出来的组件中,可以使用 this.$route.params 对象访问到动态匹配的参数值

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1MOCVgKo-1650958920211)(D:\A_study\Vue\study_image\e15.png)]

3 使用 props 接收路由参数

为了简化路由参数的获取形式,vue-router 允许在路由规则中开启 props 传参。示例代码如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BGCzm5Du-1650958920212)(D:\A_study\Vue\study_image\e16.png)]

5.5 声明式导航 & 编程式导航

  • 在浏览器中,点击链接实现导航的方式,叫做声明式导航。例如:
    • 普通网页中点击 <a> 链接、vue 项目中点击 <router-link> 都属于声明式导航
  • 在浏览器中,调用 API 方法实现导航的方式,叫做编程式导航。例如:
    • 普通网页中调用 location.href 跳转到新页面的方式,属于编程式导航
1. vue-router 中的编程式导航 API

vue-router 提供了许多编程式导航的 API,其中最常用的导航 API 分别是:

① this.$router.push(‘hash 地址’)

  • 跳转到指定 hash 地址,并增加一条历史记录

② this.$router.replace(‘hash 地址’)

  • 跳转到指定的 hash 地址,并替换掉当前的历史记录

③ this.$router.go(数值 n)

  • 实现导航历史前进、后退
2. $router.push

调用 this.$router.push() 方法,可以跳转到指定的 hash 地址,从而展示对应的组件页面。示例代码如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NqiQA1Zh-1650958920212)(D:\A_study\Vue\study_image\e17.png)]

3. $router.replace

调用 this.$router.replace() 方法,可以跳转到指定的 hash 地址,从而展示对应的组件页面。

push 和 replace 的区别:

  • push 会增加一条历史记录
  • replace 不会增加历史记录,而是替换掉当前的历史记录
4. $router.go

如果超过了限制,则原地不动

调用 this.$router.go() 方法,可以在浏览历史中前进和后退。示例代码如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QbSAfnmn-1650958920213)(D:\A_study\Vue\study_image\e18.png)]

5. $router.go 的简化用法

在实际开发中,一般只会前进和后退一层页面。因此 vue-router 提供了如下两个便捷方法:

① $router.back()

  • 在历史记录中,后退到上一个页面

② $router.forward()

  • 在历史记录中,前进到下一个页面

5.6 导航守卫

导航守卫可以控制路由的访问权限。示意图如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ObmTOnOl-1650958920214)(D:\A_study\Vue\study_image\e19.png)]

1. 全局前置守卫

只要发生了路由的跳转,必然会触发 beforeEach 指定的 function 回调函数

每次发生路由的导航跳转时,都会触发全局前置守卫。因此,在全局前置守卫中,程序员可以对每个路由进行访问权限的控制:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-H5yS37Pw-1650958920214)(D:\A_study\Vue\study_image\e20.png)]

2. 守卫方法的 3 个形参

全局前置守卫的回调函数中接收 3 个形参,格式为:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EqzgNXbC-1650958920214)(D:\A_study\Vue\study_image\e21.png)]

3. next 函数的 3 种调用方式

参考示意图,分析 next 函数的 3 种调用方式最终导致的结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-E2uST8tU-1650958920215)(D:\A_study\Vue\study_image\e22.png)]

  • 当前用户拥有后台主页的访问权限,直接放行:next()
  • 当前用户没有后台主页的访问权限,强制其跳转到登录页面:next(‘/login’)
  • 当前用户没有后台主页的访问权限,不允许跳转到后台主页:next(false)
4. 控制后台主页的访问权限

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Pg6J8kN1-1650958920215)(D:\A_study\Vue\study_image\e23.png)]

6. 总结

① 能够知道如何在 vue 中配置路由

  • createRouter、app.use(router)

② 能够知道如何使用嵌套路由

  • 通过 children 属性进行路由嵌套

③ 能够知道如何实现动态路由匹配

  • 使用冒号声明参数项、this.$route.params、props: true

④ 能够知道如何使用编程式导航

  • this. r o u t e r . p u s h 、 t h i s . router.push、this. router.pushthis.router.go

⑤ 能够知道如何使用导航守卫

  • 路由实例.beforeEach((to, from, next) => { /* 必须调 next 函数 */ })

7. 案例

7.1 导入vant 模块

官网

  • 先下载 vant 模块
# Vue 3 项目,安装最新版 Vant
npm i vant

# Vue 2 项目,安装 Vant 2
npm i vant@latest-v2
  • 引入
import Vant from 'vant'
import 'vant/lib/index.css'
Vue.use(Vant)

7.2 封装axios

  • 封装request.js 模块
// 封装request.js 模块

import axios from 'axios'
const 小axios1 = 大axios.create({
  baseURL: 'http://api.taobao.com'
})

7.3 封装 articleAPI

import request from '@/utils/request.js'

export const getArticleListAPI = function(_page, _limit) {
  return request.get('/articles', {
    // 请求参数
    params: {
      _page,
      _limit
    }
  })
}
  • 引用
import { getArticleListAPI } from '@/API/articleAPI.js'

async initArticleList() {
      // 发起GET 请求,获取文章的列表数据
      const { data: res } = await getArticleListAPI(this.pages, this.limit)

      console.log(res)
}

50958920212)]

3. $router.replace

调用 this.$router.replace() 方法,可以跳转到指定的 hash 地址,从而展示对应的组件页面。

push 和 replace 的区别:

  • push 会增加一条历史记录
  • replace 不会增加历史记录,而是替换掉当前的历史记录
4. $router.go

如果超过了限制,则原地不动

调用 this.$router.go() 方法,可以在浏览历史中前进和后退。示例代码如下:

[外链图片转存中…(img-QbSAfnmn-1650958920213)]

5. $router.go 的简化用法

在实际开发中,一般只会前进和后退一层页面。因此 vue-router 提供了如下两个便捷方法:

① $router.back()

  • 在历史记录中,后退到上一个页面

② $router.forward()

  • 在历史记录中,前进到下一个页面

5.6 导航守卫

导航守卫可以控制路由的访问权限。示意图如下:

[外链图片转存中…(img-ObmTOnOl-1650958920214)]

1. 全局前置守卫

只要发生了路由的跳转,必然会触发 beforeEach 指定的 function 回调函数

每次发生路由的导航跳转时,都会触发全局前置守卫。因此,在全局前置守卫中,程序员可以对每个路由进行访问权限的控制:

[外链图片转存中…(img-H5yS37Pw-1650958920214)]

2. 守卫方法的 3 个形参

全局前置守卫的回调函数中接收 3 个形参,格式为:

[外链图片转存中…(img-EqzgNXbC-1650958920214)]

3. next 函数的 3 种调用方式

参考示意图,分析 next 函数的 3 种调用方式最终导致的结果:

[外链图片转存中…(img-E2uST8tU-1650958920215)]

  • 当前用户拥有后台主页的访问权限,直接放行:next()
  • 当前用户没有后台主页的访问权限,强制其跳转到登录页面:next(‘/login’)
  • 当前用户没有后台主页的访问权限,不允许跳转到后台主页:next(false)
4. 控制后台主页的访问权限

[外链图片转存中…(img-Pg6J8kN1-1650958920215)]

6. 总结

① 能够知道如何在 vue 中配置路由

  • createRouter、app.use(router)

② 能够知道如何使用嵌套路由

  • 通过 children 属性进行路由嵌套

③ 能够知道如何实现动态路由匹配

  • 使用冒号声明参数项、this.$route.params、props: true

④ 能够知道如何使用编程式导航

  • this. r o u t e r . p u s h 、 t h i s . router.push、this. router.pushthis.router.go

⑤ 能够知道如何使用导航守卫

  • 路由实例.beforeEach((to, from, next) => { /* 必须调 next 函数 */ })

7. 案例

7.1 导入vant 模块

官网

  • 先下载 vant 模块
# Vue 3 项目,安装最新版 Vant
npm i vant

# Vue 2 项目,安装 Vant 2
npm i vant@latest-v2
  • 引入
import Vant from 'vant'
import 'vant/lib/index.css'
Vue.use(Vant)

7.2 封装axios

  • 封装request.js 模块
// 封装request.js 模块

import axios from 'axios'
const 小axios1 = 大axios.create({
  baseURL: 'http://api.taobao.com'
})

7.3 封装 articleAPI

import request from '@/utils/request.js'

export const getArticleListAPI = function(_page, _limit) {
  return request.get('/articles', {
    // 请求参数
    params: {
      _page,
      _limit
    }
  })
}
  • 引用
import { getArticleListAPI } from '@/API/articleAPI.js'

async initArticleList() {
      // 发起GET 请求,获取文章的列表数据
      const { data: res } = await getArticleListAPI(this.pages, this.limit)

      console.log(res)
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值