文章目录
- VUE
- Vue2.0
- vue特点
- 事件处理
- 键盘事件
- 计算属性
- 监听watch
- 深度监视
- 绑定class样式
- 条件渲染
- 列表渲染
- 列表过滤
- 列表排序
- Vue.set()的使用
- Vue检测数组的原理
- Vue监测原理总结
- 指令
- 生命周期
- Vue component
- Vue配置文件vue.config.JS
- 其他:
- 组件自定义事件
- 组件自定义事件解绑
- 全局事件总线
- $nextTick
- 动画效果
- 配置代理
- vue-resource
- 插槽
- Vuex
- mapState与mapGetters
- 路由
- 路由理解
- 多级路由(嵌套路由)
- 路由传参
- 命名路由
- 路由params参数
- 路由props配置
- 路由router-link的replace属性
- 编程式路由导航
- 缓存路由组件
- 全局路由守卫
- 独享路由守卫
- 组件内路由守卫
- 路由两种工作模式history和hash模式
VUE
Vue2.0
vue特点
- 组件化模式
- 声明式编码
<ul>
<li v-for=""p in persons>
{{p.id}}-{{p.name}}-{{p.age}}
</li>
<ul>
- 使用虚拟dom+diff算法,尽量复用dom节点
事件处理
//示例:
<span @click="smileFnc($event,1000)">000</span>
methods:{
smileFnc(e,val){
console.log(e)
console.log(val)
}
}
//总结:
v-bind => :
v-model => v-model:value => v-model
v-on:click => @click
事件修饰符
$event接收默认事件对象
@click.prevent 阻止默认事件
@click.stop 阻止冒泡
@click.once 事件只触发一次
@click.capture 事件捕获模式,事件捕获阶段就进行处理
@click.self 只有event.target是当前操作元素才触发
@click.passive 事件的默认行为会立即执行,不用等事件回调执行完毕(@wheel等事先执行函数然后执行像是滚动条滚动等页面滚动渲染)
//别名可以连着写 @click.stop.prevent
@scroll 滚动条滚动事件
@wheel 滚轮滚动事件
键盘事件
@keydown
@keyup
//获取键盘值
event.keyCode
//按键别名
@keyup.enter
@keyup.esc
//如果绑定的事件按键没有在常用的里面
获取event.key即这个key的名字,直接@keyup.caps-lock;Capslock要分开加-
tab特殊必须配合keydown使用,因为它有让光标移走的特性
也可以用编码,但是不同键盘编码不一样
@keyup.ctrl.y 需要ctrl
定义别名按键
计算属性
- 初次读取值的时候get会被调用
- 所依赖的数据发生变化的时候会重新调用
computed:{
fullname:{
//当有人调用fullname get就会被调用;computed中的值调用;多次调用执行的时候会被缓存
get(){
return this.firstname+'-'+this.lastname
},
set(value){ //当fullname被修改时候回调用;并且要修改计算时引起变化的依赖数据的值
const arr = value.split('-')
this.firstname = arr[0]
this.lastname = arr[1]
}
}
}
//computed计算属性的 简洁写法,这种写法只限只有get
computed:{
fullname:function(){ //这个函数当作get函数使用 fullname(){}
return firstname+'-'+lastname
}
}
⚠️注意:methods中的数据没有缓存,当模板语法中多次使用回多次调用方法;
⚠️注意:可以方法直接写在@click的计算语句中,不写在method中,但是这样一般只写一些简单的语法;并且
@click
这个里面的只能写vm上面挂的一些方法数据等,比如像是alert这些语法是没有的会报错
监听watch
- watch可以监听data中以及computed中的属性值
- 只有属性存在的时候才能监听
- 当监视属性发生变化时候,监听的毁掉函数handler自动执行
- 监听的两种写法watch和Vue的实例vm.$watch
watch:{
ishot:{ //其实是'ishot'的简写
//handler是ishot被修改的时候执行
handler(newValue,oldValue){
},
//immediate默认值是false,立即执行;immediate设置为true是初始化时候让handler调用一下
immediate:true
}
}
//也可以用vm.$watch进行监视
vm.$watch('ishot',{
handler(newValue,oldValue){
},
immediate:true
})
深度监视
//监视多个结构中某个属性的变化
const vm = new Vue({
data:{
ishot:true,
number:{
a:1,
b:2
}
},
watch:{
//方式一:不推荐
'number.a':{
handler(){
console.log('检测a的变化')
}
},
//方式二
//deep:true开启深度监视,也就是当number中的a b任何一个变化都会触发handler;之前是不会如果地址没变
//vue是可以监视到多层级数据改变的但是watch默认没有开启多层级监听
number:{
deep:true,
handler(){
}
}
}
})
//监视简写
const vm = new Vue({
data:{
ishot:true,
number:{
a:1,
b:2
}
},
watch:{
//当配置项只有handler的时候可以开启简写
number(newValue,oldValue){ //相当于handler函数
}
})
//vm.$watch监视简写
vm.$watch('ishot',function(newValue,oldValue){
//这里不允许使用肩头函数,会有this指向问题
})
注意:计算属性computed中不能开启异步任务去获取返回值;watch监视器的可以开启异步任务
总结:
- computed能完成的watch一定能完成
- watch能完成的computed不一定能完成,比如ajax毁掉函数、promise回调函数、setTimeout,computed中不可以做异步操作
- 注意:
- 所有被vue管理的函数最好都写成普通函数,这样吧this指向才不会出问题
- 所有不被vue管理的函数最好都写成街头函数(比如setTimeout、异步函数),这样this的指向才是vm或者组件的实例对象
绑定class样式
<style>
.basic{
}
.normal{}
.normalT{}
.style1{}
.style2{}
.style3{}
</style>
//1、字符串:动态绑定适用于类名不确定需要指定
<div :class="mood" @click="changeMood">smileyqp</div>
//2、数组:要绑定样式的个数,名字都不确定
<div :class="styleArr" @click="changeStyle" @click="changeStyle">smileyqp</div>
//3、对象:适用于要绑定样式的个数确定但是是否使用可以动态改变
<div :class="styleObj" @click="styleArr" @click="changeStyle">smileyqp</div>
//4、直接内联:
<div :style="{fontSize:fsize+'px'}" @click="styleArr" @click="changeStyle">smileyqp</div>
<div :style="stObj" @click="styleArr" @click="changeStyle">smileyqp</div>
//5、style数组写法
<div :style="stArr" @click="styleArr" @click="changeStyle">smileyqp</div>
const vm = new Vue({
data:{
mood:'normal',
styleArr:['style1','style2','style3'],
styleObj:{
style1:false,
style2:true,
style3:false,
fsize:40
},
stObj:{
fontSize:'30px',
color:'red',
}
stObj2:{
background:'blue'
},
stArr:[stObj,stObj2]
},
methods:{
changeMood(){
this.mood = 'normalT'
},
changeStyle(){
this.styleArr.shift();
},
changStyObj(){
this.styleObj.style1 = true
}
}
})
条件渲染
//v-show实际上是操作display
//1、使用v-show
<div v-show="isShow" @click="fn">smileyqp</div>
<div v-show="n===1" @click="fn">smileyqp</div>
<div v-show="n===2" @click="fn">smileyqp</div>
<div v-show="n===3" @click="fn">smileyqp</div>
//2、使用v-if;直接是节点操作
<div v-if="isShow" @click="fn">smileyqp</div>
//这种不允许打断 ;也可以直接全用v-if
<div v-if="n===1" @click="fn">smileyqp</div>
<div v-else-if="n===2" @click="fn">smileyqp</div> // 如果成立直接不看下面条件
<div v-else-if="n===3" @click="fn">smileyqp</div>
<div v-else @click="fn">smileyqp</div> //v-else
//注意:可以使用v-if与template的配合使用;template不能跟与v-show一起使用
//使用template,渲染的时候不会新增没有用的节点
<template v-if="n===1">
<h2>hello</h2>
<h2>smileyqp</h2>
<h2>yqp</h2>
</template>
const vm = new Vue({
data:{
isShow:false,
n:1
}
})
如果有很高的切换频率使用v-show,因为v-show只是动态控制节点显示,v-if会去切换节点
列表渲染
<div v-if="n===1">
<ul>
<li v-for="p in persons" :key="p.id">{{p.name}}-{{p.age}}</p>
</ul>
//1、遍历
<ul>
<li v-for="(item,index) in persons" :key="index">{{p.name}}-{{p.age}}</p>
</ul>
//2、也可以不用括号
<ul>
<li v-for="item,index in persons" :key="index">{{p.name}}-{{p.age}}</p>
</ul>
//3、in也可以改成of
<ul>
<li v-for="(item,index) of persons" :key="index">{{p.name}}-{{p.age}}</p>
</ul>
//4、也可以遍历object
<ul>
<li v-for="(value,key) of cars" :key="key">{{key}}:{{value}}</p>
</ul>
//5、也可以遍历字符串;s是字符串的每一个字符
<ul>
<li v-for="(s,index) of str" :key="index">{{index}}:{{s}}</p>
</ul>
//7、遍历指定次数;如下遍历五次,a是从1开始计数,b是index
<ul>
<li v-for="(a,b) of 5" :key="b">{{a}}:{{b}}</p>
</ul>
</div>
const vm = new Vue({
data:{
persons:[
{id:001,name:'smile1',age:12},
{id:002,name:'smile2',age:14},
{id:003,name:'smile3',age:16},
],
cars:{
name:'car1',
price:12222,
color:'yellow'
},
str:'smileyqp'
}
})
列表过滤
<div v-if="n===1">
<ul>
<li v-for="p in filterPersons" :key="p.id">{{p.name}}-{{p.age}}</p>
</ul>
<input v-model="keyword"/>
</div>
//1、用watch实现过滤
const vm = new Vue({
data:{
keyword:'',
persons:[
{id:001,name:'smile1',age:12},
{id:002,name:'smile2',age:14},
{id:003,name:'smile3',age:16},
],
filterPersons:[]
},
watch:{
keyword:{
//控制一开始就调用一次,最开始为空,是会调用的,空字符串indexOf返回0,也就是返回persons数组
immediate:true,
handler(newVal){
this.filterPersons = return this.persons.filter(p=>{
return p.name.indexOf(newVal) !== -1
})
}
}
}
})
//2、用computed实现
const vm = new Vue({
data:{
keyword:'',
persons:[
{id:001,name:'smile1',age:12},
{id:002,name:'smile2',age:14},
{id:003,name:'smile3',age:16},
]
},
computed:{
filterPersons(){
return this.persons.filter(p=>{
return p.name.indexOf(keyword) !== -1
})
}
}
}
})
列表排序
<div v-if="n===1">
<ul>
<li v-for="p in filterPersons" :key="p.id">{{p.name}}-{{p.age}}</p>
</ul>
<input v-model="keyword"/>
<button @click="sortType = 0">default</button>
<button @click="sortType = 1">default</button>
<button @click="sortType = 2">default</button>
</div>
//1、用watch实现过滤
const vm = new Vue({
data:{
sortType:0, //0原顺序 1升序 2降序
persons:[
{id:001,name:'smile1',age:12},
{id:002,name:'smile2',age:14},
{id:003,name:'smile3',age:16},
],
filterPersons:[]
},
computed:{
filterPersons(){
const arr = this.persons.filter(p=>p.name.indexOf(keyword) !== -1)
if(this.sortType){
return this.arr.sort((a,b)=>{
return this.sortType === 1?a-b:b-a
})
}
return arr;
}
}
})
Vue.set()的使用
- 局限性:只能给data中的某一个对象添加属性,并不能新增data下面的属性
Vue.set(target,key,val)
const vm = new Vue({
data:{
persons:[
{id:001,name:'smile1',age:12},
{id:002,name:'smile2',age:14},
{id:003,name:'smile3',age:16},
],
perObj:{id:1212,name:'smile1',age:12}
},
methods:{
add(){
//Vue.set(this.perObj,'sex','male')
//第一个target参数不能是vm也不能是vm下面的第一个对象
this.$set(this.perObj,'sex','male')
}
}
})
Vue检测数组的原理
- 注意数组修改的时候要使用左边七个方法,才会更新页面;类似filter以及直接修改index赋值这些不能检测到数组变化,不会去修改页面
- vue中的数组不是靠setter和getter去实现的,因此要实际修改数组的方法才行
- 注意:Vue是对数组的push这些方法进行了包装,所以能监听到这些;Vue中的push调用原来Array的push并且多做了一件解析模板的事情,所以能引起页面变化
- 备注:另外也可以直接
$set
方法去实现,但是没有必要
Vue监测原理总结
补充:Vue中数组项变化可以监听到方式
收集表单数据
过滤器
示例:
指令
生命周期
Vue component
Vue配置文件vue.config.JS
其他:
组件自定义事件
通过父组件给子组件绑定一个自定义事件实现父给子传递数据
- 形式
- 父组件
<Student v-on:componentName="funcName"></Student>
//简写形式: @componentName="funcName"
//方法只执行一次 @componentName.once="funcName"
...
funcName(name){
console.log(name)
}
- 父组件接收另外一种形式
- 这种方式灵活性强
- 只执行一次的写法
this.$refs.student.$once('smileyqp',this.getStudent)
- 子组件
<button @click="clickFunc">click me</button>
...
clickFunc(){
this.$emit('componentName',this.name) //
}
组件自定义事件解绑
- 解绑耽搁事件:在子组件上写
this.$off('funcName')
- 解绑多个事件
⚠️当子组件销毁,绑定在子组件上的所有的自定义事件也是会失效的。
⚠️注意:这个地方的this.getStudentName
如果是function(){}
,注意function函数里面的this只想的是子组件的vc,并不是this.getStudentName
中的父组件vc,拿不到父组件的属性值除非用箭头函数;
⚠️组件调用原生事件:是把这个click给到子组件的最外层元素
总结:
全局事件总线
- 总结:
- 使用
- 注册:
- 消息订阅与发布库:
pubsub-js
-
总结
-
使用
-
$nextTick
$nextTick
指定的回调会在dom节点更新完毕之后再执行
动画效果
- 总结:
配置代理
vue-resource
- vue插件库
Vue.use(xxx)
,vue-resource
是对xhr的封装
- 使用方式跟axios一模一样
插槽
- 插槽分类
- 默认插槽
- 具名插槽
- 作用域插槽
Vuex
- 原理
- 环境搭建
- 基本使用
- vuex的getters
通过this.$store.getters
使用
mapState与mapGetters
路由
路由理解
多级路由(嵌套路由)
路由传参
命名路由
路由params参数
路由props配置
路由router-link的replace属性
编程式路由导航
缓存路由组件
全局路由守卫
主要进行权限控制等
- 前置路由守卫
独享路由守卫
只有前置没有后置;写进router配置中
组件内路由守卫
写进组件中