day41((VueJS)组件实例方法--7个方法 网络请求的导入导出方式 axios库进行网络请求以及封装)

一.组件实例方法(7个方法)

1. $refs
  1) 功能
    1> 添加在标签上, 用来获取 dom 节点
    2> 添加在子组件上, 用来获取子组件的实例, 进而可以调用子组件内部的方法, 使用子组件内部的数据
    
2. $el
  1) 功能
    1> 获取组件的最外层 dom 节点(根标签)
    
3. $parent
  1) 功能
    1> 获取当前组件的父组件实例(即上一层组件,每个组件获取结果的不一定相同),如果调用该方法的组件没有父组件,就返回 null
    
4. $forceUpate
  1) 功能
    1> 强制更新组件
    
5. $root
  1) 功能
    1> 获取当前项目根组件,一般是App.vue,每个项目只有一个,在该项目中的.vue任何文件中都可以使用该方法获取根组件
    
6. $data
  1) 功能
    1> 获取通过 data 选项 return 的对象
    
7. $nextTick
  1) 功能
    1> 将指定的代码延迟执行,等到下一次事件循环到在执行(官方说法)。下一次事件循环
       到意味着组件挂载完毕或者组件的更新之后
  2) 要点(重点-------------1> 通常我们在 beforeCreate()这个钩子函数中访问 dom 节点时,会显示 undefined,因  
       为此时组件还没挂载完成,dom 节点没有渲染。但是如果有特别的需求,需要在这个函
       数中访问到 dom 节点时,可以使用 this.$nextTick(回调函数),这个方法可以使其
       回调函数中的代码延迟直到下一次事件循环到在执行,而此时 dom 节点已经渲染完毕,
       就可以访问得到

代码解析

<template>
  <div class="app">
    将ref 添加在标签上, 用来获取dom节点
    <input ref="inputbox" type="text" placeholder="搜索商品">
    将ref 添加在子组件上, 用来获取子组件的实例, 进而可以调用子组件内部的方法, 使用子组件内部的数据
    <child ref="childcom" />

  </div>
</template>

<script>
导入组件
import child from './components/child.vue'
export default {
注册局部组件
  components:{
    child
  },
  beforeCreate(){-------在这个方法中 正常是无法访问dom节点的( 原因是 执行这个方法时dom节点还未挂载 )
    console.log( this.$refs.inputbox );---------------------显示undefined
    this.$nextTick(()=>{
      console.log('nextTick', this.$refs.inputbox );----------------回调函数中的代码会等到下一次事件循环到时才执行
    })
  },
  mounted(){
    console.log( this, this.$refs.childcom, this.$refs.childcom.title );-------访问当前组件,组件中添加ref属性的子节点,访问子节点中的属性title
    console.log( this.$el );----------------------获取组件的最外层dom节点
    console.log( this.$refs.childcom.$el );
    console.log( this.$refs.childcom.$root );-------------获取当前项目根组件实例  ( 最外层的App组件的实例 )
    console.log( this.$parent );-------------------------获取当前组件父组件实例
    console.log( this.$refs.childcom.$parent );-------------------------获取当前组件子组件的父组件实例
    console.log( this.$refs.childcom.$parent == this );--当前组件子组件的父组件实例就还是当前组件
  }
}
</script>

二.网络请求

默认导入与默认导出:::
1.概念要点
	1) 特点
	  1> 默认导出只能导出一个对象,且默认导出只能写一次,多写会报错;
	  2> 默认导出对应的导入方式只能是默认导出,搭配错了也会报错
	2) 好处:默认导出对应的导入默认导入可以修改导入的对象名
2.代码解析
	语法:
	默认导出:
	    export default 对象;
	默认导入:
	    import 可任意修改的对象名 from '目标文件路径';-----------导入导出都只有一个对象
	ps:
	    如果一个文件夹下的js文件名叫index.js,那么在导入时可以省略路径中的index.js文件名,系统会自动导入
