Vue.config.productionTip=false //阳止 vue在启动时生成生产提示。

BootCDN

MOMENT.JS 日期处理库 dayjs

解构赋值连续写法

{query:{id,title}}

debugger调试

debugger
debugger 语句用于停止执行 JavaScript,并调用 (如果可用) 调试函数。
使用 debugger 语句类似于在代码中设置断点。
通常,你可以通过按下 F12 开启调试工具, 并在调试菜单中选择 "Console" 。
注意: 如果调试工具不可用,则调试语句将无法工作。

MVC


MVVM

M : 模型(Model) : 对应data中的数据
V : 视图 (View) : 模板
VM : 视图模型(ViewModel) :vue实例对象

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4vJxQlEj-1651137472216)(C:\Users\mht\AppData\Roaming\Typora\typora-user-images\image-20211212181705266.png)]

回顾 Object.defineproperty方法 reduce

Object.defineproperty(‘'给哪个对象添加属性','添加的属性叫什么名字',{配置项
value:18,
enumerable:true,//控制属性是否可以枚举,默认false
writable:true,//控制属性是否可以修改,默认false
configurable:true,//控制属性是否可以被删除,默认值是false
//当有人读取obj的age属性时,get函数就会被调用,据返回值就是age的值get:function({return: number}),
//当有人修改了obj的age属性时,set函数(setter)就会被调用,且会收到修改的具体值。set(value){console.log('有人修改了age属性,且值是',value)number=value;}
})
添加的属性不可以被枚举(遍历)
Object.keys(object)delete obj.name https://www.jianshu.com/p/e375ba1cfc47
reduce()方法可以搞定的东西,for循环,或者forEach方法有时候也可以搞定,那为啥要用reduce()?这个问题,之前我也想过,要说原因还真找不到,唯一能找到的是:通往成功的道路有很多,但是总有一条路是最捷径的,亦或许reduce()逼格更高...
array.reduce(()=>{},0)callback (执行数组中每个值的函数,包含四个参数)1、previousValue (上一次调用回调返回的值,或者是提供的初始值(initialValue))2、currentValue (数组中当前被处理的元素)3、index (当前元素在数组中的索引)4、array (调用 reduce 的数组)initialValue (作为第一次调用 callback 的第一个参数。)例子
var arr = [1, 2, 3, 4];
var sum = arr.reduce(function(prev, cur, index, arr) {console.log(prev, cur, index);return prev + cur;
})
console.log(arr, sum);
打印结果:
0 1 0
1 2 1
3 3 2
6 4 3
[1, 2, 3, 4] 10
这个例子index是从0开始的,第一次的prev的值是我们设置的初始值0,数组长度是4,reduce函数循环4次。结论:如果没有提供initialValue,reduce 会从索引1的地方开始执行 callback 方法,跳过第一个索引。如果提供initialValue,从索引0开始。
数据代理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qIb2seYZ-1651137472217)(C:\Users\mht\AppData\Roaming\Typora\typora-user-images\image-20211212192220990.png)]

数据代理:通过一个对象代理对另一个对象中属性的操作 读/写
1.Vue中的数据代理:通过vm对象来代理data对象中属性的操作(读/写)
2.Vue中数据代理的好处:更加方便的操作data中的数据
3.基本原理:通过object.defineProperty()把data对象中所有属性添加到vm 上.为每一个添加到vm上的属性,都指定一个getter/setter.在getter/setter内部去操作(读/写)data中对应的属性。let obj1={x:100}
let obj2={y:200}Object.defineProperty(obj2,'x',{get(){return obj1.x},set(value){obj1.x=value}
})vue 中的data的数据都是代理的
vm._data===data
vm._data= 里面作了数据劫持

vue原型对象

Vue.prototype
Vue.extend()返回值是VueComponents

图像界面创建

vue ui 图像界面创建选vue3.x1.安装插件
axios
2.安装依赖
echarts
echarts-gl 3d的库template 标签包裹dom元素但不生成dom元素

v-model

v-model.number

事件

v-on 简写@  绑定
@click 点击
@wheel 鼠标滚轮滚动事件
@scroll 滚动条滚动事件1.onmouseenter和onmouseleave是一组:当鼠标进入指定区域的时候触发,但是不支持冒泡,进入或者离开子组件都不触发
onmouseenter和onmouseleave相当于绑定的区域为A+B
2.onmouseover和onmouseout是一组:当鼠标进入指定区域的时候触发,进入或者离开子组件也都触发onmouseover和onmouseout相当于绑定的区域为A(不包含B)

事件修饰符

e.preventDefault()阻止默认行为
e.stopPropagation()阻止冒泡
e.target 获取点击的元素
@click.prevent=""阻止默认行为
Vue中的事件修饰符:
1.prevent:止默认事件(常用);
2.stop:阻止事件冒泡(常用);
3.once:事件只触发一次(常用);
4.capture:使用事件的捕获模式; 一般是先捕获在冒泡 冒泡才开始触发事件   加完后就是 捕获的时候就触发事件
5.self:只有event.target是当前操作的元素是才触发事件;
6.passive:事件的默认行为立即执行,无需等待事件回调执行完毕;

键盘事件

keydown按下去
keyup抬起来
keyCOde 键盘编码
@keyup.enter
常用的按键别名:
回车=>enter
删除=>delete(捕获“删除”和“退格”键)
退出=>esc
空格=>space
换行=>tab(切换焦点必须配置keydown使用)
上=>up
下=>down
左=>left
右=>right
@keyup.caps-lock 切换大小写2.Vue未提供别名的按健,可以使用按健原始的key值去绑定,但注意要转为kebab-case(短横线命名)
3.系统修饰键(用法特殊):ctrl、alt、 shift、meta(1).配合keyup使用:按下修饰键的同时,再按下其他键,随后释放其他健,事件才被触发。(2).配合keydown使用:正常触发事件。
4.也可以使用keyCode去指定具体的按键(不推荐)
5.Vue.config.keyCodes.自定义健名=键码,可以去定制按键别名

