vue学习
一、了解vue
1.Vue 是一套用于构建用户界面的渐进式框架
2.Vue 只关注视图层, 采用自底向上增量开发的设计。
3.Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。
4.Vue架构模式,是mvvm(双向数据绑定)
Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。
二、使用vue
1.导入连接
在html页面用链接直接使用
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<!-- 生产环境版本,优化了尺寸和速度 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
2.直接引用文件
保存vue文件到本地,使用script导入本地 vue.js 文件。
3.语法使用
可以在控制台修改message信息,浏览器实时更新。数据和DOM已经建立关系,成响应式
对象名.属性名 可以修改数据
app.message=""
4.vue2响应式原理-深入响应式原理
vue2底层使用 es5 ,vue3 使用es6
vue2 的响应式原理:你把js对象传入到vue中,作为data选项,vue会遍历传入对象所有的property,并使用使用 Object.defineproperty。把这些property 全部转换为 getter/setter。
当你把一个普通的 JavaScript 对象传入 Vue 实例作为 data 选项,Vue 将遍历此对象所有的 property,并使用 Object.defineProperty 把这些 property 全部转为 getter/setter。Object.defineProperty 是 ES5 中一个无法 shim 的特性,这也就是 Vue 不支持 IE8 以及更低版本浏览器的原因
Object.defineproperty(对象,创建的对象属性名,{函数})
/**vue2深入响应式原理**/
//创建对象
var obj={
}
//创建属性
Object.defineProperty(obj,"myname",{
get(){
console.log('使用了get方法');
},
//括号里写上value可以查看值,不写也可以
set(value){
console.log("使用了set方法"+value)
}
})
当你把js对象传入vue实例中作为data选项,vue会遍历传入对象的所有property,并使用 Object.definepproperty ,把 property 全部转换为getter/setter。 每一个组件实例都会有一个 watcher 观察者,watcher 会在组件渲染过程中接触到的 property 全部记录成 依赖。之后当依赖的setter触发的时候,会通知 watcher ,从而使他关联的组件从新渲染。
组件渲染 生成虚拟dom树,后期修改了参数,会生成新的虚拟dom 树,新的虚拟dom树 和 老的虚拟 dom树 进行对比 用diff 对比,用小补丁 更新真实dom。
为什么不直接生成真实dom,真实dom属性很多,浪费内存。
5.模板语法
插值
模板语法在页面中用双大括号 {{}} 进行数据绑定, 用来文本插值, 可以写参数和表达式 。vue.js 支持js的写法。
<!-- 完整语法 -->
<a v-bind:href="url">...</a>
<!-- 缩写 -->
<a :href="url">...</a>
<!-- 动态参数的缩写 (2.6.0+) -->
<a :[key]="url"> ... </a>
<!-- 完整语法 -->
<a v-on:click="doSomething">...</a>
<!-- 缩写 -->
<a @click="doSomething">...</a>
<!-- 动态参数的缩写 (2.6.0+) -->
<a @[event]="doSomething"> ... </a>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style type="text/css">
.red{
background-color: red;
}
.yellow{
background-color: yellow;
}
</style>
<script src="../lib/vue.js"></script>
</head>
<body>
<div id="box">
我是 {{name}},{{age}}岁.
{{10>20? 'aaa':'大括号可以放表达式'}}
<!-- 监听事件 -->
<button @click="changeValue()">change</button>
<!-- 属性绑定 -->
<div :class="bc">
切换背景颜色
</div>
<div :class="isColor? 'red':'yellow'">
切换背景颜色之表达式
</div>
<!-- 显示隐藏 和 插入删除 -->
<div v-show="isShow">我是动态隐藏和显示</div>
<div v-if="isCreate">我是动态创建和删除</div>
<!-- 图片绑定属性 -->
<img :src="imgpath"/>
<!-- v-for 循环 渲染 -->
<ul>
<!-- 随便用一个变量接收list数组 -->
<li v-for="data in list" >
<!-- 显示数组内容 -->
{{data}}
</li>
<!-- 还可以查看下标 -->
<li v-for="(item,index) in list">{{item}}---{{index}}</li>
</ul>
</div>
<script type="text/javascript">
new Vue({
//绑定dom
el:'#box',
//数据对象
data:{
name:"su",
age:19,
bc:"red",
isColor:true,
isShow:false,
isCreate:false,
imgpath:"",
list:['aaa','bbb','ccc','ddd']
},
//方法
methods:{
changeValue(){
console.log("点击绑定方法生效",this)
this.name="sumq";
this.age=28;
this.bc='yellow';
this.isColor=!this.isColor; //取反 可以来回切换两个格式
this.isShow=!this.isShow;
this.isCreate=!this.isCreate;
this.imgpath="https://github.com/yyx990803.png"
}
}
})
</script>
</body>
</html>
指令
指令是带有 v- 前缀的特殊属性。
指令用于在表达式的值改变时,将某些行为应用到 DOM 上。
v-html : html语法中绑定dom,用于输出html代码,你的站点上动态渲染的任意 HTML 可能会非常危险,因为它很容易导致 XSS 攻击。请只对可信内容使用 HTML 插值,绝不要对用户提供的内容使用插值。
v-bind : html 属性值 用v-bind绑定。把html 标签的属性和参数或表达式绑定。他的缩写是 冒号
v-on: 用来监听绑定事件,缩写用@
v-if:v-if 指令将根据表达式的值的真假来插入/移除,真的就插入,假的就移除。
v-else:取v-if的反值。
v-show:用来对表达式的值进行 显示/隐藏,假的就隐藏,真的就显示。
v-for:用来循环遍历数组,达到渲染的效果。
v-model: 双向绑定表单
6.Vue2动态添加class、style
VUe2动态添加属性,只能通过 Vue.set(对象名,属性名,值), 添加dd。
动态添加后就会拦截到,就会对属性生成getter setter方法。
Vue3 可以自动增加动态拦截
Vue2 可以用数组的方法,来动态添加/删除 class
Vue.数组.push(数值) 添加
Vue.数组.splice(1,1) 删除 根据位置删除
使用对象 动态添加属性,vue2拦截不到,需要用 Vue.set()添加,进行动态拦截。
使用数组 比较方便,直接添加数据,修改的话直接覆盖。
<!-- 动态绑定 切换 class -->
<body>
<!-- 利用对象进行class切换,通过对变量的值进行更改达到切换的目的 style同理 -->
<div id="box" :class="classobj">
动态切换-利用对象切换
<div :class="classlist">动态切换clas-利用数组切换</div>
</div>
<script type="text/javascript">
var vm =new Vue({
el:"#box",
data: {
classobj: {
// VUe2动态添加属性,只能通过 Vue.set(对象名,属性名,值), 添加dd。
//添加后就会拦截到,就会对属性生成getter setter方法。
// Vue3 可以自动增加动态拦截
aa: true,
bb: true,
cc: false,
},
// Vue2 可以用数组的方法,来动态添加/删除 class
// Vue.数组.push(数值) 添加
// Vue.数组.splice(1,1) 删除 根据位置删除
classlist:["aa","bb"]
}
})
</script>
</body>
7.Vue3 动态添加属性
vue3的声明式渲染语法做了些改变,去除了new vue 对象的声明方式,改为使用Vue.createApp(传入obj).mount(绑定的dom。创建一个对象,封装了data,用return 将对象属性抛出。
vue3不需要 vue2中的Vue.set()添加对象属性。Vue3自动拦截对象属性
<!-- Vue3 的使用创建 -->
<body>
<div id="box">
{{myname}} {{10+10}}
<input type="text" v-model="myname">
<div v-if="isShow">1111</div>
<div v-else>222222</div>
</div>
<!--
vue3使用创建
-->
<script type="text/javascript">
var obj={
data(){
return{
myname:"sususu",
isShow:true
}
},
methods:{
}
}
Vue.createApp(obj).mount("#box")
</script>
</body>
8.条件渲染
使用v-if、v-else-if、v-else 进行渲染
当接口传来的数据需要 对应不同的显示结果 可以用条件渲染来完成。
<!-- 根据接口返回的数据 进行条件渲染 -->
<body>
<div id="box">
{{showOrder}}
<ul>
<li v-for="item in orderList">
{{item.title}}----
<span v-if="item.state===0">待支付</span>
<span v-else-if="item.state===1">已支付</span>
<span v-else-if="item.state===2">已发货</span>
<span v-if="item.state===3">已签收</span>
</li>
</ul>
</div>
<script type="text/javascript">
new Vue({
el:"#box",
data:{
showOrder:"订单信息页",
orderList:[
{
title:"笔记本",
state:0
},
{
title:"鼠标",
state:1
},
{
title:"键盘",
state:2
},
{
title:"uPan",
state:3
},
{
title:"随机盲盒",
state:1
},
]
},
methods:{
}
})
</script>
</body>
9.vue包装元素 template
template 是一个包装元素,不会创建在页面上。如果想一起操作多个 dom 显示隐藏,不能用div 会破坏 dom 结构,可以用template。 template 是vue的 选项式 API。template 不会破坏 dom 结构。
<template v-if="te">
<div>123</div>
<div>123</div>
<div>123</div>
<div>123</div>
</template>
10.列表渲染
列表渲染 用 v-for。 可以对列表或者数组进行循环遍历 ,设置key。
为什么设置key:
为了虚拟dom对比方便,不能用 index。 为了节点的复用和排序。减少重复dom的创建。 索引值不适合作为key,如果从中间添加删除数据,数据对比麻烦 。理想的key 唯一不重复。
vue2操作数组有的方法会被检测到,并且更新dom,有的方法不会被检测,需要注意。
直接用数组下标 修改数据 检测不到。可以用vue.set进行更改,或者用splice方法
<!-- vue2列表渲染 -->
<body>
<div id="box">
<ul>
<li v-for="item in list" :key="item.id">
{{item}} 可以对数组遍历
</li>
</ul>
<ul>
<li v-for="item in obj">
{{item}} 可以遍历对象,遍历出所有属性值
</li>
</ul>
<ul>
<li v-for="item in 10">
{{item}} 1-10
</li>
</ul>
</div>
<script type="text/javascript">
var vm= new Vue({
el:"#box",
data:{
list:["aa","bb","cc"], //vue2修改数的参数 有的方法可以检测到,有的方法检测不到。还要注意 数组下标修改参数不会被检测到。
obj:{
name:"sususu",
age:18
}
}
})
</script>
</body>
<!-- vue3列表渲染 -->
<body>
<div id="box">
<ul>
<li v-for="item in datalist" :key="item">
{{item}}
</li>
</ul>
</div>
<script type="text/javascript">
var vm= Vue.createApp({
data(){
return{
datalist:[111,222,333] //可以直接修改数组的下标值,vue3可以检测到
}
}
}).mount("#box")
</script>
11.vue3函数表达式应用
函数也可以用在 指令中 和双大括号中。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="../lib/vue.global.js"></script>
</head>
<!-- 搜索框,输入搜索的数据,模糊查询 函数表达式 -->
<body>
<div id="box">
<input type="text" @input="handleInput()" v-model="myinput"/>
<ul>
<li v-for="item in dataSerch()":key="item" >
{{item}}
</li>
</ul>
</div>
<script type="text/javascript">
var vm= Vue.createApp({
data(){
return{
datalist:["aaa","bb","cc","dd","abc","bac"],
myinput:"",
}
},
methods:{
dataSerch(){
//filter(写回调函数,用来返回查询条件) 过滤函数 用来过滤给出的条件,生成新的数组
//数组元素一个一个和条件对比,满足条件,生成新的数组返回。
//includes() 检索函数,对数组的所有元素 进行对比,满足的返回true。
return this.datalist.filter(item=>item.includes(this.myinput))
}
}
}).mount("#box");
</script>
</body>
</html>
12.事件处理器
事件处理器就是,触发事件,执行事件绑定的函数(函数叫做处理方法)。
绑定的函数 不加括号 ,可以获取evt 事件对象,调用evt.target 可以获取标签元素。写上括号无法获取。
<button @click=“handleadd1($event,1,2)”> 在括号中加入后 就可以 即获得event和参数了。
事件类型
input事件:写入的文本实时更新
change事件:当文本框失去焦点的时候才会触发。
<body>
<div id="box">
{{count}}
<button @click="handleadd1($event,1,2)">
add1
</button>
<button @click="handleadd2">
add2
</button>
<button @click="count++">
add3
</button>
</div>
<script type="text/javascript">
var vm=Vue.createApp({
data(){
return{
count:1
}
},
methods:{
handleadd1(){
this.count++
},
handleadd2(evt){
console.log(evt.target)
this.count++
}
}
}).mount("#box")
</script>
</body>
13.事件修饰符
.self 作用在父节点上,阻止事件冒泡,防止所有子节点的冒泡。
.stop 作用在子节点,可以对单个子节点阻止事件冒泡。
什么时候阻止事件冒泡:做模态框的案列,点击某个按钮会弹出对话框,不阻止事件冒泡肯能会
14.按键修饰符
只能绑定在 keyup上 ,如果还有其他的键想用,直接 .键值
15.表单绑定
应用场景:在多选框,单选框表单中使用
<body>
<div id="box">
{{mytext}}{{checkList}}
<textarea v-model="mytext"></textarea>
<div>
<label>
用户名:<input type="text" v-model="mytext" />
</label>
<!-- 多选绑定事件,用一个数组来接收选择的值,写上value(随便起名) -->
<input type="checkbox" v-model="checkList" value="vue">Vue
<input type="checkbox" v-model="checkList" value="re">react
<input type="checkbox" v-model="checkList" value="wx">小程序
</div>
<!-- 一个选择框 用变量来接收,方便判断 布尔值 -->
<input type="checkbox" v-model="isRemember"/>记住用户名
<!-- 多个值选一个。用字符串来实现,这样就会保存一个值-->
<input type="radio"/ v-model="sex" value="man">男
<input type="radio" v-model="sex" value="woman"/>女
<button @click="handleLogin">登陆</button>
</div>
<script type="text/javascript">
var vm=Vue.createApp({
data(){
return{
mytext:localStorage.getItem("username"),
isRemember:false,
checkList:[],
sex:""
}
},
methods:{
handleLogin(){
if(this.isRemember){
localStorage.setItem("username",this.mytext)
console.log("保存成功")
}
}
}
}).mount("#box")
</script>
</body>
16.表单修饰符
lazy修饰符,会在表单失去焦点后更新数据
number修饰符。vue表单绑定输出的数字也是字符串,如果想要转换成数字类型,用number修饰符将字符串数字转换为数字类型。
trim修饰符,去除首位空格,不会去除中间的空格
17.计算属性computed
在模板中,表达式在页面中不可取,写的太长。
计算属性computed:临时存在缓存中,有缓存,多次调用只用一次的结果,用来处理计算。不用写括号。
方法:一般用于事件中写方法,作为事件处理器。在页面中调用几次执行几次。放在methods中
计算属性:是为了防止模板过重,难以维护,负责逻辑放在计算中来写。计算属性有缓存,临时缓存,基于依赖的缓存,依赖改一次,计算属性重新计算一次。依赖改变后,计算属性立即发生改变,在同步中好用,异步中不好用。必须有return
18.watch
用来监听一个值,重视的是过程,不用返回值,异步同步都支持。
监听的值对应一个监听方法,监听的值,和写入watch的方法名一致。
-computed和watch区别
三、异步请求数据
1.fetch
fetch-get
fetch也是一个标准和XMLHttpRequest一样
第一个then只能获取状态码,响应头,拿不到真正的数据
只有返回res.json 在下一个then中才能拿到真正的数据
不做处理可以简写方法
fetch-post
post请求 为什么需要请求头:需要前后端数据一样,双方对接,看看要什么格式。
一个明文格式,一个json格式
2.axios
不是标准,属于第三方库,需要引入文件
axios 把数据封装在data中。
axios post请求,直接调用,他会根据你传入的数据进行分析,你传入的是数据还是对象。
3.异步数据或样式加载失败
有时候用数据获取加载不上样式,可以给上一层组件加数组长度,等获取数据后加载样式
四、可复用性
1.过滤器 vue.filter
vue2的过滤器,vue3不支持
语法:需要处理的数据 | 处理过程
过滤器的过程可以写一个,也可以写多个
五、组件component
组件是vue最强大的功能之一。
为什么用组件:组件可以扩展HTML元素,封装可重用的代码。
一个组件是把dom、css、js、封装在一起。可以多次调用。
组件命名要用 - 隔开 例如:but-abc
全局组件要在根组件的前面注册。
组件之间互相访问不到数据。通过通信来交流,newVue 属于根组件。
组件分为 全局组件和局部组件
1.全局组件
定义一个全局组件,其他的语法都和vue一样。 子组件写在父组件的里面,
子组件也是全局组件。 全局组件写在哪个模板语法里,他就是哪个父组件的子组件
命名法则
组件的问题:
template必须是一个根节点,不能有兄弟节点
2.局部组件
局部组件写在全局组件里,只能在全局组件的模板用,拿到页面中无法使用。
-Vue3创建组件
vue3中先创建对象,在对象上使用compnent方法
3.组件父传子props
应用场景:父传子 为了复用组件里的值达到不同的显示效果。
父组件 接收一个name的变量 传给子组件们使用。在div标签里面使用都可以,写在div标签外使用就会报错。 通过属性来传值。
如果是在根组件放置一个属性,要在全局组件中使用,可以给全局组件创建一个属性动态绑定来接收 根组件的值。
-props和data优先级
加载顺序是 props-methods-data-computed-watch
4.属性验证
进行属性验证后可以用对象接收属性值。还可以加入默认值
5.组件子传父
应用场景:通过事件将子组件的属性给父组件。父组件用自定义的事件接收。来达到操作父组件属性的目的。
父组件自定义组件不写参数,可以接收子组件 this.$emit()的返回值,根据需求而定。
6.中间人模式通信
两个不同的子组件进行通信,需要通过父组件来连接。父子组件通信。1子组件将信息给父组件,父组件再给其他子组件。
7.bus中央事件总线
创建一个bus 新vue。一个是订阅者,一个是发布者。 要触发的是订阅者,用bus.$on()
,
要接收的是发布者,用bus.$emit(触发事件)
1.先创建bus
2.在发布者兄弟组件中,刚开始的时候订阅事件
3.兄弟组件写事件函数,在函数中监听触发事件。触发后返回数据给订阅者
8.ref通信组件
ref="随便起名 固定写法 调用:this.$refs.绑定的名"
ref绑定组件,拿到组件对象。父组件可以获子组件的属性值,修改子组件的值。
9.动态组件
vue 内置组件 component
,切换组件不会保存其他组件的输入内容。在component外面加上keep-alive
会保存其他组件的内容,防止切换后输入框的内容消失。
10.slot 插槽-旧版
创建完组件后,在组件里写东西不会进行显示,这时候想要显示就要用到slot
插槽。插槽写在组件的模板中。
插槽的意义:
拓展组件的能力,提高组件的复用性
插槽有 单个插槽 和 具名插槽 两种。单个插槽就是对未定义名的插槽进行显示。插槽会分类,具名的且具名相同的插槽一起显示。单个插槽会在一起显示。
先看单个插槽,没定义名字的都是单个插槽,组件写一个slot
,未定义名字的都会一起显示一遍,写几个slot就会显示几遍。
具名插槽,会进行分类,相同名字的一起显示
插槽的应用场景:
组件模板定义好 插槽的位置,在页面中 想要显示什么就写什么
11.slot 插槽-新版
新版写法用到 v-slot 简写 #
,把内容放在template
中。
组件里面还是用slot
写
六、过渡、动画
1.transition 过渡
vue中提供transition组件。
transition需要配合v-if、v-show
进行使用,把需要动画的内容包裹起来。
提前写的进场离场动画,前面的名字可以随便起,后面的enter-active和leave-active
需要固定写法。
组件复杂写法 transition
里面写好进场离场动画,固定写法
简单写法,这时候 就体现出为什么要给样式固定起名了。
首次显示动画 appear
,添加后第一次显示就会用定义好的动画显示出来。
2.多个元素过渡
transition中只能放一个元素,不能放多个。多个元素是用v-if
的条件判断放入执行的。多个div互斥的可以用。
transition动画 div里的值遍了,却没有动画效果。加上key就好了,运用了vue diff算法和虚拟dom对比。没加key认为div相同,进行复用了,所以没有动画效果。
mode
过渡模式
3.多个组件过渡
4.多个列表过渡
transition-group
5.可复用过渡
将transition
写在组件模板中,组件传入自定义的属性和值,可以修改多个样式方案
七、diff算法
在列表中按照key比较,没有key按照标签比较。
八、生命周期
生命周期函数有八个,对应四个阶段。四个阶段:创建create、挂载mount、更新update、销毁destroy。每个阶段之前之后都有个函数。 在vue3中beforDestroy和destroy
改变成了beforUnmount 和unmounted
前四个生命周期只会初始化一次,是创建阶段。
1.创建生命周期
beforeCreate() 访问不到当前状态没什么用
created() 可以访问状态,可以挂载一些状态并且直接使用。获取this下的属性
2.挂载生命周期
innerHtml是当前节点的子节点,outHtml就是当前节。
beforeMount
3.更新生命周期
更新阶段,更新是无限次的
4.销毁生命周期
销毁阶段,当一个组件销毁的时候,他的定时器,事件绑定还会存在,这种是不合理的,所以要在销毁之前 或销毁后 清除定时器和事件解绑。
-加载新页面声明周期
beforeCreate :没有加载data和el
Create : 加载data 没有el
beforeMounted : 加载data 没有el
Mounted : data 和 el 都加载
如果添加keep-alive(缓存页面),会多两个生命周期activated 和 deactivated。
九、Vue3指令
1.vue2和vue3的改变
vue3创建用的是vue.createApp()
,然后在对象上创建组件,创建完组件后再挂载到节点上。
生命周期的最后两个 destroy
换成了unmount
Vue2用的类的写法,vue3用的类和hooks
2.自定义指令
dom操作的时候用指令。
指令就是对底层dom操作的封装,指令可以拿到底层dom。
指令可以知道什么时候dom创建完成。从而可以依赖dom的库进行初始化工作。
Vue.directive(el)
封装一个自定义指令,el
是使用指令的dom,自带的。在里面操作dom。binding
是个对象
inserted()
是指令第一次插入父节点的生命周期,这时候是可以获取原生节点
update()
是后面更新的生命周期
unbind()
是指令销毁声明周期,在dom销毁后指令还会在,所以当不用指令的时候要进行指令的销毁
简写自定义指令,用回调函数,这样使用指令,dom在创建和更新的时候都会执行回调函数。有的时候可以简写,根据业务情况
vue2指令生命周期
vue3指令生命周期和钩子函数
3.nexttick
只执行一次,没有复用性
十、单文件组件
1.vue-cli 脚手架
如果配合webpack 包管理工具,推荐使用vue-cli。
代码是热更新。
npm install -g @vue/cli
# OR
yarn global add @vue/cli
查看vue版本
vue --version
创建项目
vue create 项目名
创建项目后,选择版本,第三个是自定义选择安装内容,按回车确定,空格选择。
babel 可以把es6代码转换成es5代码
自定义选项
2.项目启动
在package.json 文件中有脚本 ,进行命令启动
npm run serve
启动后得到一个运行环境
main.js 文件
3.eslint修复
统一代码开发风格
1.通过运行 npm run lint 命令
2. 在vscode 中 安装 eslint 插件,在setting.json 文件中添加
//写完保存后自动更正
"editor.codeActiononsave":{
"source.fixAll":true
}
3.关闭eslint
在vue.config.js
中关闭代码检测,提交代码之前执行一次 npm run lint
或者删除下图代码也可以。
4.单文件格式
在template
中写模板,在script
中写js ,可以用es6写法,babel会把es6代码转换成es5。
引入子组件
在子组件文件夹中创建,用es6 import 方式引入,然后再注册组件使用。用全局注册需要再引入vue。
名字随便起的
使用局部注册,不需要引入vue,直接compnents引入文件就行
子组件样式被父组件取代
子组件想要用自己的样式,在自己的文件中加入 scoped
。
5.静态文件引用
vue访问的是public 文件中的静态资源,所需要的静态资源放在public 文件夹中,引用public 直接/文件名
。
6.引入模块
没有的模块可以适用npm 下载后引入到组件中进行使用。
7.自定义指令引入
需要引入vue模块,其他的和以前的一样
8.什么需要写成组件
1.足够独立
2.可复用性强
9.alias别名@
使用webpack引入方式,配置alias,设置符号或名称,使用符号指向路径,省去了写一些../../../
的麻烦
在项目文件jsconfig.json
配置文件中
十一、反向代理devServer
前端访问别人网站的接口,会报跨域错误。可以设置代理,前端访问本地后端,本地后端访问别人服务接口,收到数据返回,前端拿来使用。
直接域名请求会报错
去掉域名, 在vue.config.js
中配置devserver
代理,改完配置重启
多个ajax代理请求时,可以加入自定义的路径,然后用pathRewrite
清除
十二、vue路由
路由实现单页面应用
1.SPA概念单页面应用
2.vue-router
映射表里有路径 ,映射到对应的组件,只需要在url中修改路径,就可以切换到对应的组件
3.router一级路由
main.js
下启动router,指向router文件夹下的index.js
router下的index.js文件,注册完后可以使用<router-view>和<router-link>
传入映射对象,path
对应页面中显示的路径,component 对应路径映射的组件
还需要在app.vue 根组件下引用路由容器<router-view>
才能显示成功
4.路由重定向
应用场景:用户首次进入网站会到.../
的路径下,没有页面,所以需要重定向到指定页面。
在路由下配置重定向路径即可 ,斜杠匹配一个,型号可以都匹配,随机输入的都会到重定向路径
vue同域名,域名可以省略不写
5.声明式导航
location.hash
显示当前路由路径,window.onhashchange
监听路由切换。有这两个方法完成监听切换工作
to 指向router目录下的index.js 配置的routes 路由path。填写自己想要指向的path。active-class
可以自定义 router 的class 样式名称
用上 router-link to
后,路由会根据你点击的link连接,可以添加上自带的class
你可以根据此功能进行样式添加。
router自带class
自定义class名称,方便多组 router-link 使用
自定义标签
vue-router 版本4 写法 插槽式写法,可以自定义配置 新写法
navigate和isActive是固定的
,navigate 外层li标签是自定义的,想用什么就写什么。isActive
是被选中的状态。
6.嵌套路由-二级路由
应用场景:一级路由页面里面需要显示不同的子组件,整体页面不改变。
1.先在一级路由下配置子路由
2.在一级路由的映射页面插入组件
应用场景:列表到详情或 页面搜索
一级路由页面里面显示其他子组件,整体显示子组件,相当于同一个页面能有不同的显示
const routes = [
{
path: '/films',
component: Films,
children: [
{
path: '/films/nowplaing',
component: Nowplaing
},
{
path: '/films/showvideo',
component: ShowVideo
},
{
path: '/films',
redirect: '/films/nowplaing'
}
]
},
{
path: '/films/search',
component: Search
},
7.编程式导航
应用场景:页面跳转
声明式导航可以写几个固定的跳转连接,编程式导航可以写很多个。不固定,可以灵活运用
1.对li添加绑定事件
2.在需要跳转的页面使用vue提供的跳转方法
location.href
属于写死的,只能跳转到#页面。而this.$router.push()
可以根据路由,判断页面路径带不带#,而进行选择
在main.js注册路由。
this.$router
拿到的是router实例对象。this.$route
拿到的是当前匹配的路由信息
8.动态路由
应用场景:列表到详情页面,不确定要到具体那个页面。通过路径跳转
思路:根据后端接口,拿到列表内容,进行布局。点击列表获取列表详情,确定路径id,把路径获取到,向后端请求数据,拿到后布局页面
可以在路由跳转的时候传参,在myid后面加?号,可以在跳转时选择传入params还是不传值。query随便传
1.在路由配置文件下配置路径
在路由配置对应的路径和变化的参数
2.在组件列表展示页面将点击的id传给详情页面
注意下面 router和route
3.在点击后的详情页面里拿到id
4.axios利用id获取详情内容进行布局
9.命名路由
应用场景:列表到详情页面,不确定要到具体那个页面。通过命名路由跳转
可以用route获取路径跳转,也可以使用命名路由跳转,两者选一个使用
1.加上name
2.要跳转的页面
路由名字自定义
3.在跳转后的页面接收数据
-路由传值
1.路由传值方式
$route路由对象
用来获取路由url、params、query等
$router
编程式导航,用来路由跳转页面。有$router.push()和$router.replace()
$router.push()传params和query有三种方式
- 字符串传参
- 模板字符串传参
- 对象传参
对象传参通过{path: ,query}或者{name: ,params: ,query:,}。传params需要动态路由 在路由path加:xxx?
,?的作用是判断params是否为空,防止params为空路径不对。
10.路由模式
在路由index.js
配置文件下 增加mode模式。
带#的网址是前端路由做的。history 路径不带#
注意:使用mode:history,当用户直接访问的时候,会以为是后端接口,而后端没有这样的接口,会直接返回404。需要在后端服务器配置代码
后端服务器配置
11.全局路由拦截-守卫
应用场景:判断用户是否登陆是否授权,可能要在多个页面进行判断,比较繁琐。在路由跳转之前判断一次。在路由配置页面设置index.js
思路:
另一种方法 路由元信息
给路由设置meta
,自定义变量判断是否需要登陆。true/false 是否拦截。
在路由配置页面判断是否拦截和后续登陆操作
query属性判断从哪里来的,可以从地址获取redirect
可以随便取名。方便在登陆后,拦截到之前的地址,跳转回去。登陆完继续去到想去的页面。
登陆页面跳转回去
登陆页面
12.局部路由拦截
由对全部的路由拦截,改为对单个的路由拦截
13.组件内部路由生命周期拦截
写在组件内部的路由拦截
14.路由懒加载
针对首评加载过慢。当打包加载应用时,js打包过大,影响页面加载。如果把不同路由对应的组件分割成不同的代码块,当路由被访问时才加载对应的组件
对于之前的import进行优化
在app.vue
页面中,优化前
router3x版本 使用的是webpack 代码分割功能
router4x版本 支持开箱即用的动态导入,这意味着你可以用动态导入代替静态导入
修改后
15.数据懒加载
十三、vuex-状态管理
工作流
state、mutations、actions、getter、module
1.引用vuex
在脚手架中已经安装好,在store/index.js
已经完成引入进行配置即可。
在state设置公共状态
在App.vue文件中,引入store,并且创建了store全局对象。可以通过调用对象获取对应的公共状态值
js语法中需要用this,模板语法中不需要使用this调用对象
2.mutations
mutation只支持同步请求,不支持异步请求
为了防止公共状态被修改,不知道哪里修改。在mutation中编写对应的方法
在组件中修改用commit提交修改的数据和使用的方法。
3.action
支持异步和同步
1.在store index.js中写入
2.在组件中分发
ui框架
1.element-uiPC端组件库
PC端ui框架,有多个版本,针对vue2/3,react,需要安装不同的版本
npm install element-ui --save
简写
npm i element-ui -S
初始化