命名导入与命名导出:::
1.概念要点
	1) 特点
	  1> 命名导出可以多次书写,导出多个对象
	  2> 命名导出对应的导入方法只能是命名导入,对应错了会报错
	  3> 命名导入在导入时不能改名,因为导入的很可能不止一个对象
	  4> 命名导入在需要导入的对象数量特别多时,可以使用集中导入,将所有命名导出的对象统一导入到一个自定义对象中,然后在导入的文件中使用自定义对象打点访问导入的对象方法
2.代码解析
	语法:
		导出:
		    export 对象;
		    export 对象;
		    ......
		导入:
		    export {对象1,对象2,对象3,.....} from '目标文件路径';
		当需要导入的对象数量太多,书写繁琐时,可以选择使用集中导入:
		    export * as 自定义对象名 from '目标文件路径';

ajax封装(重点--------------)

封装函数文件.js
封装一个用于发送ajax请求的方法

export function service(url,method,data){
    return new Promise((resolve,reject)=>{
        1.实例化ajax对象
        var xhr = new XMLHttpRequest();
        2.配置请求信息
        xhr.open(method, method.toLowerCase() == 'get' ? url + "?" + dataToUrl(data) : url );-------判断请求方式是否为post,决定是否在url结尾拼接携带的参数
        3.设置回调函数( 事件 )
        xhr.onreadystatechange = ()=>{
            if( xhr.readyState == 4 ){
                resolve(xhr.responseText)
            }
        }
        if( method.toLowerCase() == 'post' ){-------------此处使用条件判断请求方法是否为post,如果是,则在此处添加请求头
            xhr.setRequestHeader('content-type','application/json');
        }
        4.发送请求
        xhr.send(method.toLowerCase() == 'post' ? dataToUrl(data) : '');--------此处使用三目运算判断请求方式是否是post,如果请求方式不是post,则此处参数为空,如果请求参数是post此处参数就是由自定义函数处理拼接成的key=value&key=value式的字符串
    })
}

function dataToUrl(data){---------此处封装函数将携带的参数拼接成key=value&key=value形式的字符串,在需要时传给send方法作为参数
    var str = ''
    for( var key in data  ){
        str += `${key}=${data[key]}&`;
    }
    return str.slice(0,str.length-1);
}

在调用service方法发送ajax请求时, 为了避免回调地狱问题, 可以使用await,async来处理
var d = await service('','get',{});-------------使用await修饰返回promise对象的函数,可以使该函数直接返回promise对象fullfilled状态时存储在PromiseResult属性中的值,一般也就是我们需要的响应值
var d = await service('','get',{d});
var d = await service('','get',{d});

在使用匿名函数或者箭头函数的情况下可以使用then方法,但是此处的封装函数是个具名函数,如果作为then方法的回调函数,就需要传入一个实参,写法较为复杂,且依然要用到await,所以不推荐。
async function don(){
        let d = 0;
        await fun().then((i)=>d = i+1);
        console.log(d)
        await fon(d).then((i)=>d = i+1);
        console.log(d)
        await fon(d).then((i)=>d = i+1)
        console.log(d)
        await fon(d).then((i)=>console.log(i));
    }
don()

二次封装文件.js
简化写法(如果有相同的参数可以进行二次封装,使原本的ajax封装函数只接受一个参数,类似于柯理化)
使用封装过的方法 发请求
import { service } from "../utils/request";

一个请求封装一个函数, 如果请求地址中没有指定服务器地址,默认会发到本机内置的服务器,而本机没有这个接口则会报错404.
export function userlist( payload = {} ){----------此处赋值空对象可以避免在实参为空时出现问题
    return service('/api/userlist','get', payload );---------------在此处将前两个参数写定,第三个参数保持形参,然后将该函数返回,同时外部函数改成接受一个参数,可以在前两个参数重复的调用场景中减少代码量,只需要传一个参数,重复的参数不用写
}
export function useradd( payload = {} ){
    return service('/api/useradd','post', payload );
}

应用文档.vue
<script>
import * as service from './api'