计算属性与监听,过滤

vue所管理的函数都要写普通函数
计算属性
//计算属性
不能开启异步任务的
export default {data() {return {hasWeixinAuth: '您好',}},computed:{hash:{//get有什么作用?当有人读取hash时,get就会被调用,且返回值就作为hash的值 重复调用走缓存//get什么时候调用? 1.初次读取hash的时候调用。2.所有依赖的数据发生变化时get(){console.log('被调用了');return '帅哥'+this.hasWeixinAuth},//set什么时候调用? 当hash被修改的时候set(value){console.log('set',value);const arr=value.split('-');console.log(arr);}}},onShow() {this.hash='李-四';},methods: {demo(){}}}简写(只读取不改)computed:{hsah(){console.log('被调用了');return '帅哥'+this.hasWeixinAuth}}
监视属性watch
可以做异步任务的
监视属性watch:
1.当被监视的属性变化时,回调函数自动调用,进行相关操作
2.监视的属性必须存在,才能进行监视!!
3.监视的两种写法:
(1).new Vue时传入watch配置
(2).通过vm.$watch监视
watch:{isHot:{//handler什么时候被调用?当isHot发生改变的时候immediate:true,//初始化时让handler调用一下deep:true,//深度监听handler(newValue,oldValue){新值和旧值对比console.log('isHot被修改了',newValue,oldValue)}}
}
vm.$watch('isHot',{//handler什么时候被调用?当isHot发生改变的时候immediate:true,//初始化时让handler调用一下handler(newValue,oldValue){新值和旧值对比console.log('isHot被修改了',newValue,oldValue)}
})还可以监听计算属性里面的值
export default {data() {return {hasWeixinAuth: '您好',isShow:true,}},computed:{info(){return this.isShow?'炎热':'寒冷'}},watch:{info:{immediate:true,handler(newValue,oldValue){console.log('info被修改了',newValue,oldValue)}},},methods: {demo(){this.isShow=!this.isShow}}}
//深度监听
/**
(1).Vue中的watch默认不监测对象内部值的改变(一层)
(2).N置deep:true可以监测对象内部值改变(多层)
-备注:
(1).Vue自身可以监测对象内部值的改变,但Vue提供的watch默认不可以!
(2).使用watch时根据数据的具体结构,决定是否采用深度监视-
*/
data() {return {numbers:{a:1,b:2}}
},
watch:{'numbers.a':{//监视多级结构中某个属性的变化immediate:true,handler(newValue,oldValue){console.log('a被修改了',newValue,oldValue)}},numbers:{//监视多级结构中所有属性的变化deep:true,immediate:true,handler(value){console.log('a被修改了',value)}}
},
// 简写(简写了就不能配置了)
info(newValue,oldValue){console.log('info被修改了',newValue,oldValue)
}
vm.$watch('isShow',function(newValue,oldValue){console.log('info被修改了',newValue,oldValue)
})
vue监测数据的原理
vue 怎么检测对象中数据改变的defineProperty
加工data 就可以实现对对象进行监视
vue监测数组的原理
数组里面值得变化不是靠set和get来监测的用这写可以改变原数组的来写 可以相应
包装数组修改数组身上的方法实现的
push push() 方法可向数组的末尾添加一个或多个元素,并返回新的长度。
pop pop() 方法用于删除数组的最后一个元素并返回删除的元素。
shift shift() 方法用于把数组的第一个元素从其中删除,并返回第一个元素的值。
unshift unshift() 方法可向数组的开头添加一个或更多元素,并返回新的长度。
splice
sort
reverse(颠倒数组中元素的顺序:)
Vue数据监听总结

过滤器
<h3>{{ time | timeFormater('YY年MM月DD日') | mySlice}}</h3>
过滤器本质是个函数
局部过滤器
首先读取time 将time作为参数给timeFormater函数 最好返回值会把他{{ time | timeFormater}}全部替换掉
第一个参数 就是time 阶梯模式往下传
filters:{timeFormater(value,str="YY年MM月DD日 HH:mm:ss"){}
}全局的叫filter
Vue.filter('mySlice',function(value){return value.slice(0,4)
})用于插值语法
绑定值的时候也可以用
有时候电商 1999 => 过滤成1,900
<h3 :x="msg | mySlice ">撒大大</h3>
过滤
filter不改变原数组 返回新数组应用场景
平时开发中,需要用到过滤器的地方有很多,比如单位转换、数字打点、文本格式化、时间格式化之类的等
比如我们要实现将30000 => 30,000,这时候我们就需要使用过滤器
Vue.filter('过滤器名称',function(){})
//搜索 watch 实现
<body><div id="app"><h1>人员列表</h1><button @click.once="add">添加</button><input type="text" placeholder="请输入名字" v-model="keyWord"><ul><li v-for="(p,index) in filterPersons" :key="p.id">{{p.name}}-{{p.age}}-{{p.sex}}</li></ul></div><script>new Vue({el: '#app',data:{keyWord:'',persons: [{ id: '001', name: '马东梅', age: 18,sex:'女' },{ id: '002', name: '周冬雨', age: 19,sex:'女' },{ id: '003', name: '夏洛', age: 20,sex:'男' },{ id: '004', name: '金毛狮王', age: 21,sex:'男' },],filterPersons:[]},filter:{},watch: {keyWord:{immediate:true,handler(newValue){this.filterPersons = this.persons.filter((p)=>{return p.name.indexOf(newValue)!== -1;})}}},methods: {}})</script>
</body>//计算属性的过滤
new Vue({el: '#app',data:{keyWord:'',persons: [{ id: '001', name: '马冬梅', age: 18,sex:'女' },{ id: '002', name: '周冬雨', age: 19,sex:'女' },{ id: '003', name: '夏洛', age: 20,sex:'男' },{ id: '004', name: '金毛狮王', age: 21,sex:'男' },],},computed:{filterPersons(){return this.persons.filter((p)=>{return p.name.indexOf(this.keyWord)!== -1;console.log(p);})}}})
1.定义:要用的属性不存在,要通过已有的计算属性得来
2.原理:底层借助了objcet.defineproperty方法提供的getter和setter.
3.get函数什么时候执行?(1).初次读取时会执行一次。(2).当依赖的数据发生改变时会被再次调用。
4.优势:与methods实现相比,内部有缓存机制(复用),效率更高,调试方便。
5.备注:1.计算属性最终会出现在vm 上。直接读取使用即可。2.如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生改变
//可以读性高
computed:{//方法:函数
}
计算属性与方法的区别
计算属性是基于他们的依赖进行缓存的(依赖指data 中的数据)  比较耗时的计算可以节省性能
方法不存在缓存的  //监听 处理异步  用于登录
watch:{isHot:{//handler什么时候被调用?当isHot发生改变的时候immediate:true,//初始化时让handler调用一下handler(newValue,oldValue){新值和旧值对比console.log('isHot被修改了',newValue,oldValue)}}
}
这两个都可以实现相同效果但过程有点不一样
Computed特点:
需要主动调用,具有缓存能力只有数据再次改变才会重新渲染,
否则就会直接拿取缓存中的数据。Watch特点:
无论在哪只要被绑定数据发生变化Watch就会响应,
这个特点很适合在异步操作时用上。//过滤器
应用场景
平时开发中,需要用到过滤器的地方有很多,比如单位转换、数字打点、文本格式化、时间格式化之类的等
比如我们要实现将30000 => 30,000,这时候我们就需要使用过滤器
Vue.filter('过滤器名称',function(){})

key作用与原理

用inputd时最好用id 区分
面试题: react. vue中的key有什么作用?(key的内部原理)
1.虚拟DOM中key的作用:key是虚拟DOM对象的标识,当状态中的数据发生变化时,Vue会根据【新数据】生成【新的虚拟DON》,随后Vue进行【新虚拟DOM】与【旧虚拟DOM】的差异比较,比较规则如下:
2.对比规则:   (1).旧虚拟DOw中找到了与新虚拟DOM相同的key:1.若虚拟DOM中内容没变,直按使用之前的真实DOW!2.若虚拟DOM中内容变了,则生成新的真实DOM,随后替换掉页面中之前的真实DOM。(2).旧虚拟DOM中未找到与新虚拟DOM相同的key创建新的真实DOM,随后渲染到到页面。
3.用index作为key可能会引发的问题:1.若对数据进行:逆序添加、逆序删除等破环顺序操作:会产生没有必要的真实DOM更新==>界面效果没问题,但效率低。2.如果结构中还包含输入类的DOM:会产生错误DOM更新==>界面有问题。
4.开发中如何选择key?1.最好使用每条数据的唯一标识作为key,比如id、手机号、身份证号、学号等唯一值。2.如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示,使用index作为key是没有问题的。

收集表单信息

单选框
要配置value值
多选
初始化数据是数组
@submit.prevent  表单提交事件type="number" v-model.number 输入的字符串转成有效数字v-model.lazy 失去焦点后在收集数据
v-model.trim 输入首位空格过滤

vue.set()

//改数组里面的值
this.$set('哪个对象','对象的哪个属性','值是什么');
只能给data中某个响应式对象添加属性//改数组里面的值
this.$set('哪个数组','数组的下标','值是什么');

内置指令

v-text
向其所在的标签插文本
name='牛比'
拿到name的值替换掉整个内容的值
<div v-text=name> </div> => <div>牛比</div>
v-html

v-cloak
主要解决当你网速过慢的时候他不会让你未经过解析的东西跑到页面上去
1.本质是一个特殊属性 Vue实例创建完毕并接管容器后,会删掉v-cloak属性。
2.使用css配合v-cloak可以解决网速慢时页面展示出{{xxx}}的问题。<style>[v-cloak]{display: noen;}</style>
<h1 v-cloak>人员列表</h1>
v-once
1.v-once所在节点在初次动态渲染后,就视为静态内容了。
2.以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能。
<h1 v-once>初始化的n值:{{n}}</h1>
<h1>当前的n值:{{n}}</h1>
<button @click="n++">n++</button>
v-pre
1.跳过其所在节点的编译过程。
2.可利用它跳过:没有使用指令语法、没有使用插值语法的节点,会加快编译。
加了之后vue就不去解析他了
自定义指令
directives:{
对象和函数的写法big:{},big(){}
}

生命周期

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eOuR8ee1-1651137472218)(C:\Users\mht\AppData\Roaming\Typora\typora-user-images\image-20211223205619303.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BTd8NRXP-1651137472219)(C:\Users\mht\AppData\Roaming\Typora\typora-user-images\image-20211223205713030.png)]

mounted(挂载完毕)
//Vue完成模板的解析并把初始的真实DOM元素放入页面后(挂载完毕)调用mounted
  • 什么是生命周期

    • 一个组件从创建到销毁的过程,就是组件的一生
  • 作用

    • 在不同的阶段做不同的事
  • 分四个阶段

    • a.挂载阶段,只执行一次

      1. beforeCreate

        • 实例初始化后调用,做一些初始化的事件,但组件的data、methods、computed、props、watch…等等选项对象还未创建,数据观察与事件机制尚未形成,也就不能使用data中的状态和methods方法
      2. created

        • 实例已经创建完成之后被调用,可以通过this访问injectpropsdatamethodscomputedwatch等大部分属性和方法了
        • 可以在此发网络请求
      3. beforeMount

        • 挂载前调用,在内存中对模板与数据进行编译结合,但此时还没有挂载到页面上,页面还是旧的,可以在此 对数据进行最后一步修改
      4. mounted

        • 挂载完成,内存中编译好的vnode渲染到了网页上,此时才可以获取dom,但不建议直接操作dom,要用框架的思想通过状态去实现需求
    • b.更新阶段,状态更新了就会触发

      • beforeUpdate

        • 响应式数据更新时调用,当状态发生改变的时候就会触发此钩子函数,页面还没有和最新的数据保持同步,这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器
      • updated
        • 数据与模板相互结合 ,会将新数据挂载到页面上,可以在此获取最新的dom结构,避免在此期间更改状态,因为这可能会导致更新无限循环
    • c.销毁阶段

      • beforeDestroy

        • 在实例销毁之前调用,实例仍然完全可用
        • 一般在这一步做一些重置的操作,比如清除掉组件中的定时器 和 解绑监听的dom事件
      • destroyed
        • 在实例销毁之后调用,所有的事件监听器会被移出,所有的子组件实例也会被销毁,所有的 data 和 methods , 指令, 过滤器 ……都是处于不可用状态。组件销毁后会将vue与当前网页之间的关系进行断开解绑
    • d.错误捕获

      • errorCaptured

        • 当捕获一个来自子孙组件的错误时被调用。此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回 false 以阻止该错误继续向上传播。
  • keep-alive专属

    • activited

      • 组件被激活时调用
    • deactivated
      • 组件被销毁时调用

组件化编程

非单文件组件
Vue中使用组件的三大步骤:
一、定义组件(创建组件)
二、注册组件
三、使用组件(写组件标签)一、如何定义一个组件?使用Vue.extend(options)创建,其中options和new Vue(options)时传入的那个options儿乎一样,但也有点区别;区别如下:1.el不要写,为什么?—最终所有的组件都要经过一个vm的管理,tvm中的el决定服务哪个容器。2.data必须写成函数,为什么?——避免组件被复用时,数据存在引用关系。备注:使用template可以配置组件结构。二、如何注册组件?  1.局部注册:靠new Vue的时候传入components选项2.全局注册:菲vue.component('组件名",组件)三、编写组件标签:<school></ school>const schoo = Vue.extend({name:'atghg',template:``,data(){return{}},methods: {}
})
//全局注册组件
Vue.components('schoo',schoo)
components:{schoo,
}
单文件组件

组件注意事项
1.关于组件名:一个单词组成:第一种写法(首字母小写):school第二种写法(首字母大写):School多个单词组成:第一种写法(kebab-case命名):my-school第二种写法(Camelcase命名):MySchoo1(需要Vue脚手架支持)备注:(1).组件名尽可能回避HTML中已有的元素名称,例如:h2、H2都不行。(2).可以使用name配置项指定组件在开发者工具中呈现的名字。2.关于组件标签:第一种写法: <school></ school>第二种写法:<school/>备注:不用使用脚手架时,<school/>会导致后续组件不能渲染。3.一个简写方式:const school = Vue.extend(options)可简写为: const school = options底层写了判断他会直接帮你解决
VueComponent构造函数
关于VueComponent:1.school组件本质是一个名为VueComponent的构造函数,且不是程序员定义的,是Vue.extend生成的2.我们只需要写<school/>或<school></school>,Vue解析时会帮我们创建school组件的实例对象,即Vue帮我们执行的:new VueComponent(options). 3.特别注意:每次调用Vue.extend,返回的都是一个全新的VueComponent!!!!4.关于this指向:(1).组件配置中;data函数、methods中的函数、watch中的函数、computed中的函数它们的this均是【Vue】(2).new Vue()配置中:data函数、methods中的函数、watch中的函数、computed中的函数它们的this均是【Vue】5.VueComponent的实例对象,以后简称vc(也可称之为:组件实例对象)。   Vue的实例对象,以后简称vm。I
原型
1.一个重要的内置关系:VueComponent.prototype._proto_ === Vue.prototype
2.为什么要有这个关系:让组件实例对象_(vc)可以访问到Vue原型上的属性、方法。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5U1ZzdHo-1651137472219)(C:\Users\mht\AppData\Roaming\Typora\typora-user-images\image-20220105202936951.png)]

vue脚手架

npm install -g @vue/clivue inspecrt > output.js 把vue脚手架默认配置整理成为.js文件public 里面的index.html 不支持ie8以下版本指public目录<%= BASE_URL %>
src
-assets 放静态资源
-components 组件
-main.js 项目入口文件Vue.config.productionTip = false 关闭vue生产提示new Vue({//将App组件放入容器中render: h => h(App),}).$mount('#app').gitignore ->git忽略文件 不想接受git管理
babel.config.js ->转es5
package.json -> 包管理vue-cli-service build webpack打包   "lint": "vue-cli-service lint" 语法检查
package-lock.json包管理
README.md 说明笔记//改默认配置
vue.config.js
vue会将其中的配置跟webpack里面的配置进行合并

render函数

关于不同版本的Vue:、1.vue.js 与vue.runtime.xxx.js的区别:(1).vue.js是完整版的Vue,包含:核心功能+模板解析器。(2). vue.runtihe.xxx.js是运行版的Vue,只包含:核心功能;没有模板解析器。2.因为vue.runtime.xxx.js没有模板解析器,所以不能使用template配置项,需要使用render函数接收到的createElement函数去指定具体内容。

ref属性

1.被用来给元素或子组件注册引用信息(id的替代者)
2.应用在html标签上获取的是真实DOM元素,应用在组件标签上是组件实例对象(vc)
3.使用方式:打标识: <h1 ref="xxx">.....</h1>或<School ref="xxx"></School>获取:this.$refs.xxx<h1 ref="title">人员列表</h1>console.log(this.$refs.title); 拿到真实DOM元素也可以拿到组件的实例对象 可以用于组件间通信 

props配置

 父组件也可以给子组件传方法第一种props:['schoolName'],简单接收第二种// 接收收同时对数据进行类型限制props:{school:String,number:Number}第三种// 接收收同时对数据 进行类型限制 +默认值的指定+必要性的限制props:{school:{type:String,//school类型是字符串required:true,//school是必要的传},number:{type:Number,required:false,default:99,//默认值default()=>{return }}}要是想改传过来的值可以在data中重新定义一个 myNumber:this.numberprops 优先级更高 先准备props中的数据在准备data中的数据备注: props是只读的,Vue底层会监测你对props的修改,如果进行了修改,就会发出警告,若业务需求确实需要修改,那么请复制props的内容到data中一份,然后去修改data中的数据

mixin混入

export default {name:'School',data() {return {name:'大哥大'};},mixins:[mixin]
}
上面这个组合中的每一个配置项在混合中都可以写以你的数据为主
生命周期除外 都执行 混入中的生命周期执行在前全局混入  main.js
import {hunhe,hunhe2} from "./mixin"Vue.mixin(hunhe)
Vue.mixin(hunhe2)

插件plugins.js

plugins.js

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GaGM4OG6-1651137472219)(C:\Users\mht\AppData\Roaming\Typora\typora-user-images\image-20211228205448219.png)]

本地存储webStorage

浏览器通过 Window.sessionStorage 和Window.localStorage 属性来实现本地存储机制
取不到返回null
//浏览器关了也不会消失
保存数据
localStorage.setItem('msg','18')
对象用jsoN存localStorage.setItem('person',JSON.stringify(obj))读取数据console.log(localStorage.getItem('msg'))删除数据localStorage.removeItem('msg')清空本地数据localStorage.clear();//session 浏览器中的 会话浏览器关闭就没了
保存数据
sessionStorage.setItem('msg','18')
对象用jsoN存
sessionStorage.setItem('person',JSON.stringify(obj))读取数据
console.log(sessionStorage.getItem('msg'))删除数据
sessionStorage.removeItem('msg')清空本地数据
sessionStorage.clear();

自定义事件

给组件用的
子给父传递东西
this.$emitthis.$emit('student','您在噶那么');vue使用$emit时,父组件无法触发监听事件的原因是:
$emit传入的事件名称只能使用小写,不能使用大写的驼峰规则命名<HelloWorld ref="student" />
this.$refs.student.$on('students',this.students)
this.$refs.student.$once('students',this.students)

自定义事件解绑

this.$off('school');//解绑一个自定义事件
this.$off(['school','demo']);//解绑多个自定义事件
this.$off();//解绑所有的自定义事件销毁
vm vc
销毁后所有自定义事件的全都不奏效了
this.$destroy();
destroyed(){}

事件总线(GlobalEventBus)

用事件总线好点const Demo = Vue.extend({});
const d = new Demo()
Vue.prototype.x=d哥哥组件
绑定事件总线
this.x.$on('hello',(data)=>{console.log('我是School组件,收到了数据',data);
})
弟弟组件
sndtStudent(){this.x.$emit('hello',666)
}//标准写法
new Vue({render: h => h(App),beforeCreate(){Vue.prototype.$bus=this //安装全局事件总线  $bus就是当前应用的vm}
}).$mount('#app')建一个config文件用完给解绑了

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Cl1Gg8I7-1651137472220)(C:\Users\mht\AppData\Roaming\Typora\typora-user-images\image-20220105210314770.png)]

