1.comput ed与watch的区别
computed:监听多个数据或者一个数据来维护返回一个状态值,只要其中一个或多个数据发生了变化,则会重新计算整个函数体,重新返回状态值
watch:只能一个一个监听数据,只要这个数据发生变化,就会返回两个参数,第一个是当前的值,第二个是变化前的值。每当变化的时候,则会触发函数体的逻辑行为,根据逻辑行为做后续的操作
2.key的作用
1. key是辅助diff算法的 做最小量的更新 key 为了提高渲染效率 进行新旧虚拟dom的对比时一个标识 如果有相同的key 直接复用 如果不同的则创建新的对象进行替换的操作
2. diff算法的规则 深度优先 同层比较
注:使用key的时候兄弟元素之间不能有相同的key值
3.// <!-- 1.虚拟DOM中key的作用:
key是虚拟DON对象的标识,当数据发生变化时,Vue会根据【新数据】生成【新的虚拟DON】,
随后Vue进行【新虚拟DOM】与【旧虚拟DOM】的差异比较,比较规则如下:
.对比规则:
(1).旧虚拟DOM中找到了与新虚拟DOM相同的key:
①.若虚拟DOM中内容没变,直接使用之前的真实DOM!
②.若虚拟DOM中内容变了,则生成新的真实DOM,随后替换掉页面中之前的真实DOM。
(2).旧虚拟DOM中未找到与新虚拟DOM相同的key
创建新的真实DOM,随后渲染到到页面。
4.//用index作为key可能会引发的问题:
①若对数据进行:逆序添加、逆序删除等破坏顺序操作:
会产生没有必要的真实DOM更新==>界面效果没问题,但效率低。
②如果结构中还包含输入类的DOM:
会产生错误DOM更新==>界面有问题。
5.//开发中如何选择key?:
① 最好使用每条数据的唯一标识作为key,比如id、手机号、身份证号、学号等唯一值。
② 如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示,使用index作为key是没有问题的。
6. //v-for 使用key的作用:
① 为了高效的更新虚拟dom, 提高列表渲染效率 提高页面的性能(减少dom操作)
② 底层的原理通过diff算法 对操作前后的dom树 进行一一对比, 默认没有key时 是逐个替换
有key 保证了元素的唯一性,在对比时不再逐个替换 而是在合适的位置添加或删除
3.v-for与v-if
1. <!-- vfor 和 vif 在一起 并没有减少循环次数,而是先解析vfor 再解析v-if。v-for的等级比v-if的高。-->
<div>
<div v-for="(obj, index) in lists" :key="obj.id" v-if="obj.price>= 500">{{obj.name}}</div>
//这个时候页面上并没有把obj.price的内容显示出来,但是也没有减少渲染的次数,可以说是先渲染了,在删除
</div>
2.解决方法
<!-- 使用过滤方法 -->
<div>
<div v-for="(obj, index) in lists.filter(item => item.price>=500)" :key="obj.id">{{obj.name}} </div>
</div>
4.模板的使用
<!-- template 模板 h5 提出的新标签 不会渲染到页面中 display:none (可以写到Vue实例中,或者当作组件的模板)
使用该标签做为模板
不会产生额外的新标签
要使用 id选择器
-->
<div>
<template id="a">
<div>
999
</div>
</template>
</div>
<!-- 不会显示 -->
<div id="app">
<template>
<div>
123
</div>
</template>
<div>
<div>
1234
</div>
</div>
<com></com>
</div>
<!-- 里面的都会显示 -->
<script src="../../vue/vue.js"></script>
<script>
Vue.component("com", {
template: "#a"
})
let app = new Vue({
el: "#app",
data: {
},
methods: {
}
})
5.computed与methods的区别
1. 区别 方法需要调用(其实在方法中data中的数据发生改变的时候,方法的调用也会更新)
2. 计算属性有缓存 方法没有
3. 如果这些函数的名字相同优先使用method
prop -> method -> data -> computed -> watch
6.class与style
1.<!-- 没有进行属性绑定就是一个普通的类名 -->
<div class="test">123</div>
<div :class="active">动态绑定 active声明在data中: 字符串 对应类名</div>
<div :class="{active:'value'}">key是类名,value意思是true或者false</div>//这里的active为类名,data里可以不用定义
<span :class="{active: BMI > 0 && BMI < 18.5}">偏瘦</span>//后面为true时执行,利用改变BMI的值来确定active的样式,是否显示
<!-- value 变量 必须要声明,表示true或者false-->
<div :class="{active:value}">对象的另外一种形式</div>
<div :class="['red','blue']">value是字符串的时候,值为style里定义的类名</div>
<div :class="[red,blue]">value是变量的时候其值要在Data里面定义,且定义时red,blue为类名</div>
<div :class="[{color:'blue'},{fontSize:'50px'}]">变量为数组类型</div>
2.
<div :style="'color:pink'">style样式</div>
<div :style="styleObj">对象的形式 </div>
<div :style="styleArray">数组的形式 </div>lue
Data{
styleObj: {
color: "blue",
"font-size": "40px",
backgroundColor: "yellow"
},
styleArray: [{
color: "blue"
}, {
fontSize: '50px'
}],
}
7.数组的更新
1.通过下标修改不是响应式的,因为不会触发set函数
2. vue 把数据的7个方法进行了重写 调用以下7个方法 可以实现响应式
push(), pop(), shift(), unshift(),splice(),sort()reverse()
3.发filter(),concat(),slice()是替换数组,生成新的数组,并不改变原数组的值
8.对象的增删实现响应式
1. data中所声明的变量 会通过defineReactive方式 调用definePropety方法 生成对应的set get函数
而没有声明 后续添加上 或者 删除都是非响应式的
2. 解决动态添加为响应式
//1.使用实例方法
this.$set(this.obj,"gf","lili");
//2.静态方法
Vue.set(this.obj,"gf","nana");
//3.调用assign方法 可以添加多个
this.obj = Object.assign({},this.obj,{gf:"nana",money:"200000"});
9.数组的增删实现响应式
this.array[0] = 100;//不是响应式
this.array.length = 10;//不是响应式
// 数据响应式
this.$set(this.array,0,100);
Vue.set(this.array,0,100);
this.array.splice(0,1,100);//从数组的索引号为0开始,更改的个数,更改为100,如果更改多个数,后面的参数可为多个
this.array = [100,2,3,4,5,6]//直接给数组赋一个新值
10.响应式原理
1. 响应式原理: 数据劫持 + 观察者模式
2. data中所声明的变量 会通过defineReactive方式 调用definePropety方法 生成对应的set get函数,当data中数据发生变化后,会通知对应的监听器,重新生成新的虚拟dom对象,根据diff算法 把新老虚拟dom做对比,如果存在差异 则替换或删除创建元素 并打补丁 patch(上树)
11.自定义按键修饰符
1.Vue.config.keyCodes.a = 65;
// 配置多个
2. Vue.config.keyCodes = {
a:65,
v:86,
up:[38,87]
}
12.表单提交
1. <!-- 使用vmodel 必须要指定value属性 值要和sex中的值相同 才能被选中-->
<input type="radio" name="" id="" v-model="sex" value="男"> 男
<input type="radio" name="" id="" v-model="sex" value="女"> 女
data{
sex:"男"
}
2.
<!-- 使用vmodel 必须要指定value属性 值要和sex中的值相同 才能被选中-->
<input type="checkbox" name="" id="" v-model="gfs" value="lili"> 丽丽
<input type="checkbox" name="" id="" v-model="gfs" value="shasha"> 莎莎
<input type="checkbox" name="" id="" v-model="gfs" value="nana"> 娜娜
data{
gfs:["lili","shasha"]
}
3.
<select name="" id="" v-model="city1">
<option value="1">北京</option>
<option value="2">郑州</option>
<option value="3">上海</option>
</select>
data {
city1:1
}
13.异步刷新
1.$nextTick的用法 在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。
Vue 实现响应式并不是数据发生变化之后 DOM 立即变化,而是按一定的策略进行 DOM 的更新。Vue 在更新 DOM 时是异步执行的。
所以那些同步的代码会先执行。
用法如下:
methods:{
2 testClick:function(){
3 let that=this;
4 that.testMsg="修改后的值";
5 that.$nextTick(function(){
6 console.log(that.$refs.aa.innerText); //输出:修改后的值
7 });
8 }
9 }
14.传递数据(父传子,子传父)
1. <!-- 父向子传值
1.父组件中 通过自定义属性 进行数据的传递
2. 子组件 通过 props:[] 进行接收
-->
2. // 单向数据流 子组件中不要修改父组件中的数据 只能向下流动 (否则会造成数据流混乱)
// 子向父传递数据
1.子组件中 this.$emit('xxx',val)
2.父组件中 绑定自定义事件类型 @xxx='事件处理函数'//不传参的时候默认传的也是$event,即子向父传递的数据。如果有参数一定是$event
15.props的命名问题
1. <div id="app">
<com mydata="123" my-data1="456" my-data2="789" MyData3="abc" my-data4="def"></com>//这里可以带-,但不区分大小写
</div>
<template id="a">
<div>
<h1>展示数据:
{{mydata}} -- {{myData1}} -- {{myData2}} -- {{mydata3}} -- {{MyData4}}
</h1>
</div>
</template>
<script src="../../vue/vue.js"></script>
<script>
// 1.自定义属性为 - 连接 ,接收时可以使用 - 接收, 使用时必须是小驼峰
// 2.自定义属性为 - 连接 ,接收时小驼峰 ,使用时小驼峰
// 3.自定义属性为 - 连接 ,接收时大驼峰 ,使用时大驼峰
// 4.自定为大驼峰浏览器转换为小写,接收时用小写,使用时也用小写
Vue.component("com", {
props: ["mydata", "my-data1", "myData2", "mydata3", "MyData4"],
// template:"#a"
template: `<div>{{myData1}}--{{ my-data1}}</div>` //总结:不管是模板字符串,还是上面的模板都不可以带-。但是组件名是可以带-
})
2.组件标签用的时候,是在html中,不区分大小写,但是可以用-横线连接的方式
16.格式化时间
1. 引入 <script src="https://unpkg.com/dayjs@1.8.21/dayjs.min.js"></script>//Day.js的一个插件
<h1>dayjs插件 格式化事件 {{now | fdate}}</h1>
let app = new Vue({
filters: {
formatMessage(v, a) {
return v + a
},
fdate: function(v) {
//Day.js中需要传入一个Date的实例对象
return dayjs(v).format("YYYY年MM月DD日")//2022年08月31日
}
}
})
2.过滤器
<h1>全局过滤器 默认将|前的值 当作过滤器第一个参数: {{price | formatPrice}}</h1>
<h1>全局过滤器 传递两个参数: {{2022 | formatStr(price,31)}}</h1>//也可以传递data里面的值如price
17.Vue实例在页面的渲染
let app = new Vue({
el: "#app",//没有挂载el元素的时候,后面需要执行app.$mount(document.querySelector('#app'))来挂载
template: "#a", //有模板的时候直接就渲染的是模板的内容了。就不渲染 <div id="app"> </div>的内容了
data: {
msg: "1232"
}
})
18.生命周期函数
let app = new Vue({
el: "#app",
template: "#a", //有模板的时候直接就渲染的是模板的内容了。就不渲染 <div id="app"> </div>的内容了
// 生命周期函数 钩子 从组件的生 到 死的过程 8 + 2
//1.创建阶段
// 2.更新阶段
// 3.销毁阶段
// 创建阶段 4
// 主要使用 created 和 mounted 进行网络请求的发送
beforeCreate() {
// 创建之间 data还没有被初始化
},
created() {
//data 已经被初始化 可以使用了
},
beforeMount() {
// 虚拟dom生成 并没有生成真是dom 挂载到页面中
},
mounted() {
// 真实dom已经生成 并挂载到页面中 可以访问dom节点了
},
// 2.更新阶段
beforeUpdate() {
// 数据已经是最新值 但是页面中还是旧数据
},
// 不要尝试在updated函数中修改data中的数据 死循环
updated() {
// 已经更新完毕 页面中已经是最新的数据了
},
// 3.卸载阶段 Destroy 销毁
//
beforeDestroy() {
// 清除 事件监听 定时器 延时器的清除
},
destroyed() {
// 销毁完成
},
})
19.父子组件中生命周期的执行顺序
1父子创建的执行顺序
// 父组件 beforeCreate
// 父组件 created
// 父组件 beforeMount
// 子组件 beforeCreate
// 子组件 created
// 子组件 beforeMount
// 子组件 mounted
// 父组件 mounted
2父子更新的执行顺序
// 父组件 beforeUpdate
// 子组件 beforeUpdate
// 子组件 updated
// 父组件 updated
3.子组件更新的顺序
// 子组件 beforeUpdate
// 子组件 updated
4.父组件更新
// 父组件 beforeUpdate
// 父组件 updated
5.父子销毁的执行顺序
// 父组件 beforeDestroy
// 子组件 beforeDestroy
// 子组件 destroyed
// 父组件 destroyed
6. 子组件销毁
// 父组件 beforeUpdate
// 子组件 beforeDestroy
// 子组件 destroyed
// 父组件 updated
20.手写v-model指令,并熟悉自定义指令的用法
<div id="app">
<input type="text" v-mymodel="num"> {{num}}
</div>
<script src="../libs/vue.js"></script>
<script>
let app = new Vue({
el: "#app",
data: {
num:123
},
directives:{
mymodel:{
inserted(el,bind,vnode){
el.value = bind.value;//bind.value为指令绑定的值
el.oninput = function () {
vnode.context[bind.expression] = this.value//vnode.context为Vue的实例,bind.expression为指定绑定的属性名
}
}
}
}
})
21.使用template标签当作模板时,应注意的点
22.子组件直接修改,父组件传过来的值,控制台会报错,用props传过来的值,需要接一下
//子组件可以使用data和computed来接受父组件传的值,之后做相关操作
1. props: ['subnum'],
data() {
return {
count:this.subnum
}
}
-->this.$emit("sub", --this.count);//且用data来接受父组件的值时,数据是非响应式的。即在父组件中修改这个值。子组件里的这个值不会变。因为data里的数据只初始化一次。
2.computed 来接收
// 为什么使用中间变量接收 是因为计算属性默认只定义了 get函数 没有set函数
// 如果定义set 就必定又触发修改父组件传递过来的值 所以定义中间变量 只获取计算属性中的值
computed: {
cnum(){
return this.subnum
}
--> var num = this.cnum
--> this.$emit("sub", --num);//注用computed来接受父组件的值做相应操作的时候。数据是响应式的。即父组件中改变这个值。子组件也会改变。
23.ref的使用
// ref reference 引用 主要是用来在vue中获取dom元素的
// vue不建议直接操作dom元素
如:
<div id="app">
<input type="text" ref="input">
</div>
----------------------------------------------------
let app = new Vue({
el: "#app",
data: {
},
methods: {
handle() {
this.$refs.d1.innerText = 455;
}
24.mixin混入的应用
// mixin 混入(组件中可以使用mixin里的数据和方法)
// 把相同的业务逻辑抽离出来 封装在一个单独js文件中 公用js代码(有局部混入和全局混入)
1.尽可能不要使用全局混入
// 注意传递为一个对象
// Vue.mixin(mixin);
2.局部混入
var mixin = {
data() {
return {
show:true,
msg:123
}
},
methods: {
handle(){
this.show = false;
}
}
--------------------------------------------
Vue.component("modal",{
template:"#a",//可以使用引入的mixin里的属性和方法
// 局部混入
mixins:[mixin]
}
3.模板中用到一些方法和数据的时候的执行顺序
// 1.优先执行混入的生命周期函数
// 2.计算属性,过滤器,方法,data的值 都优先使用组件的
25.兄弟间的传值
方法一
//思路
// 1.子 发射给父组件
// 2.父组件保存
// 3.父prop 传递另外一个子组件
方法二 bus
// 思路
// this.$emit() 发射
// this.$on() 监听
// this.$off() 解绑
注意!!!// 发射时机问题 一定要先监听 后 发射
如:
var vm = new Vue();
Vue.component("comb", {
template: "#b",
data() {
return {
content: "123"
}
},
mounted() {
vm.$on("send", (v) => {
// 注意this指向的问题!!!,普通函数里的this指向vm这个实例
this.content = v;//用content接受兄弟组件传过来的值
})
}
})
Vue.component("coma", {
template: "#a",
data() {
return {
msg: "i am A"
}
},
mounted() {
setTimeout(() => {
vm.$emit("send", this.msg);//使用延时器使触发在监听之后
}, 1000);
}
})
26.插槽
// 插槽就是子组件向父组件提供一个容器 用来显示 组件标签中间内容的 中间的内容可以是 字符串 标签 组件
// 一般用在大多数样式结构相同 极个别不相同时使用
<!-- 作用域插槽:的作用是子组件的有些数据展示样式,想要父组件决定,此时可以用作用域插槽 -->
1.匿名插槽
<div id="app">
<weather>
多云转晴
</weather>
</div>
-----------------------
Vue.component("weather",{
template:"<div>
<h1>天气预报情况:</h1>
<slot></slot>//显示的内容则为 多云转晴
</div>",
})
2.具名插槽
<!-- v-slot:xxx #xxx 使用在模板中或者组件中-->
<com>
<template v-slot:header>
<div>
头内容
</div>
</template>
<template #default>
<div>
匿名内容
</div>
</template>
</com>
--------------------------
Vue.component("com", {
template: "
<div>
<h1>网页头部</h1>
<slot name="header"></slot>//头内容
</div>
"
})
3.作用域插槽
父:
<div id="app">
<com>
<!-- 作用域插槽:的作用是子组件的有些数据展示样式,想要父组件决定,此时可以用作用域插槽 -->
<!-- obj是子组件插槽slot中动态绑定的数据组成的一个对象.名字可以随便定义 -->
<template v-slot:header="obj">//可以结构赋值 <template v-slot:header="{uname,age,list">,名字要相同
<div>
<span v-for="(item, index) in obj.list" :key="index">{{item}}</span>
</div>
</template>
</com>
</div>
子:
Vue.component("com", {
template: "
<div>
<slot name="header" :list="list" :uname="name" :age="age"></slot>
</div>
",
data() {
return {
name: "张三",
age: 20,
list: ["丽丽", "莎莎", "娜娜"]
}
},
})
26.监听器的使用
1.使用场景:当一条数据影响多条数据的时候就需要用watch
watch: { //监听数据的变化,并根据监听的数据的变化,做出相应的操作。监听的函数名,必须是data里定义的数据
// 简写
msg(newValue,oldValue){
console.log("新值: ",newValue,"老值:",oldValue);
if(typeof newValue == "number"){
alert("我变成了一个数");
}
}
// 深层时 直接监听外层对象 无效,下面这个代码无效
"gf"(n,o){
console.log("新值: ",n,"老值:",o);
}
// 可以监听到数据的变化的,但是可以监听对象里的属性
"gf.age"(n,o){
console.log("新值: ",n,"老值:",o);
}
//如果想要监听一个对象,可以深度监听
gf: {
deep: true, // 是否要深度监听
immediate: true, // 是否立即监听,第一次渲染组件的时候就执行,无需数据发生变化才执行。这个时候的第一次,n为当前的值,o为undefined
// 函数名称必须为 handler
handler(n, o) {
console.log("新值: ", n, "老值:", o);
}
}
}
})
27.当是爷组件和孙组件之间的传值的时候,不能直接传递,方法有
1.需要一层一层的用动态属性加props和发射时间进行传递,十分麻烦。
2.可以参考兄弟组件之间的传值,借助一个公共的bus总线,进行传值
var bus = new Vue();
bus.$emit("send",res.data);//发射事件之后。监听事件会自动执行
bus.$on("send",(v) => {
this.lists = v;
})//一定要注意顺序,先监听,在发射。
28.动态组件
<div id="app">
<!-- component 决定显示哪个组件 会频繁创建销毁 影响性能 -->
<component :is="cname"></component>//根据变量cname来切换不同的组件,但会频繁的创建于销毁,所以用以下的方法
<!-- component keep-alive 内置组件 -->
<!-- 提升性能 会缓存 不会频繁的创建和销毁 -->
<keep-alive>
<component :is="cname"></component>
</keep-alive>
<!-- <home></home>
<home></home> -->
</div>
28.keep-alive的用途
1.作用
实现组件缓存,保存这些组件的住状态,以避免反复渲染导致的性能问题。
2.场景
tabs标签页,后台导航,vue性能优化
3.原理
vue.js内部将dom节点抽象成了一个个vnode节点,keep-alive组件的缓存也是基于vnode节点,而不是直接存储dom结构。它将满足条件的组件在cache对象中缓存起来,在需要重新渲染的时候再将vnode节点从cache对象中取出并渲染
29.兄弟组件之间的周期函数的执行顺序(适用于传值时候的发射于监听事件)
1.两个兄弟组件传值,用发射$emit和监听$on,一定要注意顺序,监听一定要在发射的前面。所以如果都写在mounted的周期函数里。大多可能是发射发生在监听之前了。
2.可以让监听事件写在beforeMount函数之前。发射事件写在mounted函数里。这样就可以保证监听在发射之前了。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mVXhmjGF-1681263996215)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20220905190512256.png)]
30.路由传参的方式
1.通过查询字符串的形式进行传递$route.query的对象的形式
①<router-link to="/home?name=娜娜&age=18">首页</router-link>
② <template id="home">
<div>
<!-- $route 当前路由信息的对象 包含路由信息 路由参数 -->
<!-- <h1>接收路由传递的参数:{{$route.query.name}} -- {{$route.query.age}}</h1> -->
<h1>接收路由传递的参数:{{$route.query.name}} -- {{$route.query.age}}</h1>
</div>
</template>
③ const router = new VueRouter({
routes:[
{path:"/home",component:home}
]
})
2.动态路由传参 $route.params
①<router-link to="/user/1">用户1</router-link>
<router-link to="/user/2">用户2</router-link>
<router-link to="/user/3">用户3</router-link>
②var usercom = {//一个组件来回切换的时候,created等周期函数只执行一次。只不过数据发生了改变
template:"#user",
// 解决办法:
computed:{
id(){
return this.$route.params.id//获取了传过来的id
}
}
}
③ // 注意事项: 动态路由 必须要添加:
const router = new VueRouter({
routes:[
{path:"/user/:id",component:usercom}//需要写:id
]
})
3. 使用命名路由由params字段传值,使用$route.params接收数据
使用query对象传值,使用$route.query接收数据
① <!-- 根据名称 进行路由的跳转 -->
<!-- 一定要记得动态绑定下 -->
<router-link :to="{path:'/home',query:{id:1,uname:'张三',age:18}}">home</router-link>
<router-link :to="{name:'home',query:{id:1,uname:'张三',age:20}}">home</router-link>
<!-- 如果要使用params进行传递参数 必须使用命名路由 path的方式是获取不到数据的 -->
<router-link :to="{name:'about',params:{id:2,uname:'李四',age:18}}">about</router-link>
<!-- 下面的有问题的,因为使用params传值,不能使用path路径 -->
<router-link :to="{path:'/about',params:{id:2,uname:'李四',age:18}}">about</router-link>
②<template id="about">
<div>
<h1> params :传递参数:{{$route.params.id}} -- {{$route.params.name}} --{{$route.params.age}}</h1>
</div>
</template>
③ const router = new VueRouter({
routes: [{
path: "/about",
name: "home",
component: home
}]
})
4.props传参
① bool模式
使用动态路由和使用命名路由由params字段传递的值将被返回出去,组件里用props接受,即props接收$.route.params的值
<router-link :to="{name:'about',params:{id:2,uname:'李四',age:18}}">bool 模式 </router-link>//bool模式传参
<router-link to="/about/1">bool模式</router-link>//bool模式传参
② 函数模式
在函数中把使用命名路由由params字段传值,使用query对象传值,返回出去,然后在组件里用props接收
一.<router-link :to="{name:'home',params:{id:1,uname:'张三',age:20}}">函数模式</router-link>
二. const router = new VueRouter({
routes: [{
path: "/home",
name: "home",
component: home,
props: function($route) {//函数的第一个参数为$route即路由对象,可以起别名
return $route.params;
}
}])
三.var home = {
template: "#home",
props: ['id', 'uname', 'age']
}
③ 对象模式
<router-link :to="{name:'search'}">对象模式</router-link>
const router = new VueRouter({
routes: [{
path: "/search",
name: "search",
component: search,
props: {
id: "3",
uname: "王五",
age: 20
} //传一些静态的值
}])
31.路由监听
路由监听①在组件的watch监听器中对$route这个字段进行监听
②全局监听路由在app.vue组件中,watch监听$route
③也可以在全局路由守卫beforeEach函数中操作全局路由
1.<router-link to="/user/1">用户1</router-link>
<router-link to="/user/2">用户2</router-link>
2. var usercom = {
template: "#user",
data() {
return {
id: ''
}
},
created() {//只有当组件渲染的时候执行一次,所以后面切换路由的时候,id不变化
// console.log(this.$route);
// this.id = this.$route.params.id;
},
// 解决办法: 计算属性见 -2
// 监听器
watch: {
// 1 配合 (1) data中赋值 (2) 生命周期函数中赋值 (ps:二选一即可)
// $route(to,from){
// this.id = to.params.id;
// }
// 2.无需配合 (1) data中赋值 (2) 生命周期函数中赋值
// 第一次加载该组件时 立即执行该函数 immediate
$route: {
immediate: true,
handler(to, from) { //第一次渲染组件的时候就执行了。此时to为当前的,from为undefined
console.log("111111", to, from);
this.id = to.params.id;
}
}
}
}
3. const router = new VueRouter({
routes: [{
path: "/user/:id",
component: usercom
}]
})
32.前置路由守卫(全局路由守卫)
const router = new VueRouter({
routes: [{
path: "/home",
component: home
},
// meta 对象中的key自定义
{
path: "/about",
component: about,
meta: {
author: true
}
]
})
// 购物车页面必须时登录之后才可以访问 否则跳转到登录页面
// 路由的前置守卫:当:初始化时执行、每次路由切换前执行。(此时ruoter挂载了前置路由守卫,当在路由规则里定义的路由发生变化时,则会执行该路由守卫),只是后面的参数发生改变的时候,也会执行,该前置守卫
router.beforeEach((to, from, next) => {
console.log(1111111);
// to and from are both route objects. must call `next`.
console.log(to);
if (!to.meta.author) {//to为即将跳转的路由的参数对象,相当于$route。在跳转到to对应的路由时,要先经过这个路由守卫,执行里面的逻辑操作
next();
} else {
var token = localStorage.getItem("token");
if (token) {
next();
} else {
next({
path: "/login",
query: {
fpath: to.path
}
}); //next的参数,还可以是一个对象
}
}
})
33.组件的路由守卫
var com = {
template: "#a",
data() {
return {
lists: []
}
},
// watch:{
// $route(to,from){
// this.getInfo(to.params.id)
// }
// }
// 组件内的路由守卫
beforeRouteEnter(to, from, next) {
// ...
// 路由参数的切换不会调用该函数 只有当前路由第一次进入时有效
// 不要在此发送网络请求
console.log("enter", to);
next(); // 必须要调用next函数 放行
},
beforeRouteUpdate(to, from, next) {
// ...
console.log("beforeRouteUpdate", to);
this.getInfo(to.params.id);
next();
},
// 当路由地址与当前组件不对应时 触发离开,如果只是路由参数发生变化,不会调用该函数
beforeRouteLeave(to, from, next) {
// ...
console.log("beforeRouteLeave");
}
}
34.编程式导航
声明式导航如<router-link to="/user/1">用户1</router-link>,渲染成a标签,需要点击才会执行。而编程式导航是执行该代码的时候,就跳转到对应的路由
1.this.$router.push的参数
// 字符串路径
router.push('/users/eduardo')
// 带有路径的对象
router.push({ path: '/users/eduardo' })
// 命名的路由,并加上参数,让路由建立 url
router.push({ name: 'user', params: { username: 'eduardo' } })
// 带查询参数,结果是 /register?plan=private
router.push({ path: '/register', query: { plan: 'private' } })
// 带 hash,结果是 /about#team
router.push({ path: '/about', hash: '#team' })
2. // 把当前的页面替换为对应的页面,因此替换不会产生历史记录
this.$router.push({ path: '/home', replace: true })
// 相当于
this.$router.replace({ path: '/home' })
3.this.$router.go(-1);
35.vue中如何写动画
36.代理服务器
1.在vue.config.js文件中写入
devServer: {
host: "localhost",
port: "8081", //使程序运行在8081这个端口
open: true, //在终端运行的时候,立即打开这个页面
proxy: { //代理服务器的用法
"/dy": {
target: "http://capi.douyucdn.cn/api",
pathRewrite: { //去掉前缀/dy
"^/dy": ""
},
changeOrigin: true
},
}
}
2.发送请求时
created() {
this.$axios({
method:"get",
// 127.0.0.1:8080/dy/v1/getColumnList
// 替换成
// http://capi.douyucdn.cn/api/dy/v1/getColumnList
// pathRewrite 去掉了前缀dy
// http://capi.douyucdn.cn/api/v1/getColumnList
url:"/dy/v1/getColumnList"
}).then((res) => {
console.log(res.data)
})
}
37.组件中data为什么是一个函数
1.一个组件被复用多次的话,也就创建了多个实例。实质上,这些实例用的都是同一个构造函数
2.如果data是对象的话,对象属于引用类型,会 影响到所有实例,所以为了保证组件不同的实例之间data不冲突,data必须是一个函数。拥有单独的作用域
38.特殊的函数形参
1. function test({
x = 0,
y = 0
} = {}) {
console.log(x, y);
}
test(); // 0 0
test({}); // 0 0
test({
x: 1,
y: 1
}); // 1 1
test({
a: 1,
b: 2
}); // 0 0
2. function test2({
x,
y
} = {
x: 0,
y: 0
}) {
console.log(x, y)
}
test2(); //0 0
test2({}) // undefined undefined
test2({
x: 10
}) //10 undefined
test2({
x: 10,
y: 100
}) //10 100
39. .native的用法
1.在父组件中写入子组件标签,并给子组件标签写入事件函数,是没有任何效果的,需要使用.native的方法
.native 在父组件中把子组件当作普通的html标签 进行事件的绑定
<Room v-for="(item) in lists" :key="item.room_id" :item="item" @click.native="handle"/>//这个时候写入该事件,点击的时候,是有效的
40.样式穿透::v-deep的使用
1.在给一些element-ui和vant-ui里的组件修改样式的时候,直接写一个类名,给相应的样式的时候,是不能修改成功的,因为此时,如写在了HomeView.vue组件里用element-ui里的组件的时候,HomeView.vue组件是element-ui里的组件的父组件。HomeView.vue组件里写的样式,其子组件不能用,即使里面的标签有相同的类名也不可以,这个时候,父组件在写样式的时候,需要用到深度选择器即样式穿透。这个啥时候,子组件里的标签写入一样的类名,也就拥有相同的样式了
2.方法
① 1. >>> 只能用在原生的css中
② 2. /deep/ 脚手架 3以上无效
③3. ::v-deep 常用
::v-deep .el-input__icon {
line-height: 30px;
}
41.scoped的作用
1.在页面的<style></style>里面
一定要写上scoped:(代表仅在当前页面生效),
如果没有写上这个,就代表是全局样式,容易污染到其他页面的element样式)
42.json-serve的使用
1.安装npm i json-server -g插件
2.建立一个文件夹,在文件夹中放入如db.json文件
3.让这个文件夹在终端中打开,执行语句json-server --watch db.json --port 5001
之后就可以发送请求,进行delete,get,put,post请求了
43.axios的使用
1. 发送get 请求
2. get 请求传递参数
2.1 通过传统的url 以 ? 的形式传递参数
axios.get('http://localhost:3000/axios?id=123').then(function(ret){
console.log(ret.data)
})
2.2 restful 形式传递参数
axios.get('http://localhost:3000/axios/123').then(function(ret){
console.log(ret.data)
})
2.3 通过params 形式传递参数 //使用params传递的参数。后台也用req.query来获取
axios.get('http://localhost:3000/axios', {
params: {
id: 789
}
}).then(function(ret){
console.log(ret.data)
})
3 axios delete 请求传参 传参的形式和 get 请求一样 (也可以用?链接的那种还有restful的那种)
4 axios 的 post 请求//默认传递json形式的数据,此时服务端需要设置相关的配置
4.1 通过选项传递参数
axios.post('http://localhost:3000/axios', {
uname: 'lisi',
pwd: 123
}).then(function(ret){
console.log(ret.data)
})
5 axios put 请求传参 //和 post 请求一样
axios.put('http://localhost:3000/axios/123', {//123是id写到了url里面了
uname: 'lisi',
pwd: 123
}).then(function(ret){
console.log(ret.data)
})
44.使用this.$route.push(‘path’,query{ })获取的数据,一刷新,就没有了
1. 存储在sessionStorage中
2. vuex
3.动态路由 拼接在地址中 /a/1/2/3/4 地址栏变得丑陋
①.通过this.$route.push({name:'xx',params:{id:123}}) 传递一个id到组件中,然后在组件中通过id来获取这个数据,因为id是存在url之后的,不管怎样刷新,都是存在的
②.且在路由的routes[{
path:'/home/:id'
}]来动态定义一下id
③.使用this.$route.params.id
45.router里的routes地path路径里什么时候写:id什么时候不用
1.
动态路由传参 $route.params
①<router-link to="/user/1">用户1</router-link>
<router-link to="/user/2">用户2</router-link>
<router-link to="/user/3">用户3</router-link>
③ // 注意事项: 动态路由 必须要添加:
const router = new VueRouter({
routes:[
{path:"/user/:id",component:usercom}//需要写:id
]
})
2.
① this.$router.push({ name: 'detail', params: { id: item.id } })
② const router = new VueRouter({
[{
path: '/detail/:id',//来获取params里面地id,是url地址栏有/id(用于刷新页面会丢失数据)使用params传值,如果想要里面的数据连接在url地址上,就使用:写一下
name: 'detail',
component: () =>
import ('../views/Detail')
}]
}
vuex的概念
概念:在Vue中实现集中式状态(数据)管理的一个Vue插件,对vue应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信
46.vuex中四个map方法的使用
引入:import { mapState,mapMutations,mapAction,mapGetters} from ‘vuex’
-
mapState方法:用于帮助我们映射
state
中的数据为计算属性computed: { //借助mapState生成计算属性:sum、school、subject(对象写法) ...mapState({sum:'sum',school:'school',subject:'subject'}), //借助mapState生成计算属性:sum、school、subject(数组写法) ...mapState(['sum','school','subject']), },
-
mapGetters方法:用于帮助我们映射
getters
中的数据为计算属性computed: { //借助mapGetters生成计算属性:bigSum(对象写法) ...mapGetters({bigSum:'bigSum'}), //借助mapGetters生成计算属性:bigSum(数组写法) ...mapGetters(['bigSum']) },
-
mapActions方法:用于帮助我们生成与
actions
对话的方法,即:包含$store.dispatch(xxx)
的函数methods:{ //靠mapActions生成:incrementOdd、incrementWait(对象形式) ...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'}) //靠mapActions生成:incrementOdd、incrementWait(数组形式) ...mapActions(['jiaOdd','jiaWait']) }
-
mapMutations方法:用于帮助我们生成与
mutations
对话的方法,即:包含$store.commit(xxx)
的函数methods:{ //靠mapActions生成:increment、decrement(对象形式) ...mapMutations({increment:'JIA',decrement:'JIAN'}), //靠mapMutations生成:JIA、JIAN(对象形式) ...mapMutations(['JIA','JIAN']), }
备注:mapActions与mapMutations使用时,若需要传递参数需要:在模板中绑定事件时传递好参数,否则参数是事件对象。
47.模块化+命名空间
-
目的:让代码更好维护,让多种数据分类更加明确。
-
修改
store.js
const countAbout = { namespaced:true,//开启命名空间 state:{x:1}, mutations: { ... }, actions: { ... }, getters: { bigSum(state){ return state.sum * 10 } } } const personAbout = { namespaced:true,//开启命名空间 state:{ ... }, mutations: { ... }, actions: { ... } } const store = new Vuex.Store({ modules: { countAbout, personAbout } })
-
开启命名空间后,组件中读取state数据:
//方式一:自己直接读取 this.$store.state.personAbout.list //方式二:借助mapState读取: ...mapState('countAbout',['sum','school','subject']),
-
开启命名空间后,组件中读取getters数据:
//方式一:自己直接读取 this.$store.getters['personAbout/firstPersonName'] //方式二:借助mapGetters读取: ...mapGetters('countAbout',['bigSum'])
-
开启命名空间后,组件中调用dispatch
//方式一:自己直接dispatch this.$store.dispatch('personAbout/addPersonWang',person) //方式二:借助mapActions: ...mapActions('countAbout',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
-
开启命名空间后,组件中调用commit
//方式一:自己直接commit this.$store.commit('personAbout/ADD_PERSON',person) //方式二:借助mapMutations: ...mapMutations('countAbout',{increment:'JIA',decrement:'JIAN'}),
48.store.js中四种对象的使用方法
1.state:{
count:0
}
2.mutations: {
add(state,step){
//第一个形参永远都是state也就是$state对象
//第二个形参是调用add时传递的参数
state.count+=step;
}
}
3.actions: {
addAsync(context,step){//context为store对象
setTimeout(()=>{
context.commit('add',step);
},2000)
}
}
4.getters:{
//添加了一个showNum的属性
showNum : state =>{
return '最新的count值为:'+state.count;
}
}
})
49.路由器的两种工作模式
1. 对于一个url来说,什么是hash值?—— #及其后面的内容就是hash值。
2. hash值不会包含在 HTTP 请求中,即:hash值不会带给服务器。
3. hash模式:(默认)想要更改为history要new VueRouter({mode: 'history' })
1. 地址中永远带着#号,不美观 。
2. 若以后将地址通过第三方手机app分享,若app校验严格,则地址会被标记为不合法。
3. 兼容性较好。
4. history模式:可以前进和后退,不能刷新
1. 地址干净,美观 。
2. 兼容性和hash模式相比略差。
3. 应用部署上线时需要后端人员支持,解决刷新页面服务端404的问题。(或者前端配置webpack
在devServer中存在historyApiFallback配置项,只需要将其设置成true就可以解决刷新404问题前端配置)
5.原理的区别
hash原理:hash通过监听浏览器的onhashchange()事件变化,查找对应的路由规则
history原理: 利用H5的 history中新增的两个API pushState() 和 replaceState() 和一个事件onpopstate监听URL变化
4、hash ——由于 hash 值变化不会导致浏览器向服务器发出请求,而且 hash 改变会触发 hashchange 事件(hashchange只能改变 # 后面的url片段);虽然hash路径出现在URL中,但是不会出现在HTTP请求中,对后端完全没有影响,因此改变hash值不会重新加载页面,基本都是使用 hash 来实现前端路由的。
5、history —— 利用了 HTML5 History Interface 中新增的 pushState() 和 replaceState() 方法。(需要特定浏览器支持)这两个方法应用于浏览器的历史记录栈,在当前已有的 back、forward、go 的基础之上,它们提供了对历史记录进行修改的功能。只是当它们执行修改时,虽然改变了当前的 URL,但浏览器不会立即向后端发送请求。还有最重要一点是history路由害怕刷新,因为切换路由后浏览器中url改变,再刷新的话会重新向服务器发送请求,所以后端需要做简单的配置
50.Storage的api(localStorage,sessionStorage)
1. xxxxxStorage.setItem('key', 'value');
该方法接受一个键和值作为参数,会把键值对添加到存储中,如果键名存在,则更新其对应的值。
2. xxxxxStorage.getItem('person');
该方法接受一个键名作为参数,返回键名对应的值。
3. xxxxxStorage.removeItem('key');
该方法接受一个键名作为参数,并把该键名从存储中删除。
4. xxxxxStorage.clear()
该方法会清空存储中的所有数据。
51.props的配置项(props可以是一个数组,也可以是一个对象)
1. 功能:让组件接收外部传过来的数据
2. 传递数据:<Demo :name="xxx"/>
3. 接收数据:
1. 第一种方式(只接收):props:['name']
2. 第二种方式(限制类型):props:{name:String}
3. 第三种方式(限制类型、限制必要性、指定默认值):
props:{
name:{
type:String, //类型
required:true, //必要性
default:'老王' //默认值
}
}
> 备注:props是只读的,Vue底层会监测你对props的修改,如果进行了修改,就会发出警告,若业务需求确实需要修改,那么请复制props的内容到data中一份,然后去修改data中的数据。
52. r o u t e r 与 router与 router与route
1.router为VueRouter的实例,相当于一个全局的路由器对象,里面含有很多属性和子对象,例如history对象。。经常用的跳转链接,就可以用this.$router.push,和router-link跳转一样
2.route 相当于当前正在跳转的路由对象。可以从里面获取name,path,params,query对象
53,vue.页面刷新 vuex 数据丢失 所以需要持久化
vuex-persist 插件
npm install vuex-persist -S下载
// 1.引入
import VuexPersistence from "vuex-persist"
// 2.添加配置项
const vuexLocal = new VuexPersistence({
storage: window.localStorage
})
export default new Vuex.Store({
//3.挂载
plugins: [vuexLocal.plugin],
})
54.name的作用
export default {
name:"erzi",
props:["msg"],
methods: {
handle(){
this.$emit("send",1234);
}
},
}
1.递归自身组件
2.辅助keepalive
3.方便调试使用 vuedevtool中查看
4.指定组件名称 vant element
https://blog.csdn.net/weixin_45811256/article/details/109498407
55.动态标题,给组件取名字
1.vue-wechat-title 插件 mian.js中注册 home bus页面 根元素中添加了 v-wechat-title="xxxx"
https://blog.csdn.net/m0_61672533/article/details/126194995
2. 路由定义 meta信息
全局路由守卫 设置document.title = to.meta.xxxx
56.在vuex中如何给state中的对象,添加响应式的属性
mutations: {
tianjia(state, item) {
//第一个形参永远都是state也就是$state对象
Vue.set(item, 'num', 1);//item之前是没有num这个属性的
Vue.set(item, 'flag', false) //可以响应式的给对象添加属性
// item.flag = false,不能响应式的给对象添加属性
state.goodlist.push(item);
},
57. computed中的数据是不能直接更改的,没有setter函数,会报错。如何给computed添加setter函数
computed: {
...mapState(["goodlist"]),
flag: {
set(isCheked){//isChecked是当前给flag赋的值
console.log(this.goodlist);
this.goodlist.forEach(el=>{
el.flag = isCheked;
})
},
get()
return this.goodlist.every(el=>el.flag==true)
}
},
58.多选框的选中与取消,用v-model是双向的赋值,用checked是单向的
<input style="margin:30px 30px" type="checkbox" name="" id="" v-model="flag">
//此时flag为true则为选中,为false为不选中。当点击该多选框的时候,也会更改flag的数据
59.重写VueRouter的push和replace方法
在router.js的文件中写入这些代码
// 重新push方法
let originalPush = VueRouter.prototype.push;
let originalReplace = VueRouter.prototype.replace;
// 第一个参数: 告诉原来push方法,你往哪里跳
VueRouter.prototype.push = function push(location) {
return originalPush.call(this, location).catch(err => err)
}
VueRouter.prototype.replace = function push(location) {
return originalReplace.call(this, location).catch(err => err)
}
60.bus总线传值
main.js中
var bus=new Vue;
Vue.prototype.$bus = bus;
A.
mounted() {
this.$bus.$on("send", (res) => {
this.msg = res;
})
B.
methods: {
handle(){
this.$bus.$emit("send",123);
}
},
61.监听路由的变化,触发相应的函数
许多时候,仅仅用mounted,和created周期函数,来做一些首次渲染页面调用相应的函数,是远远不够的。因为comunted和rreated只触发一次(只是在渲染这个页面的时候触发一次,当仅是url的参数变的时候是不会在触发),当仅仅是url的参数发生改变,是不会触发的
watch:{
$route:{//监听路由的变化,此时正在跳转的路由url的参数发生变化,也会触发改函数
deep:true,
immediate:true,//首次渲染的时候就执行,无需数据发生变化,此时newn和oldn为初始值和undefineds
handler(newn,oldn){
this.getlist();
this.getcontentlist()
}
}
}
62.git的使用
1.创建一个仓库,并将项目托管到该仓库
首先在该项目所在路径下打开终端执行以下命令
① git init
② git remote add origin https://gitee.com/tan-xiaocui/test.git(仓库的地址)
③ git push -u origin "master"
2.克隆
右键点击git bash here,执行以下命令
git clone xxx(项目仓库的https地址)
出现 一个项目文件夹
3.创键一个新的分支
git checkout -b login //创建一个新分支,并切换到该分支上(一般在master分支下执行)
git add .
git commit -m "登录"
git pull 同步,拖拽
git push -u origin login//第一次将新分支,上传到云端
git checkout master
git merge login //将login分支,合并到master中(在master分支中运行)
git push //将新master上传到云端
git status 状态
4.clone出来地项目文件夹,云端上有所有分支,但在该文件夹终端中执行git branch只有一个master分支,意思是本地工作区只有一个master分支,若想从远程仓库克隆到本地 将分支也配置到本地的命令
创建本地分支并与远程分支关联
git checkout -b dev origin/dev
//--------------------------------------------------------------------------------------------------------
把本地仓库 推送到远程
把远程项目 clone到本地
日常操作
git clone xxx
git add .
git commit -m xxx
git pull
git push
//解决冲突!!!,当不同人修改同一个文件,则会出现冲突问题,需要删除出现地冲突乱码
分支 分支的合并
把本地创建的dev分支 上传了远程仓库 在dev分支下面执行
git push --set-upstream origin dev
git diff //查看上次提交
git branch //查看分支
git status //查看状态,是否干净
63.如何封装axios,之后可以直接点用函数使用
1.在api文件夹里创建request.js文件和index.js文件
在request文件里写入
import axios from 'axios';
// 创建一个自定义的Axios对象
const Axios = axios.create({
baseURL: 'http://127.0.0.1:1234',
timeout: 3000,
/*也可以不设置Content-Type,影响是在你发送请求时
Vue会先发送OPTIONS包探测路由是否存在,需要后端也做设置响应OPTIONS
方法,否则会报跨域错误;我这里用的Beego2,路由里不响应OPTIONS方法,
所以我在这块设置Content-Type*/
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
/*这个配置很重要,允许axios携带用户Cookie到后端,不设置这个的话
Set-Cookie是无效的,除此之外,Chrome默认开启了SameSite检查,如果
后端不主动设置SameSite = none,Set-Cookie是无效的。详情请文章末尾
参考阮老师的SameSite讲解*/
withCredentials: true
});
Axios.interceptors.request.use(req => {
// 请求拦截处理
// console.log('这里是请求拦截器,我拦截了请求', req);
return req;
}, err => {
console.log('在发送请求时发生错误,错误为', err);
//这里不能直接放回err,需要按照官方说明返回一个Promise
return Promise.reject(err);
})
Axios.interceptors.response.use(res => {
// 响应拦截处理
// console.log('响应拦截 ', res);
return res.data;
}, error => {
const err = error.toString();
//按照实际的响应包进行解析,通过关键字匹配的方式
switch (true) {
case err.indexOf('Network') !== -1:
console.log('后端服务器无响应或者URL错误', err);
break;
case err.indexOf('timeout') !== -1:
console.log('请求后端服务器超时!', err);
break;
}
return Promise.reject(error);
})
//暴露Axios实例化对象,允许所有文件调用Axios
export default Axios;
2.在index.js文件中写入
import axios from "./request";
export let reqGetData = (props) => axios.get('')
export let reqGetlist = (props) => axios.get('')
//使用的时候解构赋值
3.在.vue组件中按需引入直接调用函数
import { reqGetData} from '../index.js'
mounted(){
var data= reqGetData(xx);
}
写入
import axios from ‘axios’;
// 创建一个自定义的Axios对象
const Axios = axios.create({
baseURL: ‘http://127.0.0.1:1234’,
timeout: 3000,
/也可以不设置Content-Type,影响是在你发送请求时
Vue会先发送OPTIONS包探测路由是否存在,需要后端也做设置响应OPTIONS
方法,否则会报跨域错误;我这里用的Beego2,路由里不响应OPTIONS方法,
所以我在这块设置Content-Type/
headers: {
‘Content-Type’: ‘application/x-www-form-urlencoded’
},
/这个配置很重要,允许axios携带用户Cookie到后端,不设置这个的话
Set-Cookie是无效的,除此之外,Chrome默认开启了SameSite检查,如果
后端不主动设置SameSite = none,Set-Cookie是无效的。详情请文章末尾
参考阮老师的SameSite讲解/
withCredentials: true
});
Axios.interceptors.request.use(req => {
// 请求拦截处理
// console.log(‘这里是请求拦截器,我拦截了请求’, req);
return req;
}, err => {
console.log(‘在发送请求时发生错误,错误为’, err);
//这里不能直接放回err,需要按照官方说明返回一个Promise
return Promise.reject(err);
})
Axios.interceptors.response.use(res => {
// 响应拦截处理
// console.log('响应拦截 ', res);
return res.data;
}, error => {
const err = error.toString();
//按照实际的响应包进行解析,通过关键字匹配的方式
switch (true) {
case err.indexOf(‘Network’) !== -1:
console.log(‘后端服务器无响应或者URL错误’, err);
break;
case err.indexOf(‘timeout’) !== -1:
console.log(‘请求后端服务器超时!’, err);
break;
}
return Promise.reject(error);
})
//暴露Axios实例化对象,允许所有文件调用Axios
export default Axios;
2.在index.js文件中写入
import axios from “./request”;
export let reqGetData = (props) => axios.get(‘’)
export let reqGetlist = (props) => axios.get(‘’)
//使用的时候解构赋值
3.在.vue组件中按需引入直接调用函数
import { reqGetData} from ‘…/index.js’
mounted(){
var data= reqGetData(xx);
}