export default {
    async mounted(){----------发请求一般在挂载完成时的钩子函数中
        var res = await service('/api/userlist','get',{});
        var res = await userlist();
        var res = await service.userlist();
        发第二个请求
        var res = await service('/api/useradd','post',{ name:'张三',age:30 });----------如果没有进行减少参数的二次封装,每调用一次,重复的前两个两个参数就需要写一次,会造成代码冗余
        var res = await useradd( { name:'张三',age:30 } );
        var res = await service.useradd( { name:'张三',age:30 } );------进行二次封装之后,每次调用只需要传入不重复第三个的参数即可,前两个参数在封装是已经写好
        ...
    }
}
</script>

使用axios库进行网络请求

1.要点
	步骤:
	1) 下载 axios 库第三方插件:npm i axios
	2) 在公用文档的文件夹 utils 中创建request.js文件,在该文件中引入 axios 库并将其实例化,使用 create 方法为其添加配置对象,配置对象中包含基准路径baseURL和超时时间timeout
	3) 在设置 api 的文件夹中创建index.js文件,从添加配置对象的request.js文件中引入 axios 实例化对象,然后在这里进行一定条件下的二次封装,将多次重复的参数提前写定,不重复的参数使用外部函数接收。
	4) 在应用文档中引入二次封装文件index.js,从其中调用提前二次封装好的函数
	
2.发请求的不同形式
	发请求的方式一:
	    var res = await service({------------以json对象的形式传入参数
	      url:'/api/userlist',
	      method:'get',
	      params:{  }
	    })
	
	发请求的方式二( 以 restful style 方式 ):请求大体分为get,post,put,patch,dalete五类
	    var res = await service.get('http://180.76.99.14/api/index/catelist', { 
	      headers:{ token:'sdfkl2232k3kdekdk23kh232' }, ----------------axios库实例调用get方法时,接受两个参数,第一个参数是url,第二个参数是一个对象,里面可以写headers:{token:"请求头字符串"}和params:{这里写携带的参数key:value,...}
	      params: {} 
	    } );
	    
	    var res = await service.post('/api/userlist4', {} , { 
	      headers: { token:'sdfkl2232k3kdekdk23kh232' } 
	    } );
	    var res = await service.put('/api/userlist5', {} , { 
	      headers: { token:'sdfkl2232k3kdekdk23kh232' } 
	    } );
	    var res = await service.patch('/api/userlist6', {} , { 
	      headers: { token:'sdfkl2232k3kdekdk23kh232' } 
	    } );
	
	    var res = await service.delete('/api/userlist7', { id: 1001 } , { 
	      headers: { token:'sdfkl2232k3kdekdk23kh232' } 
	    } );
	    
3.方法总结
	axios实例方法:
	发送请求类:
	1.axios实例.get("url",{
	    headers:{token:"字符串"},--------------请求头
	    params:{key:value,key:value,....}-------携带参数
	    })
	2.axios实例.post("url",{携带参数},{headers:{请求头}})
	3.axios实例.put("url",{携带参数},{headers:{请求头}})
	4.axios实例.patch("url",{携带参数},{headers:{请求头}})
	5.axios实例.delete("url",{携带参数},{headers:{请求头}})
	实例化并添加配置对象:
	axios.create({
	    timeout:毫秒单位的时间,----------超时时间
	    baseURL:"多次重复的需要自动拼接的url前缀"----------请求基准路径,在每次使用该实例发请求时, 在请求地址的前面都会自动拼接该基准路径
	    })
	设置拦截器:
	axios实例.interceptors.request.use(-------请求拦截器
	    (config)=>{
	        请求成功时执行这里的给定操作
	        return config;返回config是固定语法,删掉会报错
	    },
	    (error)=>{
	        请求失败时执行这里的给定操作
	        return Promise.reject(error);也是固定语法
	    }
	)
	
	axios实例.interceptors.response.use(---响应拦截器
	    (response)=>{
	    响应成功时触发该回调函数,在这里进行一些操作,添加提示信息等
	        return response;返回response是固定语法,删掉会报错
	    },
	    (error)=>{
	     响应出现错误时触发该回调函数,在这里添加一些操作,比如根据不同的状态码设定不同的提示信息等  
	        return Promise.reject(error);固定语法
	    }
	)
	