消息订阅与发布

组件通信消息订阅与发布
1.订阅消息:消息
2.发布消息: 消息内容订阅什么名字 发布什么名字
推荐 pubsub-js
pub(publish发布)sub(subscribe订阅)School组件
mounted() {// this.$bus.$on("hello", (data) => {//   console.log("我是School组件,收到了数据", data);// });// 订阅消息   函数中有两个参数  一个是消息名 一个数据   pubsub.subscribe('hello',(msgName,darta)=>{console.log("有个人发布了hello消息,hell消息的回调执行了",msgName,darta);})},beforeDestroy(){//   this.$bus.$off('hello')// 取消订阅pubsub.unsubscribe(this.pubId);}student组件sndtStudent(){// this.$bus.$emit('hello',this.name)// 发布消息pubsub.publish('hello',666)
}第二中方式mounted() {// 订阅消息   函数中有两个参数  一个是消息名 一个数据    每个订阅的id都不一样this.pubId=pubsub.subscribe('hello',this.demo)},methods: {demo(msgName,darta){console.log("有个人发布了hello消息,hell消息的回调执行了",msgName,darta);}},beforeDestroy(){//this.$bus.$off('hello')// 取消订阅pubsub.unsubscribe(this.pubId);}student组件sndtStudent(){// this.$bus.$emit('hello',this.name)// 发布消息pubsub.publish('hello',666)
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-srK0l7Xr-1651137472220)(C:\Users\mht\AppData\Roaming\Typora\typora-user-images\image-20220105213823487.png)]

