- VUE基础入门
- vue 简介
1.1构建用户界面
前端开发者最主要的工作,就是为网站的使用者(又称为:网站的用户)构建出美观、舒适、好用的网页。
1.1构建用户界面的传统方式
在传统的 Web 前端开发中,是基于jQuery + 模板引擎 的方式来构建用户界面的。
1.1.2使用 vue 构建用户界面
使用 vue 构建用户界面,解决了 jQuery + 模板引擎 的诸多痛点,极大的提高了前端开发的效率和体验。
- 编写结构:基于 vue 中提供的指令,可以方便快捷的渲染页面的结构。
- 美化样式:基础 CSS 样式,美化网页的可视化效果。
- 处理交互:基于 vue 中提供的事件绑定,可以轻松处理用户和页面之间的交互行为。
vue 的定位是前端框架,提供构建用户界面的整套解决方案(俗称 vue 全家桶):
- vue(核心库)
- vue-router(路由方案)
- vuex(状态管理方案)
- vue 组件库(快速搭建页面UI 效果的方案)
? vue-cli(npm 全局包:一键生成工程化的 vue 项目-基于 webpack、大而全)
? vite(npm 全局包:一键生成工程化的 vue 项目 - 小而巧)
? vue-devtools(浏览器插件:辅助调试的工具)
? vetur(vscode 插件:提供语法高亮和智能提示)
1.3 vue 的特性
vue 框架的特性,主要体现在如下两方面:
- 数据驱动视图② 双向数据绑定
在使用vue 的页面中,vue 会监听数据的变化,从而自动重新渲染页面的结构。
好处:当页面数据发生变化时,页面会自动重新渲染!
注意:数据驱动视图是单向的数据绑定。
1.3.2 双向数据绑定
在填写表单时,双向数据绑定可以辅助开发者在不操作 DOM 的前提下,自动把用户填写的内容同步到数据源中。
1.3.3 MVVM
MVVM 是 vue 实现数据驱动视图和双向数据绑定的核心原理。它把每个 HTML 页面都拆分成了如下三个部分:
View 表示当前页面所渲染的 DOM 结构。
Model 表示当前页面渲染时所依赖的数据源。
ViewModel 表示 vue 的实例,它是 MVVM 的核心。
(1)MVVM 的工作原理
ViewModel 作为 MVVM 的核心,是它把当前页面的数据源(Model)和页面的结构(View)连接在了一起。
当数据源发生变化时,会被 ViewModel 监听到,VM 会根据最新的数据源自动更新页面的结构
当表单元素的值发生变化时,也会被 VM 监听到,VM 会把变化过后最新的值自动同步到Model 数据源中
1.4 vue3.x 和 vue2.x 版本的对比
vue2.x 中绝大多数的 API 与特性,在 vue3.x 中同样支持。同时,vue3.x 中还新增了 3.x 所特有的功能、并废弃了某些 2.x 中的旧功能。
新增的功能例如:
组合式 API、多根节点组件、更好的 TypeScript 支持等
废弃的旧功能如下:
过滤器、不再支持 $on,$off 和 $once 实例方法等
详细的变更信息,请参考官方文档给出的迁移指南:
Vue.js - The Progressive JavaScript Framework | Vue.js
- vue 的基本使用
① 导入 vue.js 的 script 脚本文件
② 在页面中声明一个将要被 vue 所控制的 DOM 区域
③ 创建 vm 实例对象(vue 实例对象)
2.1 基本代码与 MVVM 的对应关系
{{username}}
- vue 的调试工具
vue 官方提供的 vue-devtools 调试工具,能够方便开发者对 vue 项目进行调试与开发。
Chrome 浏览器在线安装 vue-devtools
vue 2.x 调试工具:
https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd
vue 3.x 调试工具:
https://chrome.google.com/webstore/detail/vuejs-devtools/ljjemllljcmogpfapbkkighbhhppjdbg
注意:vue2 和 vue3 的浏览器调试工具不能交叉使用!
3.2配置 Chrome 浏览器中的 vue-devtools
点击 Chrome 浏览器右上角的 按钮,选择更多工具-> 扩展程序 -> Vue.js devtools 详细信息,并勾选相关选项。
3.3使用 vue-devtools 调试 vue 页面
在浏览器中访问一个使用了 vue 的页面,打开浏览器的开发者工具,切换到 Vue 面板,即可使用 vue-devtools调试当前的页面。
- vue 的指令与过滤器
指令(Directives)是 vue 为开发者提供的模板语法,用于辅助开发者渲染页面的基本结构。
vue 中的指令按照不同的用途可以分为如下 6 大类:
① 内容渲染指令
② 属性绑定指令
③ 事件绑定指令
④ 双向绑定指令
⑤ 条件渲染指令
⑥ 列表渲染指令
4.2常用指令
4.2.1 内容渲染指令
内容渲染指令用来辅助开发者渲染 DOM 元素的文本内容。常用的内容渲染指令有如下 3 个:
- v-text
- {{ }} 插值表达式 Mustache
- v-html
如果需要为元素的属性动态绑定属性值,则需要用到 v-bind 属性绑定指令。
由于 v-bind 指令在开发中使用频率非常高,因此,vue 官方为其提供了简写形式(简写为英文的 : )。
4.2.3使用 Javascript 表达式
在 vue 提供的模板渲染语法中,除了支持绑定简单的数据值之外,还支持Javascript 表达式的运算.
4.2.4事件绑定指令
vue 提供了 v-on 事件绑定指令,用来辅助程序员为 DOM 元素绑定事件监听。语法格式如下:
v-on:事件名称=”事件处理函数得名称”
注意:原生 DOM 对象有 onclick、oninput、onkeyup 等原生事件,替换为 vue 的事件绑定形式后,分别为:v-on:click、v-on:input、v-on:keyup
通过 v-on 绑定的事件处理函数,需要在 methods 节点中进行声明.
由于 v-on 指令在开发中使用频率非常高,因此,vue 官方为其提供了简写形式(简写为英文的 @ )
1、事件对象 event
(1)在原生的 DOM 事件绑定中,可以在事件处理函数的形参处,接收事件对象event。同理,在 v-on 指令(简写为 @ )所绑定的事件处理函数中,同样可以接收到事件对象 event。
(2)在使用 v-on 指令绑定事件时,可以使用 ( ) 进行传参。
(3)$event 是 vue 提供的特殊变量,用来表示原生的事件参数对象 event。$event 可以解决事件参数对象event被覆盖的问题。
2、事件修饰符
在事件处理函数中调用preventDefault() 或 stopPropagation() 是非常常见的需求。因此,vue 提供了事件修饰符的概念,来辅助程序员更方便的对事件的触发进行控制。
3、按键修饰符
在监听键盘事件时,我们经常需要判断详细的按键。此时,可以为键盘相关的事件添加按键修饰符。
4.2.5双向绑定指令
vue 提供了 v-model 双向数据绑定指令,用来辅助开发者在不操作 DOM 的前提下,快速获取表单的数据。
注意:v-model 指令只能配合表单元素一起使用!
(1)v-model 指令的修饰符
为了方便对用户输入的内容进行处理,vue 为 v-model 指令提供了 3 个修饰符
.lazy即指在鼠标失去焦点的时候更新
4.2.6条件渲染指令
条件渲染指令用来辅助开发者按需控制 DOM 的显示与隐藏。条件渲染指令有如下两个,分别是:
- v-if
- v-show
(1)实现原理不同:
- v-if 指令会动态地创建或移除DOM 元素,从而控制元素在页面上的显示与隐藏;
- v-show 指令会动态为元素添加或移除 style="display: none; " 样式,从而控制元素的显示与隐藏;
v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。
- 如果需要非常频繁地切换,则使用 v-show 较好
- 如果在运行时条件很少改变,则使用 v-if 较好
vue 提供了 v-for 指令,用来辅助开发者基于一个数组来循环渲染相似的UI 结构。v-for 指令需要使用 item in items 的特殊语法,其中:
- items 是待循环的数组
- item 是当前的循环项
v-for 指令还支持一个可选的第二个参数,即当前项的索引。语法格式为 (item, index) in items
注意:v-for 指令中的 item 和 index 索引都是形参,可以根据需要进行重命名。
4.2.8使用 key 维护列表的状态
当列表的数据变化时,默认情况下,vue 会尽可能的复用已存在的DOM 元素,从而提升渲染的性能。但这种默认的性能优化策略,会导致有状态的列表无法被正确更新。
为了给 vue 一个提示,以便它能跟踪每个节点的身份,从而在保证有状态的列表被正确更新的前提下,提升渲染的性能。此时,需要为每项提供一个唯一的 key 属性。
注意:
① key 的值只能是字符串或数字类型
② key 的值必须具有唯一性(即:key 的值不能重复)
③ 建议把数据项 id 属性的值作为 key 的值(因为 id 属性的值具有唯一性)
④ 使用 index 的值当作 key 的值没有任何意义(因为index 的值不具有唯一性)
⑤ 建议使用 v-for 指令时一定要指定 key 的值(既提升性能、又防止列表状态紊乱)
4.3过滤器
过滤器(Filters)常用于文本的格式化。例如:hello -> Hello过滤器应该被添加在 JavaScript 表达式的尾部,由“管道符”进行调用。
过滤器可以用在两个地方:插值表达式和v-bind 属性绑定。
4.3.1定义过滤器
在创建 vue 实例期间,可以在 filters 节点中定义过滤器,示例代码如下:
const vm = new Vue({
el: '#app',
data: {
message: 'hello vue.js',
info: 'title info',
},
filters: {
capitalize(str) {
return str.charAt(0).toUpperCase() + str.slice(1)
}
}
})
4.3.2私有过滤器和全局过滤器
在 filters 节点下定义的过滤器,称为“私有过滤器”,因为它只能在当前vm 实例所控制的 el 区域内使用。如果希望在多个 vue 实例之间共享过滤器,则可以按照如下的格式定义全局过滤器:
注意:要在创建 Vue 实例之前全局定义过滤器
过滤器可以串联地进行调用,直接使用管道符连续调用。
过滤器的本质是 JavaScript 函数,因此可以接收参数。
4.3.3过滤器的兼容性
过滤器仅在 vue 2.x 和 1.x 中受支持,在 vue 3.x 的版本中剔除了过滤器相关的功能。在企业级项目开发中:
- 如果使用的是 2.x 版本的 vue,则依然可以使用过滤器相关的功能
- 如果项目已经升级到了3.x 版本的 vue,官方建议使用计算属性或方法代替被剔除的过滤器功能
二、组件基础 1、单页面应用程序
1.1概念和特点
概念:单页面应用程序(英文名:Single Page Application)简称 SPA,顾名思义,指的是一个 Web 网站中只有唯一的一个 HTML 页面,所有的功能与交互都在这唯一的一个页面内完成。
特点:单页面应用程序将所有的功能局限于一个 web 页面中,仅在该 web 页面初始化时加载相应的资源( HTML、JavaScript 和 CSS)。一旦页面加载完成了,SPA 不会因为用户的操作而进行页面的重新加载或跳转。而是利用 JavaScript 动态地变换HTML 的内容,从而实现页面与用户的交互。
SPA 单页面应用程序最显著的 3 个优点如下:
① 良好的交互体验
? 单页应用的内容的改变不需要重新加载整个页面
? 获取数据也是通过 Ajax 异步获取
? 没有页面之间的跳转,不会出现“白屏现象”
② 良好的前后端工作分离模式
? 后端专注于提供 API 接口,更易实现 API 接口的复用
? 前端专注于页面的渲染,更利于前端工程化的发展
③ 减轻服务器的压力
? 服务器只提供数据,不负责页面的合成与逻辑的处理,吞吐能力会提高几倍
任何一种技术都有自己的局限性,对于 SPA 来说,主要的缺点有如下两个:
① 首屏加载慢
? 路由懒加载
? 代码压缩
? CDN 加速
? 网络传输压缩
② 不利于 SEO
? SSR 服务器端渲染
1.2创建 vue 的 SPA 项目
vue 官方提供了两种快速创建工程化的 SPA 项目的方式:
① 基于 vite 创建 SPA 项目
② 基于 vue-cli 创建 SPA 项目
2、vite 的基本使用 2.1创建 vite 的项目
按照顺序执行如下的命令,即可基于 vite 创建 vue 3.x 的工程化项目:
npm init vite-app 项目名称
cd 项目名称
npm install
npm run dev
2.2项目结构梳理
项目结构:
? node_modules 目录用来存放第三方依赖包
? public 是公共的静态资源目录
? src 是项目的源代码目录(程序员写的所有代码都要放在此目录下)
? .gitignore 是 Git 的忽略文件
? index.html 是 SPA 单页面应用程序中唯一的HTML 页面
? package.json 是项目的包管理配置文件
src项目结构:
? assets 目录用来存放项目中所有的静态资源文件(css、fonts等)
? components 目录用来存放项目中所有的自定义组件
? App.vue 是项目的根组件
? index.css 是项目的全局样式表文件
? main.js 是整个项目的打包入口文件
2.3 vite项目的运行流程
在工程化的项目中,vue 要做的:通过 main.js 把 App.vue 渲染到 index.html 的指定区域中。
① App.vue 用来编写待渲染的模板结构
② index.html 中需要预留一个 el 区域
③ main.js 把 App.vue 渲染到了 index.html 所预留的区域中
3、组件化开发思想 3.1 组件化开发
组件化开发指的是:根据封装的思想,把页面上可重用的部分封装为组件,从而方便项目的开发和维护。如:http://www.ibootstrap.cn/ 所展示的效果,就是组件化开发的思想。用户可以通过拖拽组件的方式,快速生成一个页面的布局结构。
3.2 组件化开发的好处
前端组件化开发的好处主要体现在以下两方面:
- 提高了前端代码的复用性和灵活性
- 提升了开发效率和后期的可维护性
vue 是一个完全支持组件化开发的框架。vue 中规定组件的后缀名是 .vue。之前接触到的 App.vue 文件本质上就是一个 vue 的组件。
4、vue 组件的构成 4.1 vue 组件组成结构
每个 .vue 组件都由 3 部分构成,分别是:
- template -> 组件的模板结构
- script -> 组件的 JavaScript 行为
- style -> 组件的样式
4.2 组件的 template 节点
vue 规定:每个组件对应的模板结构,需要定义到 节点中。
注意: 是 vue 提供的容器标签,只起到包裹性质的作用,它不会被渲染为真正的 DOM 元素。
4.2.1在 template 中使用指令
在组件的 节点中,支持使用前面所学的指令语法,来辅助开发者渲染当前组件的DOM 结构。
4.2.2在 template 中定义根节点
在 vue 2.x 的版本中, 节点内的 DOM 结构仅支持单个根节点,但是,在 vue 3.x 的版本中, 中支持定义多个根节点。
4.3组件的 script 节点
vue 规定:组件内的
import Swiper from './components/01.globalReg/Swiper.vue'
import Test from './components/01.globalReg/Test.vue'、
const app = createApp(App)
app.component('my-swiper', Swiper)
app.component('my-test', Test)
app.mount('#app')
使用 app.component() 方法注册的全局组件,直接以标签的形式进行使用即可。
注意:注册组件一定要写在vue实际控制区域的函数前面
5.1.2局部注册和使用组件
见事例
5.1.3全局注册和局部注册的区别
- 被全局注册的组件,可以在全局任何一个组件内使用
- 被局部注册的组件,只能在当前注册的范围内使用
如果某些组件在开发期间的使用频率很高,推荐进行全局注册;
如果某些组件只在特定的情况下会被用到,推荐进行局部注册。
5.2组件的基本使用
5.2.1组件注册时名称的大小写
在进行组件的注册时,定义组件注册名称的方式有两种:
① 使用 kebab-case 命名法(俗称短横线命名法,例如 my-swiper 和 my-search)
② 使用 PascalCase 命名法(俗称帕斯卡命名法或大驼峰命名法,例如 MySwiper 和 MySearch)
短横线命名法的特点:
- 必须严格按照短横线名称进行使用
- 既可以严格按照帕斯卡名称进行使用,又可以转化为短横线名称进行使用
5.2.2通过 name 属性注册组件
在注册组件期间,除了可以直接提供组件的注册名称之外,还可以把组件的 name 属性作为注册后组件的名称
5.2.3组件之间的样式冲突问题
默认情况下,写在 .vue 组件中的样式会全局生效,因此很容易造成多个组件之间的样式冲突问题。导致组件之间样式冲突的根本原因是:
① 单页面应用程序中,所有组件的 DOM 结构,都是基于唯一的 index.html 页面进行呈现的
② 每个组件中的样式,都会影响整个 index.html 页面中的 DOM 元素
解决方法:
为每个组件分配唯一的自定义属性,在编写组件样式时,通过属性选择器来控制样式的作用域。
5.2.4 style 节点的 scoped 属性
为了提高开发效率和开发体验,vue 为 style 节点提供了 scoped 属性,用来自动为每个组件分配唯一的“自定义属性”。并自动为当前的DOM标签和style样式应用这个自定义属性,从而防止组件之间的样式冲突问题。
5.2.5 /deep/ 样式穿透
如果给当前组件的 style 节点添加了 scoped 属性,则当前组件的样式对其子组件是不生效的。如果想让某些样式对子组件生效,可以使用 /deep/ 深度选择器。
注意:/deep/ 是 vue2.x 中实现样式穿透的方案。在 vue3.x 中推荐使用 :deep() 替代 /deep/。
5.3组件的 props
为了提高组件的复用性,在封装 vue 组件时需要遵守如下的原则:
- 组件的 DOM 结构、Style 样式要尽量复用
- 组件中要展示的数据,尽量由组件的使用者提供
组件的 props
props 是组件的自定义属性,组件的使用者可以通过 props 把数据传递到子组件内部,供子组件内部进行使用。
props 的作用:父组件通过 props 向子组件传递要展示的数据。
props 的好处:提高了组件的复用性。
- 在封装 vue 组件时,可以把动态的数据项声明为 props 自定义属性。自定义属性可以在当前组件的模板结构中被直接使用。
- 如果父组件给子组件传递了未声明的 props 属性,则这些属性会被忽略,无法被子组件使用。
- 可以使用 v-bind 属性绑定的形式,为组件动态绑定 props 的值
- props 的大小写命名:
5.4 Class 与 Style 绑定:
在实际开发中经常会遇到动态操作元素样式的需求。因此,vue 允许开发者通过 v-bind 属性绑定指令,为元素动态绑定 class 属性的值和行内的 style 样式。
5.4.1 动态绑定 HTML 的 class
可以通过三元表达式,动态的为元素绑定class 的类名。
如果元素需要动态绑定多个 class 的类名,此时可以使用数组的语法格式,使用数组语法动态绑定class 会导致模板结构臃肿的问题。此时可以使用对象语法进行简化。
5.4.2以对象语法绑定内联的 style
:style 的对象语法十分直观——看着非常像 CSS,但其实是一个 JavaScript 对象。CSS property 名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用引号括起来) 来命名。
6、props 验证 1、概念:
在封装组件时对外界传递过来的props 数据进行合法性的校验,从而防止数据不合法的问题。
用数组类型的 props 节点的缺点:无法为每个 prop 指定具体的数据类型。
【vue|vue基础(主要为vue3)】2、对象类型的 props 节点
使用对象类型的 props 节点,可以对每个 prop 进行数据类型的校验使
3、props 验证
对象类型的 props 节点提供了多种数据验证方案,例如:
- 基础的类型检查
- 多个可能的类型
- 必填项校验
- 属性默认值
- 自定义验证函数
- 计算属性
- 概念:
- 声明计算属性
注意:计算属性为得到一个计算的结果,因此计算属性中必须有 return 返回值!
3、计算属性的使用注意点
① 计算属性必须定义在 computed 节点中
② 计算属性必须是一个 function 函数
③ 计算属性必须有返回值
④ 计算属性必须当做普通属性使用
4、计算属性 vs 方法
相对于方法来说,计算属性会缓存计算的结果,只有计算属性的依赖项发生变化时,才会重新进行运算。因此计算属性的性能更好
8、自定义事件 1、概念:
在封装组件时,为了让组件的使用者可以监听到组件内状态的变化,此时需要用到组件的自定义事件。
2、自定义事件的 3 个使用步骤
在封装组件时:
- 声明自定义事件
- 触发自定义事件
在使用组件时:
- 监听自定义事件
- 自定义事件传参
9、组件上的 v-model 1、为什么需要在组件上使用 v-model
v-model 是双向数据绑定指令,当需要维护组件内外数据的同步时,可以在组件上使用 v-model 指令。
? 外界数据的变化会自动同步到 counter 组件中
? counter 组件中数据的变化,也会自动同步到外界
2、在组件上使用 v-model 的步骤
父组件向子组件:
① 父组件通过 v-bind: 属性绑定的形式,把数据传递给子组件
② 子组件中,通过 props 接收父组件传递过来的数据
子组件向父组件:
① 在 v-bind: 指令之前添加 v-model 指令
② 在子组件中声明 emits 自定义事件,格式为 update:xxx
③ 调用 $emit() 触发自定义事件,更新父组件中的数据
三、组件高级 1、watch 侦听器 1.1概念及用法
- 概念:
2、watch 侦听器的基本语法
开发者需要在 watch 节点下,定义自己的侦听器。实例代码如下:
watch: {
username(newVal, oldVal) {
console.log(newVal, oldVal);
}
},
3、使用 watch 检测用户名是否可用
监听 username 值的变化,并使用 axios 发起 Ajax 请求,检测当前输入的用户名是否可用:
watch: {
async username(newVal, oldVal) {
console.log(newVal, oldVal);
const {data: res} = await axios.get("https://www.escook.cn/api/finduser/" + newVal)
console.log(res);
}
},
1.2高级选项
1、immediate 选项
默认情况下,组件在初次加载完毕后不会调用 watch 侦听器。如果想让 watch 侦听器立即被调用,则需要使用 immediate 选项:
username: {
async handler(newVal, oldVal) {
const {data: res} = await axios.get("https://www.escook.cn/api/finduser/" + newVal)
console.log(res);
},
immediate: true,},
- deep选项
info: {
async handler(newVal) {
const {data: res} = await axios.get("https://www.escook.cn/api/finduser/" + newVal.username)
console.log(res);
},
deep: true,}},
3、监听对象单个属性的变化
如果只想监听对象中单个属性的变化,则可以按照如下的方式定义 watch 侦听器:
'info.username': {
async handler(newVal) {
const {data: res} = await axios.get("https://www.escook.cn/api/finduser/" + newVal)
console.log(res);
},
deep: true, },
1.3计算属性 vs 侦听器
应用场景不同:
(1)计算属性侧重于监听多个值的变化,最终计算并返回一个新值
(2)侦听器侧重于监听单个数据的变化,最终执行特定的业务处理,不需要有任何返回值
2、组件的生命周期 2.1组件运行的过程
组件的生命周期指的是:组件从创建 -> 运行(渲染) -> 销毁的整个过程,强调的是一个时间段。
2.2组件的监听
- 监听组件的不同时刻
① 当组件在内存中被创建完毕之后,会自动调用 created 函数
② 当组件被成功的渲染到页面上之后,会自动调用 mounted 函数
③ 当组件被销毁完毕之后,会自动调用 unmounted 函数
2、监听组件的更新
当组件的 data 数据更新之后,vue 会自动重新渲染组件的 DOM 结构,从而保证 View 视图展示的数据和Model 数据源保持一致。
当组件被重新渲染完毕之后,会自动调用updated 生命周期函数。
3、主要周期函数
文章图片
注意:在实际开发中,created 是最常用的生命周期函数!
4、组件中全部的周期函数
文章图片
3、组件之间的数据共享 3.1组件间关系
1、组件之间的关系
① 父子关系
② 兄弟关系
③ 后代关系
3.2数据共享
3.2.1父子组件关系之间的数据共享
1、父组件向子组件共享数据
父组件通过 v-bind 属性绑定向子组件共享数据。同时,子组件需要使用 props 接收数据。
2、子组件向父组件共享数据
子组件通过自定义事件的方式向父组件共享数据。
3、父子组件之间数据的双向同步
父组件在使用子组件期间,可以用 v-model 指令维护组件内外数据的双向同步。
3.2.2兄弟组件之间的数据共享
兄弟组件之间实现数据共享的方案是 EventBus。可以借助于第三方的包 mitt 来创建 eventBus 对象,从而实现兄弟组件之间的数据共享。
文章图片
- 在项目中运行如下的命令,安装 mitt 依赖包:
- 在项目中创建公共的 eventBus.js模块如下:
const bus = mitt()
export default bus
- 在数据接收方,调用 bus.on('事件名称', 事件处理函数) 方法注册一个自定义事件。
- 在数据发送方,调用 bus.emit('事件名称', 要发送的数据) 方法触发自定义事件。
后代关系组件之间共享数据,指的是父节点的组件向其子孙组件共享数据。此时组件之间的嵌套关系比较复杂,可以使用 provide 和 inject 实现后代关系组件之间的数据共享。
- 父节点的组件可以通过provide 方法,对其子孙组件共享数据
- 子孙节点可以使用 inject 数组,接收父级节点向下共享的数据。
(1)父节点使用 provide 向下共享数据时,可以结合computed 函数向下共享响应式的数据。
(2)如果父级节点共享的是响应式的数据,则子孙节点必须以 .value 的形式进行使用。
3.2.4 vuex
vuex 是终极的组件之间的数据共享方案。在企业级的 vue 项目开发中,vuex 可以让组件之间的数据共享变得高效、清晰、且易于维护。
文章图片
? 父子关系
① 父 -> 子 属性绑定
② 子 -> 父 事件绑定
③ 父 <-> 子 组件上的 v-model
? 兄弟关系④ EventBus
? 后代关系⑤ provide & inject
? 全局数据共享⑥ vuex
4、vue 3.x 中全局配置 axios 在实际项目开发中,几乎每个组件中都会用到 axios 发起数据请求。此时会遇到如下两个问题:
① 每个组件中都需要导入axios(代码臃肿)
② 每次发请求都需要填写完整的请求路径(不利于后期的维护)
4.1全局配置 axios
在 main.js 入口文件中,通过 app.config.globalProperties 全局挂载 axios,示例代码如下
文章图片
5、ref引用 ref 用来辅助开发者在不依赖jQuery 的情况下,获取 DOM 元素或组件的引用。
每个 vue 的组件实例上,都包含一个$refs 对象,里面存储着对应的DOM 元素或组件的引用。默认情况下,组件的 $refs 指向一个空对象。
5.1使用 ref 引用 DOM 元素
如果想要使用 ref 引用页面上的 DOM 元素,则可以按照如下的方式进行操作:
methods: {
getRefs() {
console.log(this.$refs);
this.$refs.myh1.style.color = "red";
}
}
5.2使用 ref 引用组件实例
使用 ref 引用页面上的组件实例,代码示例
1、控制文本框和按钮的按需切换
通过布尔值 inputVisible 来控制组件中的文本框与按钮的按需切换。
2、让文本框自动获得焦点
当文本框展示出来之后,如果希望它立即获得焦点,则可以为其添加 ref 引用,并调用原生 DOM 对象的.focus() 方法即可。
3、this.$nextTick(cb) 方法
组件的 $nextTick(cb) 方法,会把 cb 回调推迟到下一个 DOM 更新周期之后执行。通俗的理解是:等组件的DOM 异步地重新渲染完成后,再执行 cb 回调函数。从而能保证cb 回调函数可以操作到最新的 DOM 元素。
6、动态组件 动态组件指的是动态切换组件的显示与隐藏。vue 提供了一个内置的
①
② 通过 is 属性动态指定要渲染的组件名称
③
1、使用 keep-alive 保持状态
默认情况下,切换动态组件时无法保持组件的状态。此时可以使用vue 内置的
7、插槽 插槽(Slot)是 vue 为组件的封装者提供的能力。允许开发者在封装组件时,把不确定的、希望由用户指定的部分定义为插槽。
可以把插槽认为是组件封装期间,为用户预留的内容的占位符。
7.1插槽的基础用法
在封装组件时,可以通过元素定义插槽,从而为用户预留内容占位符。
注意:
- 如果在封装组件时没有预留任何插槽,则用户提供的任何自定义内容都会被丢弃。
- 封装组件时,可以为预留的插槽提供后备内容(默认内容)。如果组件的使用者没有为插槽提供任何内容,则后备内容会生效。
如果在封装组件时需要预留多个插槽节点,则需要为每个插槽指定具体的 name 名称。这种带有具体名称的插槽叫做“具名插槽”。
注意:没有指定 name 名称的插槽,会有隐含的名称叫做 “default”。
- 在向具名插槽提供内容的时候,我们可以在一个 元素上使用 v-slot 指令,并以 v-slot 的参数的形式提供其名称。
- 跟 v-on 和 v-bind 一样,v-slot 也有缩写,即把参数之前的所有内容 (v-slot:) 替换为字符 #。
在封装组件的过程中,可以为预留的插槽绑定 props 数据,这种带有 props 数据的叫做“作用域插槽”。
1、解构作用域插槽的 Prop
作用域插槽对外提供的数据对象,可以使用解构赋值简化数据的接收过程。
2、声明作用域插槽
在封装 MyTable 组件的过程中,可以通过作用域插槽把表格每一行的数据传递给组件的使用者。
3、使用作用域插槽
在使用 MyTable 组件时,自定义单元格的渲染方式,并接收作用域插槽对外提供的数据。
- 自定义指令
vue 中的自定义指令分为两类,分别是:
? 私有自定义指令
? 全局自定义指令
8.1私有自定义指令
1、声明私有自定义指令的语法
在每个 vue 组件中,可以在 directives 节点下声明私有自定义指令。自定义指令声明时不带-v,使用时需要带-v.
directives: {
focus: {
},
},
},
2、使用自定义指令
在使用自定义指令时,需要加上 v- 前缀。
directives: {
focus: {
mounted(el) {
el.focus()
},
},
},
8.2全局自定义指令
1、声明全局自定义指令的语法
全局共享的自定义指令需要通过“单页面应用程序的实例对象”进行声明,示例代码如下:
app.directive('focus', {
mounted(el) {
el.focus()
}
})
8.3 updated 函数
mounted 函数只在元素第一次插入 DOM 时被调用,当 DOM 更新时 mounted 函数不会被触发。 updated函数会在每次 DOM 更新完成后被调用。
注意:
- 在 vue2 的项目中使用自定义指令时,【mounted -> bind 】【 updated -> update 】
- 如果 mounted 和updated 函数中的逻辑完全相同,则可以简写成如下格式:
el.focus()
})
- 在绑定指令时,可以通过“等号”的形式为指令绑定具体的参数值
- 前端路由得概念和原理
① 后端路由
② 前端路由
后端路由指的是:请求方式、请求地址与function 处理函数之间的对应关系。
- SPA 与前端路由
结论:在 SPA 项目中,不同功能之间的切换,要依赖于前端路由来完成!
前端路由:Hash 地址与组件之间的对应关系。
1.2前端路由的工作方式
① 用户点击了页面上的路由链接
② 导致了 URL 地址栏中的 Hash 值发生了变化
③ 前端路由监听了到 Hash 地址的变化
④ 前端路由把当前 Hash 地址对应的组件渲染到浏览器中
文章图片
结论:前端路由,指的是 Hash 地址与组件之间的对应关系!
1.3实现简易的前端路由
- 导入并注册 MyHome、MyMovie、MyAbout 三个组件。
- 通过
标签的 is 属性,动态切换要显示的组件。 - 在组件的结构中声明如下 3 个链接,通过点击不同的链接,切换浏览器地址栏中的Hash 值
- 在 created 生命周期函数中监听浏览器地址栏中 Hash 地址的变化,动态切换要展示的组件的名称:
window.onhashchange = () => {
switch (location.hash) {
case '#/home':
this.comName = 'MyHome'
break;
case '#/about':
this.comName = 'MyAbout'
break;
case '#/movie':
this.comName = 'MyMovie'
break;
}
}
},
- vue-router 的基本用法
vue-router 的版本
vue-router 目前有 3.x 的版本和 4.x 的版本。其中:
? vue-router 3.x 只能结合 vue2 进行使用
? vue-router 4.x 只能结合 vue3 进行使用
vue-router 3.x 的官方文档地址:https://router.vuejs.org/zh/
vue-router 4.x 的官方文档地址:Vue Router
2.1 使用方法
vue-router 4.x 的基本使用步骤
(1)在项目中安装 vue-router
npm install vue-router@next -S
(2)定义路由组件
在项目中定义 MyHome.vue、MyMovie.vue、MyAbout.vue三个组件,将来要使用vue-router 来控制它们的展示与切换。
(3)声明路由链接和占位符
可以使用
(4)创建路由模块
在项目中创建 router.js 路由模块,在其中按照如下4 个步骤创建并得到路由的实例对象:
- 从 vue-router 中按需导入两个方法
- 导入需要使用路由控制的组件
- 创建路由实例对象
history: createWebHashHistory(),
routes: [
{ path: '/home', component: Home },
{ path: '/movie', component: Movie },
{ path: '/about', component: About },
]
})
- 向外共享路由实例对象
- 在 main.js 中导入并挂载路由模块
- 导入并挂载路由模块
const app = createApp(App)
app.use(router)
- vue-router 的高级用法
路由重定向指的是:用户在访问地址 A 的时候,强制用户跳转到地址 C ,从而展示特定的组件页面。
通过路由规则的 redirect 属性,指定一个新的路由地址,可以很方便地设置路由的重定向。
3.2路由高亮
可以通过如下的两种方式,将激活的路由链接进行高亮显示:
① 使用默认的高亮 class 类
② 自定义路由高亮的 class 类
3.2.1默认的高亮 class 类
被激活的路由链接,默认会应用一个叫做 router-link-active 的类名。开发者可以使用此类名选择器,为激活的路由链接设置高亮的样式
3.2.2自定义路由高亮的 class 类
在创建路由的实例对象时,开发者可以基于 linkActiveClass 属性,自定义路由链接被激活时所应用的类名:
linkActiveClass: 'active-router',
3.3嵌套路由
通过路由实现组件的嵌套展示,叫做嵌套路由。
- 声明子路由链接和子路由占位符
- 在父路由规则中,通过children 属性嵌套声明子路由规则
path: '/about',
component: About,
children: [
{ path: 'tab1', component: Tabl },
{ path: 'tab2', component: Tab2 },
]
},
3.4动态路由的概念
动态路由指的是:把 Hash 地址中可变的部分定义为参数项,从而提高路由规则的复用性。
(1)在 vue-router 中使用英文的冒号(:)来定义路由的参数项。
(2)通过动态路由匹配的方式渲染出来的组件中,可以使用 $route.params 对象访问到动态匹配的参数值。
(3)为了简化路由参数的获取形式,vue-router 允许在路由规则中开启props 传参。
3.5编程式导航
通过调用 API 实现导航的方式,叫做编程式导航。与之对应的,通过点击链接实现导航的方式,叫做声明式导航。例如:
- 普通网页中点击链接、vue 项目中点击
都属于声明式导航 - 普通网页中调用 location.href 跳转到新页面的方式,属于编程式导航
vue-router 提供了许多编程式导航的 API,其中最常用的两个 API 分别是:
① this.$router.push('hash 地址')
- 跳转到指定 Hash 地址,从而展示对应的组件
- 实现导航历史的前进、后退
通过 name 属性为路由规则定义名称的方式,叫做命名路由。
注意:命名路由的 name 值不能重复,必须保证唯一性!
3.6.1使用命名路由实现声明式导航
为
3.6.2使用命名路由实现编程式导航
调用 push 函数期间指定一个配置对象,name是要跳转到的路由规则、params 是携带的路由参数
3.7导航守卫
导航守卫可以控制路由的访问权限。示意图如下:
文章图片
1、声明全局导航守卫
全局导航守卫会拦截每个路由规则,从而对每个路由进行访问权限的控制。可以按照如下的方式定义全局导航守卫:
router.beforeEach(() => {
console.log('ok');
})
2、守卫方法的 3 个形参
全局导航守卫的守卫方法中接收 3 个形参,格式为:
router.beforeEach((to, from, next) => {
//to 目标路由对象
//from当前导航正要离开的对象
//next是一个函数,表示放行
})
注意:
① 在守卫方法中如果不声明 next 形参,则默认允许用户访问每一个路由!
② 在守卫方法中如果声明了 next 形参,则必须调用 next() 函数,否则不允许用户访问任何一个路由!
Next函数:
直接放行:next()
强制其停留在当前页面:next(false)
强制其跳转到登录页面:next('/login')
3、结合 token 控制后台主页的访问权限
const token = localStorage.getItem(‘token’)
If(to.path === ‘/main’ && !token) {
Next(‘/login’)
} else {
next()
}
- 综合案例
vue-cli(俗称:vue 脚手架)是 vue 官方提供的、快速生成 vue 工程化项目的工具。特点:
① 开箱即用
② 基于 webpack
③ 功能丰富且易于扩展
④ 支持创建 vue2 和 vue3 的项目
2、安装
vue-cli 是基于 Node.js 开发出来的工具,因此需要使用 npm 将它安装为全局可用的工具npm install -g @vue/cli
3、创建项目
(1)vue create 项目名称
- 在终端下运行vue create demo2 命令,基于交互式的命令行创建 vue 的项目
- 选择要安装的功能
- 使用上下箭头选择 vue 的版本,并使用回车键确认选择
- 使用上下箭头选择要使用的 css 预处理器,并使用回车键确认选择
- 使用上下箭头选择如何存储插件的配置信息,并使用回车键确认选择
- 是否将刚才的配置保存为预设
- 选择如何安装项目中的依赖包
- 开始创建项目并自动安装依赖包
- 项目创建完成
- 在终端下运行vue ui 命令,自动在浏览器中打开创建项目的可视化面板:
- 在详情页面填写项目名称:
- 在预设页面选择手动配置项目:
- 在功能页面勾选需要安装的功能(Choose Vue Version、Babel、CSS 预处理器、使用配置文件)
- 在配置页面勾选 vue 的版本和需要的预处理器
- 将刚才所有的配置保存为预设(模板),方便下一次创建项目时直接复用之前的配置
- 创建项目并自动安装依赖包
- 项目创建完成后,自动进入项目仪表盘
7.2组件库 1. 什么是 vue 组件库
在实际开发中,前端开发者可以把自己封装的 .vue 组件整理、打包、并发布为 npm 的包,从而供其他人下载和使用。这种可以直接下载并在项目中使用的现成组件,就叫做 vue 组件库。
2. vue 组件库和 bootstrap 的区别
? bootstrap 只提供了纯粹的原材料( css 样式、HTML 结构以及 JS 特效),需要由开发者做进一步的组装和改造
? vue 组件库是遵循 vue 语法、高度定制的现成组件,开箱即用
3. 最常用的 vue 组件库
① PC 端
? Element UI(https://element.eleme.cn/#/zh-CN)
? View UI(http://v1.iviewui.com/)
② 移动端
? Mint UI(http://mint-ui.github.io/#!/zh-cn)
? Vant(https://vant-contrib.gitee.io/vant/#/zh-CN/)
4. Element UI
Element UI 是饿了么前端团队开源的一套 PC 端 vue 组件库。支持在 vue2 和 vue3 的项目中使用:
? vue2 的项目使用旧版的 Element UI(https://element.eleme.cn/#/zh-CN)
? vue3 的项目使用新版的 Element Plus(https://element-plus.gitee.io/#/zh-CN)
推荐阅读
- vue基础案例
- javascript|vue基础、插值操作、计算属性、ES6补充
- VUE|官网学习Vue(一)Vue基础篇
- vue|vue,首页优化
- php|php vue rbac,Vue+ThinkPHP5.1 实现基于角色控制权限的前后端分离后台管理系统
- 每天几个面试题|token过期?页面如何实现无感刷新?
- web|CSS 3之鼠标特效
- web|CSS 3之美化菜单
- 前端|Mendix入门教程第一篇-demo实例