4.代码分析
	在设置请求的js文件中将axios实例化,然后为其添加请求拦截器与请求头等:request.js,存放于utils文件夹
	import axios from 'axios'
	
	创建axios实例
	var service = axios.create({-----------调用create方法,花括号里面的内容叫做axios实例的配置对象
	    timeout:10 * 1000,-----------------------超时时间
	    baseURL:'/' ,-----------------请求基准路径( 在每次使用该实例发请求时, 在请求地址的前面都会自动拼接该基准路径 )
	})
	
	设置请求拦截器 ( 每次从客户端发送请求到服务器前执行 )
	service.interceptors.request.use(
	    (config)=>{--------------此处书写请求成功时执行的代码
	        在这里自定义请求头( 添加新的请求头参数 )
	        config.headers.token = '1j231jj2lk5l0zssuu8sdd7cxjw32jasj234l2352kj3b42j3bjhddgfsefj23rh23bjsdjfkashfa';
	        或(上下两种写法都可,二选一)
	        config.headers['token'] = '1j231jj2lk5l0zssuu8sdd7cxjw32jasj234l2352kj3b42j3bjhddgfsefj23rh23bjsdjfkashfa';
	        return config;
	    },
	    (error)=>{
	        return Promise.reject( error )
	    }
	)
	
	设置响应拦截器 ( 每次从服务器响应返回到客户端前执行 )
	service.interceptors.response.use(
	    (res)=>{----------响应成功时触发该回调函数
	        return res;
	    },
	    (error)=>{------------响应出现错误时触发该回调函数
	        if( error.response.status == 401 ){------------使用error.response.status获取错误的状态码,根据不同的状态码设置不同的提示信息
	            alert('登陆过期,请重新登录');
	        }else if( error.response.status == 404 ){
	            alert('访问路径有误!');
	        }else if( error.response.status == 500 ){
	            alert('服务器内部错误!');
	        }else if( error.response.status == 503 ){
	            alert('服务器不可用!');
	        }
	        Promise.reject( error )
	    }
	)
	
	最后需要在这里导出实例,以便后续在需要的文件中导入使用
	export default service;
	
	
	二次封装函数的文件:index.js,存放于API文件夹
	
	import service from "../utils/request";-----------注意此处引入的是在request.js文件中添加过基准路径和拦截器的axios对象,不是直接将新的axios对象引入,如果引入新的对象,那么在request中设置的内容就不起作用了,可能会出现没有请求头或者不提示等问题
	
	一个请求封装成一个函数,根据不同的请求,将互相重复的url和请求方式写定,然后用外层函数封装,方便调用时减少代码冗余
	export function catelist( payload = {} ){-------每封装一个函数使用命名导出进行抛出,方便应用文档导入调用
	    return service.get('http://180.76.99.14/api/index/catelist',{ params: payload })
	    return service.get('/api/index/catelist2',{ params: payload })-------------如果在基准路径中设置了重复地址部分自动拼接,此处就可以将重复部分省去。没有设置基准路径的时候还是需要写完整的,不然默认访问本地服务器,就会报错
	}
	export function userlist( payload = {} ){
	    return service.post('http://180.76.99.14/api/user/login',  payload  )
	}
	
	请求函数应用文档:xxx.vue
	<script>
	命名导入
	import { userlist,catelist } from './api'
	集中导入(上下两种导入方式二选一即可)
	import * as service from './api'----------------一般是导入二次封装函数的js文件,不是直接导入axios,也不是导入添加请求头和拦截器的文档
	export default {
	  async mounted(){-----------使用await修饰请求函数使之按照同步代码顺序执行,那么钩子函数mounted外部就需要添加async,这两个关键字是搭配使用的
	发请求
	    var res = await catelist( );--------------如果是使用命名导入,可以直接调用该封装函数
	    或
	    var res = await service.catelist(  );----------如果是集中导入,需要使用对象打点调用
	    console.log(res.data);
	  }
	}
	</script>
  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值