$nextTick下一轮

1.语法: this.$nextTick(回调函数)
2.作用:在下一次DOM更新结束后执行其指定的回调。
3.什么时候用:当改变数据后,要基于更新后的新DOM进行某些操作时,要在nextTick所指定的回调函数中执行。上面一个input框隐藏了
this.$nextTick(function(){this.refs.inputTitle.focus()
})

过度动画

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NnXY4X3n-1651137472221)(C:\Users\mht\AppData\Roaming\Typora\typora-user-images\image-20220108160226474.png)]

进入的起点
.动画名-enter
进入的终点
.动画名-enter-to

插槽

默认插槽
<slot></slot>
默认插槽
<template><div class="father"><list title="美食" ><img src="@/assets/logo.png" alt=""></list><list title="游戏"><ul><li v-for="(item,index) in games" :key="index">{{item}}</li></ul></list><list title="电影"><video src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4" width="100%" controls palyauto="palyauto"></video></list></div>
</template><template><div class="list_box"><h1>{{title}}分类</h1><!--定义一个插槽(挖个坑,等着组件的使用者进行填充)--><slot>我是一些默认值,当使用者没有传递具体结构时,我会出现</slot></div>
</template>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fbHMNvJZ-1651137472221)(C:\Users\mht\AppData\Roaming\Typora\typora-user-images\image-20220108171024696.png)]

