1.什么是vue
官方给出的概念:Vue是一套用于构建用户界面的前端框架
构建用户界面<->框架
1.1 解读核心关键词:构建用户界面
前端开发者最主要的工作,就是为网站的使用者构建出美观、舒适、好用的网页
-美化样式 基于HTML
构建用户界面 -编写结构 基于CSS样式
-处理交互 基于JS
1.2 构建用户界面的传统方式
在传统的Web前端开发中,是基于jQuery + 模板引擎的方式来构建用户界面的
编写结构
基于模板结构技术 把数据渲染到页面上
优点:初步解放了前端开发者 从此不用手动拼接字符串来渲染网页结构
缺点:需要定义大量的模板结构 缺少语法高亮和智能提示 数据变化时需要重新调用模板编译的函数
美化样式
基础CSS样式 美化网页的可视化效果
处理交互
基于jQuery技术,处理用户和网页之间的交互行为
优点:屏蔽了DOM API 之间的兼容性,提高了DOM操作的效率和体验
缺点:当业务复杂时、数据变化频繁时,前端开发者需要把大量的时间和精力浪费在DOM的操作上
而不是核心业务的处理上
1.3 使用vue构建用户界面
使用vue构建用户界面,解决了jQuery + 模板引擎的诸多痛点 极大的提高了前端开发的效率和体验
编写结构
基于vue中提供的指令,可以方便快捷的渲染页面的结构
数据驱动视图图(只要页面依赖的数据源变化,则页面自动重新渲染)
Ps:指令是vue为开发者提供的模板语法,用来辅助开发者渲染页面的结构
美化样式
基础CSS样式 美化网页的可视化效果
处理交互
基于vue中提供的时间绑定 可以轻松处理用户和页面之间的交互行为
Ps:开发者把工作的重心放在核心业务的实现上
1.4解读核心关键词:框架
官方给vue的定位是前端框架,因为它提供了构建用户界面的一整套解决方案(vue全家桶)
vue(核心库)
vue-router(路由方案)
vuex(状态管理方案)
vue组件库(快速搭配页面UI效果的方案)
以及辅助vue项目开发的一系列工具
vue-cli(npm全局包:一键生成工程化的vue项目 - 基于webpack、大而全)
vite(npm全局包:一键生成工程化的vue项目-小而巧)
vue-devtools(浏览器插件:辅助调试的工具)
vetur(vscode插件:提供语法高亮和智能提示)
1.5总结:什么是vue
vue是一套用于构建用户界面的前端框架
指令 构建用户界面的一整天解决方案
数据驱动视图 构建用户界面<->框架 vue全家桶(vue+vue-router+vuex+组件库)
事件绑定 提供了辅助项目开发的配套工具
(vue-cli + vue-devtools)
vue框架的特性,主要体现如下两个方面
数据驱动视图
双向数据绑定
2.1数据驱动视图
在使用vue的页面中,vue会监听数据的变化,从而自动渲染页面的结构
自动渲染 变化
页面结构<-----------vue监听数据的变化<-------->页面所依赖的数据
好处 程序员只要把数据维护好,当页面数据发送变化时,页面会自动重新渲染
注意:数据驱动视图是单向的数据 绑定
2.2 双向数据绑定
在填写表单时,双向数据绑定可以辅助开发者在不操作DOM的前提下
自动把用户填写的内容同步到数据源中
自动渲染 变化
页面结构<-----------vue<-------->页面所依赖的数据
-----------> --------->
值发生变化 自动同步
好处 开发者不需要手动操作DOM元素 来获取表单元素最新的值
2.3 MVVM
MVVM是vue实现数据驱动视图和双向数据绑定的核心原理
MVVM指的是Model View 和ViewModel
Model 表示当前页面渲染时所依赖的数据源
View 表示当前页面所渲染的DOM结构
ViewModel 表示vue的实例 它是MVVM的核心
View ViewModel Model
DOM vue js Object
2.4 MVVM的工作原理
ViewModel作为MVVM的核心,是它把当前页面的数据源(Model)和页面结构(View)连接在一起
自动更新 监听数据源变化
View<-----------ViewModel<----------->Model
-----------> ----------->
监听DOM变化 自动同步
当前vue共有3个大版本其中
2.x版本的vue是目前企业级项目开发中的主流版本
3.x版本的vue于2020-09-19发布,生态还不完善,尚未在企业级项目开发中普及和推广
1.x版本的vue几乎被淘汰,不再建议学习与使用
总结:
3.x版本的vue是未来企业级项目开发的趋势
2.x版本的vue在未来会被逐渐淘汰
3.1 vue3.x和vue2.x版本的对比
vue2.x中绝大多数的API与特性,
在vue3.x中同样支持。同时,vue3.x中还新增了3.x所特有的功能
并废弃了某些2.x中的旧功能
新增的功能
组合式API 多根节点组件 更好的TypeScript
废弃的旧功能如下
过滤器 不再支持%on $off和$once实例方法
1.基本使用步骤
1 导入vue.js的script脚本文件
2 在页面中声明一个将要被vue所控制的DOM区域
3 创建vm实例对象
vue的指令与过滤器
1.指令的概念
指令是vue为开发者提供的模板语法 用于复制开发者渲染页面的基本结构
vue中的指令按照不同的用途可以分为如下6大类
内容渲染指令 属性绑定指令 事件绑定指令
双向绑定指令 条件渲染指令 列表渲染指令
注意:指令是vue开发中最基础 最常用 最简单的知识点
1.1 内容渲染指令
内容渲染指令依赖辅助开发者渲染DOM元素的文本内容 常用的有3个
v-text {{}} v-html
v-text
缺点:会覆盖元素原有的内容
用法示例
性别
{{}}
vue提供的{{}}语法,专门用来解决v-text会覆盖默认文本内容的值问题
{{}}语法专业名称是插值表达式
实际开发中用的最多,只是内容的占位符 不会覆盖原有的内容
v-html
v-text指令和插值表达式只能渲染纯文本内容。
如果要包含html标签的字符串渲染为页面的html元素 则用v-html
1.2 属性绑定指令
注意:
插值表达式只能用在元素的内容节点中 不能用在元素的属性节点中
如果需要为元素的属性动态绑定属性值 则需要用到v-bind属性绑定指令
简写
vue规定v-bind:指令可以简写为 :
使用JS表达式
在vue提供的模板渲染语法中,除了支持绑定简单的数据值之外 还支持js表达式的运算
{{number + 1}}
{{ok ? 'yes':'no'}}
在v-bind期间 如果绑定内容需要进行动态拼接 则字符串的外面应该包裹单引号
1.3 事件绑定指令
vue提供了v-on事件绑定指令,用来辅助程序员为DOM元素绑定事件监听。
通过v-on绑定的事件处理函数,需要在methods节点中进行声明
const vm = new Vue({
el:'#app',
data:{count:0},
methods:{
add(){
this表示当前new出来的vm实例对象
通过this可以访问到data中的数据
this.count +=1
}
}
})
注意:原生DOM对象有onclick oninput onkeyup等原生事件
分别为:v-on:click v-on:input v-on:keyup
事件对象event
在原生的DOM事件绑定中,可以在事件处理函数的形参处,接收事件对象event
同理v-on指令所绑定的事件处理函数中,同样可以接收到事件对象event
绑定事件并传参
在使用v-on指令绑定事件时,可以使用()进行传参,
count的值是:{{ count }}
$event
$event是vue提供的特殊变量,用来表示原生的事件参数对象event
$event可以解决事情参数对象event被覆盖的问题
method: {
add(n,e) {
this.count += n
const bgColor=e.target.style.backgroundColor
e.target.style.backgroundColor = bgColor==='red' ? '' : 'red'
}
}
}
事件修饰符
在事件处理函数中调用event.preventDefault()或event.stopPropagation()
因此vue提供了事件修饰符的概念,来辅助程序员更方便的对事件的触发进行控制
.prevent 阻止默认行为 *
.stop 阻止事件冒泡 *
.capture 以捕获模式触发当前的事件处理函数
.once 绑定的事件只触发1次
.self 只有在event.target是当前原生自身时触发事件处理函数
语法格式
.prevent 阻止默认行为 *
跳到百度首页
.stop 阻止事件冒泡 *
最终输出 点击inner事件 没有outer事件
.capture 以捕获模式触发当前的事件处理函数
最终输出 点击inner盒子 先触发outer事件 再触发inner事件
.once 绑定的事件只触发1次
.self 只有在event.target是当前原生自身时触发事件处理函数
最终输出 点击outer触发 box和outer事件 点击inner触发 inner和box事件
按键修饰符
在监听键盘事件 外面经常需要判断详细的按键 此时可以为键盘相关的事件添加按键修饰符
1.4 双向绑定指令
vue提供了v-model双向数据绑定指令 用来辅助开发者不操作DOM元素的前提 快速获取表单数据
v-model是双向 v-bind是单向
语法格式
用户得到名字是{{ username }}
注意 v-model指令只能配合表单元素一起使用
为了方便对用户输入的内容进行处理 vue为v-model提供了3个修饰符
.number 自动将用户的输入值转化为数值类型
.trim 自动过滤用户输入的首尾空白字符
.lazy 在"change"时而非"input时更新"
1.5 条件渲染指令
条件渲染指令用来辅助开发者按需控制DOM的显示与隐藏
条件渲染指令有如下两个
v-if v-show
v-if v-show的区别
实现原理不同
v-if指令会动态地创建或移除DOM元素 从而控制元素在页面上的显示与隐藏
v-show指令会动态为元素添加或移除style="display:none"样式 从而控制元素在页面上的显示与隐藏
性能消耗不同:
v-if有更高的切换开销 而v-show有更高的初始渲染开销
如果需要非常频繁地切换 使用v-show
如果运行时条件很少改变 使用v-if
v-else
v-if可以单独使用 或配合v-else指令一起使用
v-else-if
v-else-if指令,充当v-if的 else-if块 可以连续使用
1.6 列表渲染指令
vue提供了v-for指令 用来辅助开发者基于一个数组来循环渲染相似的UI结构
v-for指令需要使用item in items的特殊语法
items是待循环的数组
item是当前的循环项
data:{
list:[
{id:1,name:'zs'}.
{id:2,name:'ls'}
]
}
v-for中的索引
v-for指令还支持一个可选的第二个参数,即当前项的索引
语法格式为(item,index)in items
注意:v-for指令中的item项和index索引都是形参,可以根据需要进行重命名
使用key维护列表的状态
当列表的数据变化时,默认情况下,vue会尽可能的复用已存在的DOM元素,从而提升渲染的性能
这种默认的性能优化策略,会导致有状态的列表无法被正确更新
为了给vue一个提示,以便它能跟踪每个节点的身份,从而保证的列表被正确更新的前提下
提升渲染的性能。此时,需要为每项提供一个唯一的key属性
key的注意事项
1 key的值只能是字符串或数字类型
2 key的值必须具有唯一性(即:key的值不能重复)
3 数据项id属性的值作为key的值(id属性的值具有唯一性)
4 使用index的值当作key的值没有任意意义(index的值不具有唯一性)
5 使用v-for指令时一定要指的key的值(即提升性能、又防止列表状态絮乱)
1.什么是单页面应用程序
单页面应用程序(Single Page Application) SPA
指的是一个Web网站中只有唯一的一个HTML页面
所有功能与交互都在这唯一的一个页面内完成
2. 单页面应用程序的优点
1 良好的交互体验
单页应用的内容的改变不需要重新加整个页面
获取数据也是通过ajax异步获取
没有页面之间的跳转,不会出现白屏现象
2 良好的前后端工作分离模式
后端专注于提供API接口,更易实现API接口的复用
前端专注于页面的渲染,更利于前端工程化的发展
3 减轻服务器的压力
服务器只提供数据,不负责页面的合成与逻辑的处理,吞吐能力会提供几倍
3.单页面应用程序的缺点
任何一种技术都有自己的局限性,对于SPA单页面应用程序来说,主要的缺点有如下两个
1 首屏加载慢
路由懒加载
代码压缩
CDN加速
网络传输压缩
2 不利于SEO
SSR服务器端渲染
4.如何快速创建vue的SPA项目
vue官方提供了两种快速创建工程化的SPA项目的方式
基于vite创建SPA项目
基于vue-cli创建SPA项目
vite vue-cli
支持的vue版本 仅支持3.x 支持3.x和2.x
是否基于webpack 否 是
运行速度 快 较慢
功能完整度 小而巧 大而全
是否建议在企业级中使用 不建议 建议
1.创建vite的项目
即可基于vite创建vue3.x的工程化项目
npm init vite-app 项目名称
Ok to proceed? (y) y
cd 项目名称
npm install
npm run dev
2.梳理项目的结构
其中:
node_modules目录用来存放第三方依赖包
public是公共的静态资源目录
src是项目的源代码目录
.gitignore是Git的忽略文件
index.html是SPA单页面应用程序中唯一的HTML页面
package.json是项目的包管理配置文件
src这个项目源代码目录之下,包含了如下的文件和文件夹
assets目录用来存放项目中所有的静态资源文件
component目录用来存放项目中所有的自定义组件
App.vue是项目的根组件
index.css是项目的全局样式表文件
main.js是整个项目的打包入口文件
3.vite项目的运行流程
在工程化的项目中
vue要做的事情很单纯:通过main.js把App.vue渲染到index.html的指定区域中
其中:
App.vue用来编写待渲染的模板结构
index.html中需要预留一个el区域
main.js把App.vue渲染到了index.html所预留的区域中
1.什么是组件化开发
组件化开发指的是:根据封装的思想,
把页面上可重用的部分封装为组件,从而方便项目的开发和维护
2.组件化开发的好处
前端组件化开发的好处主要体现在以下两方面
提高了前端代码的复用性和灵活性
提升了开发效率和后期的可维护性
3.vue中的组件化开发
vue 是一个完全支持组件库开发的框架,vue中规定组件的后缀名是.vue
之前App.vue文件本质上就是一个vue的组件
1.vue组件组成结构
每个.vue组件都是由3部分构成,分别是:
template->组件的模板结构
script->组件的JavaScript行为
style->组件的样式
其中,每个组件中必须包含template模板结构,而script行为和style样式是可选的组成部分
2.组件的template节点
vue规定:每个组件对应的模板结构,需要定义到节点中
注意:是vue提供的容器标签,只起到包裹性质的作用,它不会被渲染为真正的DOM元素。
2.1 在中使用指令
在组件的节点中,支持使用前面所学的指令语法,来辅助开发者渲染当前组件的DOM结构
2.2 在template中定义根节点
在vue 2.x的版本中,节点内的DOM结构仅支持单个根节点
这是App.vue根组件
abc
但是,在vue3.x的版本中,中支持定义多个根节点
这是App.vue根组件
abc
3.组件的script节点
vue规定:组件内的
3.1 script中的name节点
可以通过name节点为当前组件定义一个名称
使用vue-devtools进行项目调试的时候,自定义的组件名称可以清晰的区分每个组件
3.2 script中的data节点
vue组件渲染期间需要用到的数据,可以定义在data节点中;
3.3 script中的methods节点
组件中的事件处理函数,必须定义到methods节点中
export default {
name:'MyApp',//组件的名称
data(){//组件的数据
return{
username:'zs',
count:0
}
},
methods:{//处理函数
add(){
this.count++
}
}
}
vue规定: 组件内的
其中
2.2 style节点的scoped属性
为了提高开发效率和开发体验,vue为style节点提高了scoped属性,防止组件之间样式冲突
加上了scoped,vue会自动为组件的dom结构以及样式分配一个唯一的自定义属性
2.3 /deep/样式穿透
如果给当前组件的style节点添加scoped属性 则当前组件的样式对其子组件是不生效的
如果想让某些样式对子组件生效,可以使用/deep/深度选择器
注意:/deep/是vue2.x中实现样式穿透的方案 在vue3.x中推荐使用:deep()替代/deep/
为了提高组件的复用性,在封装vue组件时需要遵守如下的原则
组件的DOM结构、Style样式要尽量复用
组件中要展示的数据,尽量由组件的使用者提供
为了方便使用者为组件提供要展示的数据,vue组件提供了props的概念
3.1 什么是组件的props
props是组件的自定义属性,组件的使用可以通过props把数据传递到子组件内部,供子组件内部进行使用
通过自定义props 把文章的标题和作者 传递到my-article组件中
props的作用:父组件通过props向子组件传递要展示的数据
props的好处:提高了组件的复用性
3.2 在组件中声明props
在封装vue组件时,可以把动态的数据项声明为props自定义属性。
自定义属性可以在当前组件的模板结构中被直接使用
3.3 无法使用未声明的props
如果父组件给子组件传递了未说明的props 则这些属性会被忽略,无法被子组件使用
标题:{{ title }}
作者:{{ author }}
2.2触发自定义事件
在emits节点下声明的自定义事件,可以通过this.$emit('自定义事件')方法进行触发
Counter组件
2.3监听自定义事件
在使用自定义的组件时,可以通过v-on的形式监听自定义事件
<使用 v-on指令绑定事件监听>
methods:{
getCount(){
console.log('监听到了count值的变化')
}
}
2.4总结
在封装组件时
声明自定义事件 emits[?]
触发自定义事件 this.$emit[?]
在使用组件时
监听自定义事件 @?="函数触发"
3.自定义事件传参
在调用this.$emit()方法触发自定义事件时,可以通过第2个参数为自定义事件传参
count的值是:{{ count }}
1.为什么需要在组件上使用v-model
v-model是双向数据绑定指令,当需要维护组件内外数据的同步时
可以在组件上使用v-model指令。
外界数据的变化会自动同步到子组件中
2.在组件上使用v-model的步骤
父组件通过v-bind:属性绑定的形式,把数据传递给子组件
子组件,通过props接收父组件传递过来的数据
2.在组件上使用v-model的步骤
在v-bind:指令之前添加v-model指令
在子组件中声明emits自动事件 格式为update:xxx
调用$emit()触发自定义事情,更新父组件中的数据
能够掌握watch侦听器的基本使用
能够知道vue中常用的生命周期函数
能够知道如何实现组件之间的数据共享
能够知道如何在vue3.x的项目中全局配置axios
1.什么是watch侦听器
watch侦听器允许开发者监视数据的变化,从而针对数据的变化做特定的操作。
监视用户名的变化并发起请求,判断用户名是否可用
2.watch侦听器的基本语法
开发者需要在watch节点下,定义自己的侦听器
export default {
data(){
return {username:''}
},
watch:{
//监听username的值的变化
//形参列表中,第一个值是变化后的新值 第二个值是变化之前的旧值
username(newVal,oldVal){
console.log(newVal,oldVal)
},
}
}
3.使用watch检查用户名是否可用
监听username值的变化,并使用axios发起Ajax请求 检查当前输入的用户名是否可用
2.2 子组件向父组件共享数据
子组件通过自定义事件的方式向父组件共享数据
子组件
export default {
name:'MySon',
props:['num'],
// 声明自定义事件
emits:['numchange'],
methods:{
add(){
// 触发自定义事件
this.$emits('numchange',this.num +1)
}
}
}
父组件
export default {
name:'MyApp',
data(){
return{
count:0,
}
},
methods:{
getNum(num){
this.count=num
}
},
// 注册子组件
components:{
MySon,
},
}
2.3 父子组件之间数据的双向同步
父组件在使用子组件期间,可以使用v-model指令维护组件内外数据的双向同步
import MySon from './Son.vue';
父组件
export default {
name:'MyApp',
data(){
return{
count:0,
}
},
// 注册子组件
components:{
MySon,
},
}
子组件
export default {
name:'MySon',
props:['num'],
// 声明自定义事件
emits:['update:num'],
methods:{
add(){
// 触发自定义事件
this.$emit('update:num',this.num+1)
}
}
}
3.兄弟组件之间的数据共享
兄弟组件之间实现数据共享的方案是EventBus。
借助于第三方的包mitt来创建eventBus对象
从而实现兄弟组件之间的数据共享
3.1 安装mitt依赖包
npm install [email protected]
3.2 创建公共的EventBus模块
在项目中创建公共的eventBus模块
import mitt from './eventBus.js'
const bus = mitt()
export default bus
3.3在数据接收方自定义事件
在数据接收方,调用bus.on('事件名称',事件处理函数)方法注册一个自定义事件。
import bus from './eventBus.js'
export default {
name:'MyRight',
data(){
return {
num:0,
}
},
// 当组件在内存中创建完成 立即通过bus声明事件
created(){
bus.on('countChange',(count)=>{
this.num = count
// 外面的count值转成到data去
})
}
}
3.4在数据接发送方触发事件
数据发送方,调用bis.emit('事件名称',要发生的数据)方法触发自定义事件
import bus from './eventBus.js'
export default {
name:'MyLeft',
data(){
return {
count:0,
}
},
// 当组件在内存中创建完成 立即通过bus声明事件
methods:{
add(){
this.count++
bus.emit('countChange',this.count)
}
}
}
4.后代关系组件之间的数据共享
后代关系组件之间共享数据,指的是父节点的组件向其子孙组件共享数据。
此时嵌套共享比较复杂,可以使用provide(发送向外)和inject(接收向内)实现后代关系组件之间的数据共享
4.1 父节点通过provide 共享数据
父节点的组件可以通过provide方法 对其子孙组件共享数据
export default {
name:'MyLeft',
data(){
return {
color:'red',
}
},
// 当组件在内存中创建完成 立即通过bus声明事件
provide(){//provide函数 return的对象包含了要向对象子孙组件共享数据
return{
color:this.color
}
}
}
4.3 子孙节点通过inject接收数据
数据发送方 --- count的值为{{ color }}
4.3 父节点对外共享响应式的数据
父节点使用provide向下共享数据时,可以结合computed函数向下共享响应式的数据
import {computed} from 'vue' //从vue中按需导入computed函数
export default {
name:'MyApp',
data(){
return{
color:'red',
}
},
provide(){
// 返回要共享的数据对象
return{
color:computed(()=>this.color)
}
},
}
4.4 子孙节点使用响应式的数据
如果父级节点共享的是响应式的数据,则子孙节点必须以.value的形式进行使用
Level Three 三级组件{{ color.value }}
5.vuex
vuex是终极的组件之间的数据共享方案。
在企业级的vue项目开发中,vuex可以让组件之间的数据共享变得高效 清晰 且易于维护
6.总结
父子关系
父 -> 子 属性绑定
子 -> 父 事件绑定
父 <-> 子 组件上的v-model
兄弟关系
EventBus
后代关系
provide & inject
全局数据共享
vuex
1.为什么要全局配置axios
在实际项目开发中,几乎每个组件中都会用到axios发起数据请求
每个组件中都需要导入axios(代码臃肿)
每次发请求都需要填写完整的请求路径(不利于后期的维护)
2如何全局配置axios
在main.js入口文件中,通过app.config.globalProperties(固定写法)全局挂载axios
例如
// 挂载请求的根路径
axios.defaults.baseURL='https://www.escook.cn'
// 全局挂载自定义属性
app.config.globalProperties.$http = axios
能够知道如何使用ref引用DOM和组件实例
能够做到$nextTick的调用时机
能够说出keep-alive元素的左右
能够掌握插槽的基本用法
能够做到如何自定义指令
组件高级(下)
ref用来辅助开发者在不依赖jQuery的情况下,获取DOM元素或组件的引用
每个vue的组件实例上 都包含一个$refs对象,里面存储着对于的DOM元素或组件的引用
组件的$refs指向一个空对象
MyRef组件
获取 $refs 引用
2.使用ref引用DOM元素
如果想要使用ref引用页面上的DOM元素,则可以按照如下的方式进行操作
MyRef 组件
methods:{
getRef(){
//通过this.$refs.引用的名称 可以获取到DOM元素的引用
console.log(this.$refs.myh3)
操作DOM元素 把文本颜色改为红色
this.$refs.myh3.style.color = 'red'
},
}
3.使用ref引用组件实例
如果需要使用ref引用页面山的组件实例 则可以按照如下的方式进行操作
methods:{
getInfo(){
console.log(this.$refs.counterRef)
this.$refs.counterRef.add()
}
}
4.控制文本框和按钮的按需切换
通过布尔值inputVisible来控制组件中的文本框与按钮的按需切换
5.让文本框自动获得焦点
当文本框展示出来之后,如果希望它立即获得焦点,则可以为其添加ref引用
并调用原生DOM对象的.focus()方法即可
export default {
name:'MyApp',
data(){
return{
inputVisible:false
}
},
methods:{
showInput(){
// 展示文本框
this.inputVisible = true
this.$refs.ipt.focus()
}
}
}
6.this.$nextTick(cb)方法
组件的this.$nextTick(cb)方法,会把cb回调推迟到下一个DOM更新周期之后执行
通俗:等组件的DOM异步重新渲染完成后,再执行cb回调函数。从而保证cb回调函数可以操作到最新DOm原生
1.什么是动态组件
动态组件指的是动态切换组件的显示与隐藏,vue提供了一个内置的
专门用来实现组件的动态渲染
通过is属性动态指定要渲染的组件名称
2.如何实现动态组件渲染
App根组件
//点击按钮,动态切换组件的名称
//is属性 动态指定要渲染的组件的名称
data(){
return{
comName:'MyHome' //要渲染的组件
}
},
3. 使用keep-alive保持状态
默认情况下,切换动态组件时无法保持组件的状态,此时可以使用vue内置的
1.什么是插槽
插槽是vue为组件的封装者提供的能力。
允许开发者在封装组件,把不确定的、希望由用户指定的部分定义为插槽
可以把插槽认为是组件封装期间,为用户预留内容的占位符
2.体验插槽的基础用法
在封装组件时,可以通过
MyCom组件 -- 插槽基本的用法
这是第一个
最后
App根组件
---
2.1没有预留插槽的内容会被丢弃
MyCom组件 -- 插槽基本的用法
这是第一个
//就是一定要定义slot
最后
App根组件
---
2.2后备内容
封装组件时,可以为预留的
则后背内容会生效
这是第一个
后备内容
最后
3.具名插槽
如果在封装组件时需要预留多个插槽节点,则需要为每个
这种带有具体名称的插槽叫做具名插槽
asd
adsfadsfas
adsffas
addsfas
afas
注意:没有指定name名称的插槽会有隐含的名称叫做default
3.2具名插槽的简写形式
跟v-on和v-bind一样,v-slot也有缩写
即把参数之前的所有内容(v-slot:)替换为字体#
4.作用域插槽
在封装组件的过程中,可以为预留的
这种带有props数据的
这是TEST 组件
{{ scoped }}
4.1 结构作用域插槽的Prop
{{ scoped }}
infomation:{
phone:'1232312312',
address:'八十多'
}
1.什么是自定义指令
vue官方提供了v-for v-model v-if等常用的内置指令
除此之外vue还允许开发中自定义指令
vue中的自定义指令分两类,分别是:
私有自定义指令
全局自定义指令
2.声明私有自定义指令的语法
在每个vue组件中 可以在directives节点下声明私有自定义指令
directives:{
私有自定义指令
focus:{
//当被绑定的元素插入到DOM中时,自动触发mounte()函数
//el就是当前指令所绑定到的那个DOM元素
mounted(el){
el.focus()//让被绑定的元素自动获取焦点
}
}
}
3.声明全局自定义指令的语法
const app =createApp(App)
app.directive('focus',{
//当被绑定的元素插入到DOM 自动触发mounted函数
mounted(el){
//Focus the element
el.focus()
}
})
4. updated函数
vue2里是update,vue3里是updated
mounted函数只在元素第一次插入DOM时被调用,当DOM更新时mounted函数不会被触发
updated函数会在每次DOM更新完成后被调用。
app.directive('focus',{
mounted(el){ //第一次插入DOM时触发这个函数
el.focus()
},
updated(el){ //每次DOM更新时都会触发updated函数
el.focus()
}
})
注意:在vue2的项目中使用自定义指令时,[mounted -> bind] [updated -> update]
5.函数简写
如果mounted和updated函数中的逻辑完全相同,则可以简写
app.directive('focus',(el)=>{
el.focus()
})
6.指令的参数值
在绑定指令时,可以通过等号的形式为指令绑定具体的参数值
MyHome组件---{{ count }}
自定义v-color指令
app.directive('color',(el,binding)=>{
//binding.value就是通过等号为指令绑定的值
el.style.color=binding.value
})
能够说出前端路由工作的过程
能够知道如何在vue3中配置路由
能够知道如何使用嵌套路由
能够知道如何实现动态路由匹配
能够知道如何使用编程式导航
能够知道如何使用导航守卫
1.什么是路由
路由就是对应关系。路由分为两大类
后端路由
前端路由
2.后端路由
后端路由指的是:请求方式 请求地址与function处理函数之间的对应关系
在node.js中 express路由的基本用法
3.SPA与前端路由
SPA指的是一个web网站只有唯一的一个html页面 所有组件的展示与切换都在这唯一的一个页面内完成
此时,不同组件之间的切换需要通过前端路由来实现
结论:在SPA项目中 不同功能之间的切换 要依赖于前端路由来完成
4.什么是前端路由
概念:Hash地址与组件之间的对应关系
5.前端路由的工作方式
用户点击了页面上的路由链接
导致了URL地址中的Hash的值发送了变化
前端路由监听了到Hash地址的变化
前端路由把当前Hash地址对应的组件渲染在浏览器中
结论:前端路由Hash地址与组件之间的对应关系
vue-router是vue.js官方给出的路由解决方案。
它只能结合vuw项目进行使用,能够使用的管理SPA项目中组件的切换
2.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 https://next.router.vuejs.org/
3.vue-router 4.x的基本使用步骤
在项目中安装vue-router
定义路由组件
声明路由链接和占位符
创建路由模块
导入并挂载路由模块
3.1 在项目中安装vue-router
在vue3的项目中,只能安装并使用1vue-router 4.x 安装的命令如下
npm install vue-router@next -S
3.2 定义路由组件
在项目中定义MyAbout,MyHome,MyMovie,将来要使用vue-router来控制它们的展示与切换
3.3声明路由链接和占位符
可以使用
3.4 创建路由模块
在项目router.js路由模块 在其中按照如下4个步骤创建并得到路由的实例对象
从vue-router中按需导入两个方法
createRouter方法用于创建路由的实例对象
createWebHashHistory用于指定路由的工作模式
import {createRouter,createWebHashHistory} from 'vue-router'
创建路由实例对象
import {createRouter,createWebHashHistory} from 'vue-router'
import About from './MyAbout.vue'
import Home from'./MyHome.vue'
import Movie from './MyMovie.vue'
const router = createRouter({
history:createWebHashHistory(),
routes:[
{path:'/home',component:Home},
{path:'/movie',component:Movie},
{path:'/about',component:About}
]
})
export default router
vur-router的高级用法
1.路由重定向
路由重定向指的是:用户在访问A的时候,强制用户跳转到C 从而展示特定的组件页面
通过路由规则的redirect属性,指定一个新的路由地址 可以很方便地设置路由的重定向
const router = createRouter({
history:createWebHashHistory(),
routes:[
// 其中,path表示需要被重定向的原地址 redirect表示将要被重定向到的新地址
{path:'/',redirect:'/home'}.
{path:'/home',component:Home},
{path:'/movie',component:Movie},
{path:'/about',component:About}
]
})
2.路由高亮
可以通过如下的两种方式,讲激活的路由链接进行高亮显示
使用默认的高亮class类
自定义路由高亮的class类
2.1 默认的高亮class类
被激活的路由链接,默认会应用一个叫做router-link-active的类名
开发中使用此类目选择器 为激活的路由链接设置高亮的样式
.router-link-active{
background-color: red;
color: white;
font-weight: bold;
}
2.2 自定义路由高亮的class类
在创建路由的实例对象时,开发中可以基于linkActiveClass属性,自定义路由链接被激活时所应用的类名
const router = createRouter({
history:createWebHashHistory(),
linkActiveClass:'active-router',
routes:[
// 其中,path表示需要被重定向的原地址 redirect表示将要被重定向到的新地址
{path:'/',redirect:'/home'},
{path:'/home',component:Home},
{path:'/movie',component:Movie},
{path:'/about',component:About}
]
})
.active-router{
background-color: blue;
color: white;
font-weight: bold;
}
3.嵌套路由
通过路由实现路由的嵌套展示,叫做嵌套路由
1 声明子路由链接和子路由占位符
2 父路由规则中,通过children属性嵌套声明子路由规则
3.1 声明子路由链接和子路由占位符
MyAbout组件
Tab1
Tab2
3.2 通过children属性声明子路由规则
在router.js路由模块中,导入需要的组件,并使用children属性声明子路由规则
const router = createRouter({
history:createWebHashHistory(),
linkActiveClass:'active-router',
routes:[
// 其中,path表示需要被重定向的原地址 redirect表示将要被重定向到的新地址
{path:'/',redirect:'/home'},
{path:'/home',component:Home},
{path:'/movie',component:Movie},
{path:'/about',component:About,
// 通过children属性嵌套声明子级路由规则
children:[
{path:'tab1',component:'Tab1'},
{path:'tab2',component:'Tab2'},
]}
]
})
4. 动态路由匹配
电影1
电影2
电影3
定义如下3个路由规则,是否可行
{path:'/movie1',component:Movie},
{path:'/movie2',component:Movie},
{path:'/movie3',component:Movie},
缺点:路由规则的复用性差
4.1 动态路由的概念
动态路由指的是:把Hash地址中可变的部分定义为参数项,从而提高路由规则的复用性
在vue-router中使用英文的冒号(:)来定义路由的参数项
// 路由中的动态参数以:进行声明.冒号后面的时动态参数的名称
{path:'./movie/:id',component:Movie}
//将以下3个路由规则,合并成了一个,提高了路由规则的复用性
{path:'/movie1',component:Movie},
{path:'/movie2',component:Movie},
{path:'/movie3',component:Movie},
4.2 $route.params参数对象
通过动态路由匹配的方式渲染出来的组件中,可以使用$route.params对象访问动态匹配的参数值
MyMovie组件---{{$route.params.id}}
4.3 使用props接收路由参数
为了简化路由参数的获取形式,vue-router允许在路由规则中开启props传参
{path:'/movie/:id',component:Movie,props:true},
MyMovie组件---{{id}}
通过调用API编程式导航的方式,叫做编程式导航。与之对应,
通过点击链接实现导航的方式,叫做声明式导航
普通网页中点击链接,vue项目中点击
普通网页中调用location.href跳转到新页面的方式,属于编程式导航
5.1 vue-router中的编程式导航API
vue-router提供了许多编程式导航的API,其中最常用的两个API分别是
this.$router.push('hash地址')
跳转到指定Hash地址,从而展示对应的组件
this.$router.go(数值n)
实现导航历史的前进、后退
5.2 $router.push
调用$router.push()方法 可以跳转到指定的hash地址,从而展示对应的组件页面
MyMovie组件---{{id}}
5.2 $router.go
调用this.$router.go()方法 可以在浏览历史中进行前进和后退。
6. 命名路由
通过name属性为路由规则定义名称的方式,叫做命名路由。
{path:'/movie/:id',
component:Movie,
name:'mov',
props:true},
注意:命名路由的name值不能重复,必须保持唯一性
6.1 使用命名路由实现声明式导航
为
期间还可以用params属性指定跳转期间要携带的路由参数。
6.2 使用命名路由实现编程式导航
调用push函数期间指定一个对象,name是要跳转到的路由规则,params是携带的路由参数
methods:{
goTOMovie(id){
this.$router.push({
name:'mov',
params:{
id:id,
}
})
}
}
7 导航守卫
导航守卫可以控制路由的访问权限
7.1如何声明全局导航守卫
全局导航守卫会拦截每个路由规则,从而对每个路由进行访问控制的权限,
const router = createRouter({...})
调用路由实例对象beforeEach函数 称全局导航守卫
fn必须是一个函数,每次拦截路由的请求,都会调用fn进行处理
因此fn叫做守卫方法
router.beforeEach(()=>{
console.log('ok');
})
7.2 守卫方法的3个形参
全局导航守卫的守卫方法中接收到3个形参
const router = createRouter({...})
调用路由实例对象beforeEach函数 称全局导航守卫
fn必须是一个函数,每次拦截路由的请求,都会调用fn进行处理
因此fn叫做守卫方法
router.beforeEach((to,from,next)=>{
//to 目标路由对象
//from 当前导航正要离开的路由对象
//next 是一个函数,表示放行
})
注意:
1 在守卫方法中如果不声明next形参,则默认允许用户访问每一个路由
2 在守卫方法中如果声明了next形参,则必须调用next()函数 否允许用户访问任何一个路由
7.3 next函数的3种调用方式
直接放行:next()
强制其停留在当前页面:next(false)
强制其跳转到指定页面:next('/login')
7.4 结合token控制后台主页的访问权限
router.beforeEach((to,from,next)=>{
const tokenStr = localStorage.getItem('token') 1.读取token
if(to.path === '/main' && !tokenStr){ 2. 访问后台主页且token
//next(false) //3.1不允许跳转
next('/login') //3.2强制跳转到登录页面
}else{
next() // 3.3 直接放行 允许访问后台主页
}
})
能够知道如何使用vue-cli创建vue项目
能够知道如何在项目中安装与配置element-ui
能够知道element-ui中常见组件的用法
能够知道如何知道axios中的拦截器
能够知道如何配置proxy接口代理
vue-cli
1.什么是vue-cli
vue-cli(vue脚手架)是vue官方提供的,快速生成vue工程化项目的工具
特点:
开箱即用
基于webpack
功能丰富且易于扩展
支持创建vue2和vue3的项目
vue-cli的中文官网首页:https://cli.vuejs.org/zh/
2.安装vue-cli
vue-cli是基于Node.js开发出来的工具,因此需要使用npm将它安装为全局可用的工具:
全局安装 vue-cli
npm install -g@vue/cli
查看vue-cli的版本
vue --version
2.1 解决Windows PowerShell不识别vue的问题
默认情况下 在PowerShell中执行vue--version命令会提示如下的错误信息
解决方案
以管理员身份运行PowerShell
执行 set-ExecutionPolicy RemoteSigned命令
输入字符Y 回车即可
3.创建项目
vue-cli提供了创建项目的两种方式:
基于命令行的方式创建vue项目
vue create 项目名称
基于可视化面板创建vue项目
vue ui
4.基于vue ui创建vue项目
1 在终端下运行vue ui命令, 自动在浏览器中打开创建项目的可视化面板
2 在详情页面填写项目名称
3 在预设页面选择手动配置项目:
4 在功能页面勾选需要安装的功能(less配置文件 CSS预处理器)
5 在配置页面勾选vue的版本和需要的预处理器
6 将刚才所有的配置保持为预设(模板)方便下一次创建项目时直接复用之前的配置
7 创建项目并自动安装依赖包:
vue ui的本质: 通过可视化的面板采集到用户的配置信息后,在后台基于命令行的方式自动初始化项目:
4.基于vue ui创建vue项目
项目创建完成后,自动进入项目仪表盘:
5.基于命令行创建vue项目
1 在终端下运行vue create deomo2命令 基于交互式的命令行创建vue的项目
6在vue2的项目中使用路由
vue2的项目中,只能安装并使用3.x版本的vue-router
版本3和版本4的路由最主要的区别:创建路由模块的方式不同
1.什么是vue组件库
在实际开发中 前端开发者可以把自己封装的.vue组件整理、打包并发布为npm的包,从而供其他人下载
和使用。这种可以直接下载并在项目中使用的现成组件,就叫做vue组件库
2.vue组件库和bootstrap的区别
二者之间存在本质的区别
bootstrap只提供了纯粹的原材料(css样式 HTML结构以及JS特效),需要由开发者做进一步的组装和改造
vue组件库是遵循vue语法、高度定制的现成组件,开箱即用
3.最常用的vue组件库
PC端
Element UI
View UI
移动端
Mint UI
Vant
4.Element UI
Element UI是饿了么前端团队开源的一套PC端vue组件库。支持vue2和vue3的使用
vue2的项目使用旧版的Element UI
vue3的项目使用新版的Element Plus
4.1在vue2的项目中安装element-ui
npm i element-ui -S
4.2 引入Element UI
开发中可以一次性完整引入所有的Element UI组件,或者是根据需求,只按需引入用到Element UI组件
完整引入:操作简单 但是会额外引入一些用不到的组件,导致项目体积过大
按需引入:操作相对复杂一些,但是只会引入用到的组件,能起到优化项目体积的目的
4.3 完整引入
在main.js中写入以下内容
import Vue from 'vue'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import App from './App.vue'
Vue.use(ElementUI)
new Vue({
el: '#app',
render: h => h(App)
})
4.4按需导入
借助babel-plugin-component,可以只引入需要的组件,以达到减小项目体积的目的
安装babel-plugin-component
npm install babel-plugin-component -D
修改根目录下的babel.config.js配置文件 新增plugins节点
{
"plugins": [["component", [
{
"libraryName": "element-ui",
"styleLibraryName": "theme-chalk"
}
]]]
}
如果只希望引入部分组件,比如Button 那么需要在main.js以下内容
4.5 把组件的导入和注册封装为独立的模块
在src目录下新建elemen-ui/index.js模块,并声明如下的代码
/src/element-ui/index.js
import Vue from 'vue'
//按需导入 element ui的组件
import {Button,Input} from 'element-ui'
注册需要的组件
Vue.use(Button)
Vue.use(Input)
//在main.js中导入
import './element-ui'
1.回顾:在vue3的项目中全局配置axios
import axios from ‘./axios’
//配置请求根路径
axios.defaults.baseURL = 'https://www.escook.cn'
//全局配置axios
app.config.globalProperties.$http = axios
2.在vue2的项目中全局配置axios
需要在main.js入口文件中,通过Vue构造函数的prototype原型对象全局配置axios
import axios from ‘./axios’
//配置请求根路径
axios.defaults.baseURL = 'https://www.escook.cn'
//通过vue构造函数的原型对象
Vue.prototype.$http = axios
3.什么是拦截器
拦截器会在每次发起ajax请求和得到响应的时候会自动被触发
应用场景
ToKen身份认证
Loading效果
etc
4配置请求拦截器
通过axios.interceptors.request.use(成功回调,失败回调)可以配置请求拦截器。
axios.interceptors.request.use(function(config){
//return config;
},function(error){
return Promise.reject(error);
}
})
注意失败的回调函数可以被省略
4.1请求拦截器-Token认证
import axios from ‘./axios’
//配置请求根路径
axios.defaults.baseURL = 'https://www.escook.cn'
axios.interceptors.request.use(function(config){
//为当前请求配置Token认证字段
config.headers.Authorization = 'Bearer xxx'
//Authorization是自定义的
//固定用法
return config;
})
Vue.prototype.$http = axios
4.2 请求拦截器 - 展示Loading效果
借助于element ui 提供的Loading效果组件
可以方便的实现Loading效果的展示
//按需导入 element ui的组件
import {Loading} from 'element-ui'
let loadingInstance = null
import axios from ‘./axios’
axios.defaults.baseURL = 'https://www.escook.cn'
axios.interceptors.request.use(function(config){
//展示Loading效果
loadingInstance = Loading.service({fullscreen:true})
config.headers.Authorization = 'Bearer xxx'
return config;
})
Vue.prototype.$http = axios
5.配置响应拦截器
通过axios.interceptors.request.use(成功回调,失败回调)可以配置响应拦截器
axios.interceptors.request.use(function(response){
return response
},function(error){
return Promise.reject(error)
})
注意失败的回调函数可以被省略
5.1 响应拦截器 - 关闭Loading效果
通过Loading实例提供的close()方法即可关闭Loading效果
axios.interceptors.request.use(function(response){
//调用Loading实例close()方法即可关闭Loading效果
loadingInstance.close()
return response
})
proxy跨域代理
1.回顾:接口的跨域问题
vue项目运行的地址:http//localhost:8080/
API接口运行的地址:https://www.escook.cn/api/users
由于当前的API接口没有开启CORS跨域资源共享,因此默认情况下,上面的接口无法请求成功
2.通过代理解决接口的跨域问题
通过vue-cli场景的项目在遇到接口跨域问题时,可以通过代理的方式来解决:
1把axios的请求根路径设置为vue项目的运行地址
2vue项目发现请求的接口不存在,把请求转交给proxy代理
3代理把请求根路径替换为devServer.proxy属性的值,发起真正的数据请求
4代理把请求到的数据,转发给axios
3.在项目中配置proxy代理
在main.js入口文件中 把axios的请求根路径改为当前web项目的根路径
//配置请求根路径
axios.defaults.baseURL = 'http://localhost:8080'
在项目根路径下创建vue.config.js的配置文件
module.exports={
devServer:{
//当前项目在开发调试阶段
//
proxy:'https://www.escook.cn'
}
}
注意
devServer.proxy提供的代理功能,仅在开发调试阶段生效
项目上线发布时,依旧需要API接口服务器开启CORS跨域资源共享