具名插槽
<template><div class="father"><list title="美食" ><img slot="center" src="@/assets/logo.png" alt="" style="display:block;margin:0 auto;"><a slot="footer" href="">更多美食</a></list><list title="游戏"><ul slot="center"><li v-for="(item,index) in games" :key="index">{{item}}</li></ul><div slot="footer"><a  href="">单机游戏</a> <a  href="">网络游戏</a></div></list><list title="电影"><video slot="center" src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4" width="100%" controls palyauto="palyauto"></video><template slot="footer" ><div ><a  href="">经典</a> <a  href="">热门</a></div><div>欢迎来看</div></template><!-- 使用template 可以用新的写法 --><!-- <template v-slot:footer ><div ><a  href="">经典</a> <a  href="">热门</a></div><div>欢迎来看</div></template> --></list></div>
</template><template><div class="list_box"><h1>{{title}}分类</h1><!--定义一个插槽(挖个坑,等着组件的使用者进行填充)--><slot></slot><slot name="center">我是一些默认值,当使用者没有传递具体结构时,我会出现</slot><slot name="footer">我是一些默认值,当使用者没有传递具体结构时,我会出现</slot></div>
</template>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ci0fWBw5-1651137472221)(C:\Users\mht\AppData\Roaming\Typora\typora-user-images\image-20220108172904792.png)]

作用域插槽
<template><div class="father"><list title="游戏"><!-- 作用域插槽必须要用template包一层 --><template scope="gamesData"><ul><li v-for="(item, index) in gamesData.games" :key="index">{{ item }}</li></ul></template></list><list title="游戏"><template slot-scope="gamesData"><!-- 第二种新写法slot-scope="gamesData" --><h4>{{gamesData}}</h4><!-- { "games": [ "红色警戒", "穿越火线", "劲舞团", "超级玛丽" ], "msg": "hello" } --><ol><li v-for="(item, index) in gamesData.games" :key="index" style="color:red">{{ item }}</li></ol></template></list></div>
</template><template><div class="list_box"><h1>{{title}}分类</h1><!--定义一个插槽(挖个坑,等着组件的使用者进行填充)--><slot :games="games" msg="hello">我是一些默认值,当使用者没有传递具体结构时,我会出现</slot></div>
</template>
export default {name: 'List',props:["listData","title"],data() {return {games:[ "红色警戒","穿越火线","劲舞团","超级玛丽"],};},mounted() {},methods: {},
};

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0EpYxuYc-1651137472222)(C:\Users\mht\AppData\Roaming\Typora\typora-user-images\image-20220108193727515.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lLyFyBS8-1651137472222)(C:\Users\mht\AppData\Roaming\Typora\typora-user-images\image-20220108193742816.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UnPZaIli-1651137472222)(C:\Users\mht\AppData\Roaming\Typora\typora-user-images\image-20220108193748435.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NbaPmpf4-1651137472223)(C:\Users\mht\AppData\Roaming\Typora\typora-user-images\image-20220108193754156.png)]

路由

vue-router
https://www.jianshu.com/p/b3f4c1b3aab2
home首页的路由 search   login
public 里面引用默认样式router.currentRoute //获取当前页面的router路由组件与非路由组件的区别?
1:路由组件一般放置在pages|views文件夹,非路由组件一般放置components文件夹中
2:路由组件一般需要在router文件夹中进行注册(使用的即为组件的名字),非路由组件在使用的时候,一般都是以标签的形式使用
3:注册完路由,不管路由路由组件、还是非路由组件身上都有$route、$router属性
$route:一般获取路由信息【路径、query. params等等】
$router:一般进行编程式导航进行路由跳转【push|replace1】 两者区别是能不能记住历史记录5.路由跳转
路由的跳转有两种形式:
声明式导航router-link,可以进行路由的跳转
编程式导航push|replace,可以进行路由跳转编程式导航:声明式导航能做的,编程式导航都能在,
但是编程式导航除了可以进行路由跳转,还可以做一些其他的业务逻辑。路由传参,参数有几种写法?
params参数:属于路径当中的一部分,需要注意,在配置路由的时候,需要占位
query参数:不属于路径当中的一部分,类似于ajax中的queryString /home?k=v&kv= 不需要占位//路由传递参数:
//第一种:字符串形式
// this. $router. push(" /search/" + this.keyword+" ?k="+this. keyword.toUpperCase());
//第二种:模板字符串
// this.$router.push( /search/${this.keyword} ?k=${this. keyword.toUpperCase()})
//第三种:对象
//this.$router.push({name: "search" , params: {fkeywond:this.keyword } , query:[ k:this.keywordg))// 字符串
router.push('home')
// 对象
this.$router.push({path: '/login?url=' + this.$route.path});
// 带查询参数,变成/backend/order?selected=2
this.$router.push({path: '/backend/order', query: {selected: "2"}});
// 命名的路由
router.push({ name: 'user', params: { userId: 123 }})
嵌套路由

router-view

<router-view/> 是用来承载当前级别下的子级路由的一个视图标签,此标签的作用就是显示当前路由级别下一级的页面。
路由传参
params传参必须用 namequery 可以name 也可以 path$route: Object $router: VueRouter
this.$router.back()返回上一页
this.$router.go()
this.$router.push('/') 返回到别的页面自己决定编程导航传参
params与query一样的
this.$router.push('/login?token=mhtsm')  传参 可以传字符串也可以传对象this.$router.push({name:'Login',query:{token:'nam',age:15,}});
this.$route//拿参数
//结构赋值拿参const {query:{name},token,path}=this.$route;console.log(this.$route);console.log(token,name,path);// console.log(this.$route.query.age);
params与query 一样组件传参 可以传字符串也可以传对象
<router-link to="/about/5570">跳转</router-link>
<router-link to="{name:'/login',query:{token:'mht'}}">跳转</router-link>created() {const {params:{cid},name,path}=this.$route;// console.log(this.$route);console.log(cid,name,path);// console.log(this.$route.query.age);},{path: '/about/:cid',name: 'About',  }

嵌套路由 重定向

关于 vue-router 里 router-link 被激活时的状态

exact 是一个单独的属性,正确用法是 <router-link to="/home" active-class="bianlan" exact>。
这样,只有当路径刚好是 /home 时才会添加 bianlan 类名,而当路径是 /home/something 时则不会(因为不 exact)。
//二级路由
借助 vue-router,使用嵌套路由配置,就可以很简单地表达这种关系。
{path: '/home',name: 'Home',component: Home,// 重定向 // 默认显示组件redirect:'/home/aw',// 嵌套子路由children:[{path:'/home/aw',name:'Aw',component:Aw},{path:'/home/ak',name:'Ak',component: Ak,}]},组件(要有视图容器)<nav><router-link to="/home/aw">大儿子</router-link><router-link to="/home/ak">小儿子</router-link></nav><router-view></router-view>
//哪个被选中根据类名给样式//三级嵌套路由
路由的props配置
{path: '/home',name: 'Home',component: Home,// 重定向 // 默认显示组件redirect:'/home/aw',// 嵌套子路由children:[{path:'/home/aw',name:'Aw',component:Aw},{path:'/home/ak',name:'Ak',component: Ak,//props的第一种写法,值为对象,该对象中的所有key-value都会以props的形式传给Detail组件。// props:{a:1,b:'hello'}//props的第二种写法,值为布尔值,若布尔值为真,就会把该路由组件收到的所有params参数,以props的形式传给Detail组件// props:true//props的第三种写法,值为函数props({query:{id,title}){return {id,title}       }}]},
router-link的replace属性
<router-link replace ></router-link> 点击后的路由没有历史记录

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GjENSKC3-1651137472223)(C:\Users\mht\AppData\Roaming\Typora\typora-user-images\image-20220111210937303.png)]

编程式路由导航

this.$router.push{path:'/'query:{id:1}
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B93P1YzZ-1651137472224)(C:\Users\mht\AppData\Roaming\Typora\typora-user-images\image-20220111211606614.png)]

缓存路由组件
路由切换 input里面得到数据即将被销毁了包含的组件才会缓存 include="写组件名"
<keep-alive include="News">
<router-view></router-view>
</keep-alive>多个缓存用数组
<keep-alive include="["News","Index"]">
<router-view></router-view>
</keep-alive>
新的生命周期钩子路由组件独有的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SsR9hUWV-1651137472224)(C:\Users\mht\AppData\Roaming\Typora\typora-user-images\image-20220111213118598.png)]


缓存的无法清除定时器
News组件
activated(){News组件出现在我们面前激活调用一次
},
deactivated(){News组件消失在我们面前激活调用一次
}$nextTick(()=>{修改完DOM后放到页面了 才调用这个生命周期钩子
})
vue导航守卫

你可以使用 router.beforeEach 注册一个全局前置守卫:

const router = new VueRouter({ ... })router.beforeEach((to, from, next) => {// ...
})

当一个导航触发时,全局前置守卫按照创建顺序调用。守卫是异步解析执行,此时导航在所有守卫 resolve 完之前一直处于 等待中

每个守卫方法接收三个参数:

  • to: Route: 即将要进入的目标 路由对象
  • from: Route: 当前导航正要离开的路由
  • next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。
    • next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。
    • next(false): 中断当前的导航。如果浏览器的 URL 改变了 (可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。
    • next('/') 或者 next({ path: '/' }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。你可以向 next 传递任意位置对象,且允许设置诸如 replace: truename: 'home' 之类的选项以及任何用在 router-linkto prop 或 router.push 中的选项。
    • next(error): (2.4.0+) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError() 注册过的回调。
// 全局前置守卫 任何路由都会触发钩子
router.beforeEach((to,from,next)=>{// console.log(webCookie.getCookie('token'));const token=webCookie.getCookie('token');if(token){console.log();}else {// 未登录if(to.name==='login'){return next()}else {return next({path:'/login'})}}next();
})
//路由独享守卫{path: '/zhidingyizhiling',name: 'ZhidingiZhiling',component: ZhidingiZhiling,//路由独享守卫beforeEnter(to,from,next){const isLogin=trueif(!isLogin){next()}else{next('/')}}//元信息 全局后置守卫
router.afterEach((to,from)=>{document.title=to.meta.title
}){path: '/home',name: 'Home',component: Home,exact:true,// 重定向 // 默认显示组件redirect:'/home/aw',// 嵌套子路由children:[{path:'/home/aw',name:'Aw',component:Aw,meta: { title: '网易aw' }//相当于网页的标题},{path:'/home/ak',name:'Ak',component: Ak,meta: { title: '网易ak' }},{path:'/home/three',name:'three',component:three,redirect:'/home/three/sanjia',children:[{path:'/home/three/sanjia',name:'Sanjia',component:Sanjia},{path:'/home/three/sanjib',name:'Sanjib',component: Sanjib},]}]},//组件内的守卫beforeRouteEnter(to, from, next) {// 在渲染该组件的对应路由被 confirm 前调用// 不!能!获取组件实例 `this`// 因为当守卫执行前,组件实例还没被创建//beforeRouteEnter 守卫 不能 访问 this,因为守卫在导航确认前被调用,因此即将登场的新组件还没被创建。//不过,你可以通过传一个回调给 next来访问组件实例。在导航被确认的时候执行回调,并且把组件实例作为回调方法的参数。next(vm=>{vm.isShow=true;// 通过 `vm` 访问组件实例})},注意 beforeRouteEnter 是支持给 next 传递回调的唯一守卫。对于 beforeRouteUpdate 和 beforeRouteLeave 来说,this 已经 可用了,所以不支持传递回调,因为没有必要了。beforeRouteUpdate(to, from, next) {// 在当前路由改变,但是该组件被复用时调用// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。// 可以访问组件实例 `this`console.log(this.$route.params.cid);next()},beforeRouteLeave(to, from, next) {// 导航离开该组件的对应路由时调用// 可以访问组件实例 `this`//这个离开守卫通常用来禁止用户在还未保存修改前突然离开。该导航可以通过 next(false) 来取消。const comfirms=window.confirm('你确定要离开吗												

vue2.x学习笔记相关推荐

  1. Vue2.0学习笔记二 基础语法

    1. Mustache语法 Mustache语法也叫插值表达式,Mustache语法式通过{{}}渲染到页面,并且数据是响应式的. 数据的响应式:数据的变化导致页面的内容随之变化 效果图: 2. 指令 ...

  2. Vue2.0学习笔记一 :各种表达式

    #,过滤器 #,在Vue2.x中,过滤器只能在mustache绑定中使用,为了在指令帮定中实现同样的行为,你应该使用计算属性:     #,过滤器可以串联 {{ message | filterA | ...

  3. 【天禹老师】Vue2个人学习笔记

    一. Vue 核心 1. Vue简介 1.1 官网 中文官网 英文官网 1.2 介绍 1.2.1 Vue 是什么? 一套用于构建用户界面的渐进式JavaScript框架 作者:尤雨溪 1.2.2 Vu ...

  4. vue2.x 学习笔记for

    文章目录 Vue指令之`v-for`和`key`属性 v-for循环普通数组 v-for循环对象数组 v-for循环对象 v-for迭代数字 v-for循环中key属性的使用 Vue指令之v-for和 ...

  5. vue2.x 学习笔记

    div标签(HTML) div标签的作用是,设定字.画.表格等的摆放位置. DIV元素,是用来为HTML文档内大块(block-level)的内容提供结构和背景的元素. DIV标签,称为区隔标记. 什 ...

  6. Vue2.0学习笔记:Vue事件修饰符的使用

    事件处理 如果需要在内联语句处理器中访问原生DOM事件.可以使用特殊变量$event,把它传入到methods中的方法中. 在Vue中,事件修饰符处理了许多DOM事件的细节,让我们不再需要花大量的时间 ...

  7. vue2.0学习笔记 -- 常用指令

    一,(windows,node)淘宝镜像配置 1,创建文件夹:E:\nodejs\node_global 2,设置nodejs全局目录,在cmd中输入npm config set cache &quo ...

  8. 尚硅谷Vue2学习笔记分享

    前言 这里是尚硅谷Vue2的学习笔记分享. 原视频是尚硅谷Vue2.0+Vue3.0全套教程丨vuejs从入门到精通 Vue3的笔记链接 文章目录 前言 初识Vue 模板语法 数据绑定 el和data ...

  9. Vue学习笔记(5)(Vuex)

    Vue2.x学习笔记.原视频教程:最全最新Vue.Vuejs教程,从入门到精通_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili Vuex 认识Vuex 官方解释:Vuex 是一个专为 Vue.js ...

最新文章

  1. Android开机自启监听网络改变源码
  2. [Redux/Mobx] Mobx和Redux有什么区别?
  3. 【机器学习】总结:线性回归求解中梯度下降法与最小二乘法的比较
  4. 减治法在查找算法中的应用(JAVA)--快速查找
  5. jfreechart createBarChart 去掉立体感
  6. 摘自网络上总结出的一些开源的技术
  7. C++请不要问我string s=”a”+”b”分配了几次内存
  8. ipv6有必要打开吗_路由器中的IPv6功能需不需要开启?
  9. 删除IE加载项及取消加载项的提示
  10. Sql查询某个字段是否包含小写字母或小写
  11. 小丁带你走进git世界一-git简单配置
  12. 笔记·Pandas几类数据读写方法对比——csv,parquet,feather和pickle
  13. 没有学历可以学习游戏建模吗?这问题真致命!
  14. Ubuntu18.04 因断电开机报错:utmp处卡死
  15. alert弹框DeprecationWarning
  16. 地铁怎么坐才不能做反_地铁怎么坐,地铁怎么坐才不能做反
  17. 工业相机各种参数计算方法
  18. 如何使用 Director 编写“拼图游戏”
  19. android 编译 icu,使用NDK构建ICU
  20. 重磅发布 | 图像图形学发展年度报告综述专刊《中国图象图形学报》2022年第6期...

热门文章

  1. R for beginners
  2. 大数据战略落地实施 上海数据中心交易系统开放
  3. torch.randn()参数size与输出张量形状详解
  4. 低代码的后浪真正冲刷掉的是什么
  5. [Java开发之路](8)输入流和输出流
  6. 螺旋式正方形制作python
  7. RHEL---http服务解读和搭建
  8. python发微信语音没声音怎么回事_苹果手机微信语音没声音怎么回事?
  9. 如何实现打印机共享?其实很简单
  10. 一个小老板眼中的开发工具— PowerBuilder 杂谈(转)