当前位置: 首页 > news >正文

Vue中Axios的封装和API接口的管理

一、axios的封装

在vue项目中,和后台交互获取数据这块,我们通常使用的是axios库,它是基于promise的http库,可运行在浏览器端和node.js中。他有很多优秀的特性,例如拦截请求和响应、取消请求、转换json、客户端防御XSRF等。所以我们的尤大大也是果断放弃了对其官方库vue-resource的维护,直接推荐我们使用axios库。如果还对axios不了解的,可以移步axios文档。

安装

npm install axios; // 安装axios

引入

一般我会在项目的src目录中,新建一个request文件夹,然后在里面新建一个http.js和一个api.js文件。http.js文件用来封装我们的axios,api.js用来统一管理我们的接口。

// 在http.js中引入axios
import axios from 'axios'; // 引入axios
import QS from 'qs'; // 引入qs模块,用来序列化post类型的数据,后面会提到
// vant的toast提示框组件,大家可根据自己的ui组件更改。
import { Toast } from 'vant'; 

环境的切换

我们的项目环境可能有开发环境、测试环境和生产环境。我们通过node的环境变量来匹配我们的默认的接口url前缀。axios.defaults.baseURL可以设置axios的默认请求地址就不多说了。

// 环境的切换
if (process.env.NODE_ENV == 'development') {    axios.defaults.baseURL = 'https://www.baidu.com';} 
else if (process.env.NODE_ENV == 'debug') {    axios.defaults.baseURL = 'https://www.ceshi.com';
} 
else if (process.env.NODE_ENV == 'production') {    axios.defaults.baseURL = 'https://www.production.com';
}

设置请求超时

通过axios.defaults.timeout设置默认的请求超时时间。例如超过了10s,就会告知用户当前请求超时,请刷新等。

axios.defaults.timeout = 10000;

post请求头的设置

post请求的时候,我们需要加上一个请求头,所以可以在这里进行一个默认的设置,即设置post的请求头为application/x-www-form-urlencoded;charset=UTF-8

axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';

  • 请求拦截

我们在发送请求前可以进行一个请求的拦截,为什么要拦截呢,我们拦截请求是用来做什么的呢?比如,有些请求是需要用户登录之后才能访问的,或者post请求的时候,我们需要序列化我们提交的数据。这时候,我们可以在请求被发送之前进行一个拦截,从而进行我们想要的操作。

请求拦截

// 先导入vuex,因为我们要使用到里面的状态对象
// vuex的路径根据自己的路径去写
import store from '@/store/index';// 请求拦截器axios.interceptors.request.use(    config => {        // 每次发送请求之前判断vuex中是否存在token        // 如果存在,则统一在http请求的header都加上token,这样后台根据token判断你的登录情况// 即使本地存在token,也有可能token是过期的,所以在响应拦截器中要对返回状态进行判断 const token = store.state.token;        token && (config.headers.Authorization = token);        return config;    },    error => {        return Promise.error(error);    
})

这里说一下token,一般是在登录完成之后,将用户的token通过localStorage或者cookie存在本地,然后用户每次在进入页面的时候(即在main.js中),会首先从本地存储中读取token,如果token存在说明用户已经登陆过,则更新vuex中的token状态。然后,在每次请求接口的时候,都会在请求的header中携带token,后台人员就可以根据你携带的token来判断你的登录是否过期,如果没有携带,则说明没有登录过。这时候或许有些小伙伴会有疑问了,就是每个请求都携带token,那么要是一个页面不需要用户登录就可以访问的怎么办呢?其实,你前端的请求可以携带token,但是后台可以选择不接收啊!

响应的拦截

// 响应拦截器
axios.interceptors.response.use(    response => {   // 如果返回的状态码为200,说明接口请求成功,可以正常拿到数据     // 否则的话抛出错误if (response.status === 200) {            return Promise.resolve(response);        } else {            return Promise.reject(response);        }    },    // 服务器状态码不是2开头的的情况// 这里可以跟你们的后台开发人员协商好统一的错误状态码    // 然后根据返回的状态码进行一些操作,例如登录过期提示,错误提示等等// 下面列举几个常见的操作,其他需求可自行扩展error => {            if (error.response.status) {            switch (error.response.status) {                // 401: 未登录// 未登录则跳转登录页面,并携带当前页面的路径// 在登录成功后返回当前页面,这一步需要在登录页操作。                case 401:                    router.replace({                        path: '/login',                        query: { redirect: router.currentRoute.fullPath }});break;// 403 token过期// 登录过期对用户进行提示// 清除本地token和清空vuex中token对象// 跳转登录页面                case 403:Toast({message: '登录过期,请重新登录',duration: 1000,forbidClick: true});// 清除tokenlocalStorage.removeItem('token');store.commit('loginSuccess', null);// 跳转登录页面,并将要浏览的页面fullPath传过去,登录成功后跳转需要访问的页面 setTimeout(() => {                        router.replace({                            path: '/login',                            query: { redirect: router.currentRoute.fullPath }                        });                    }, 1000);                    break; // 404请求不存在case 404:Toast({message: '网络请求不存在',duration: 1500,forbidClick: true});break;// 其他错误,直接抛出错误提示default:Toast({message: error.response.data.message,duration: 1500,forbidClick: true});}return Promise.reject(error.response);}}    
});

响应拦截器很好理解,就是返回给我们的数据,我们在拿到之前可以对他进行一些处理。例如上面的思想:如果后台返回的状态码是200,则正常返回数据,否则的根据错误的状态码类型进行一些我们需要的错误,其实这里主要就是进行了错误的统一处理和没登录或登录过期后调整登录页的一个操作。

要注意的是,上面的Toast()方法,是我引入的vant库中的toast轻提示组件,你根据你的ui库,对应使用你的一个提示组件。

封装get方法和post方法

我们常用的ajax请求方法有get、post、put等方法,相信小伙伴都不会陌生。axios对应的也有很多类似的方法,不清楚的可以看下文档。但是为了简化我们的代码,我们还是要对其进行一个简单的封装。下面我们主要封装两个方法:get和post。

get方法:我们通过定义一个get函数,get函数有两个参数,第一个参数表示我们要请求的url地址,第二个参数是我们要携带的请求参数。get函数返回一个promise对象,当axios其请求成功时resolve服务器返回 值,请求失败时reject错误值。最后通过export抛出get函数。

/*** get方法,对应get请求* @param {String} url [请求的url地址]* @param {Object} params [请求时携带的参数]*/
export function get(url, params){    return new Promise((resolve, reject) =>{        axios.get(url, {            params: params        }).then(res => {resolve(res.data);}).catch(err =>{reject(err.data)        })    
});}

**post方法:**原理同get基本一样,但是要注意的是,post方法必须要使用对提交从参数对象进行序列化的操作,所以这里我们通过node的qs模块来序列化我们的参数。这个很重要,如果没有序列化操作,后台是拿不到你提交的数据的。这就是文章开头我们import QS from 'qs';的原因。如果不明白序列化是什么意思的,就百度一下吧,答案一大堆。

/** * post方法,对应post请求 * @param {String} url [请求的url地址] * @param {Object} params [请求时携带的参数] */
export function post(url, params) {return new Promise((resolve, reject) => {axios.post(url, QS.stringify(params)).then(res => {resolve(res.data);}).catch(err =>{reject(err.data)})});
}

这里有个小细节说下,axios.get()方法和axios.post()在提交数据时参数的书写方式还是有区别的。区别就是,get的第二个参数是一个{},然后这个对象的params属性值是一个参数对象的。而post的第二个参数就是一个参数对象。两者略微的区别要留意哦!

axios的封装基本就完成了,下面再简单说下api的统一管理。

整齐的api就像电路板一样,即使再复杂也能很清晰整个线路。上面说了,我们会新建一个api.js,然后在这个文件中存放我们所有的api接口。

  • 首先我们在api.js中引入我们封装的get和post方法
/**   * api接口统一管理*/
import { get, post } from './http'

现在,例如我们有这样一个接口,是一个post请求:

http://www.baiodu.com/api/v1/users/my_address/address_edit_before

我们可以在api.js中这样封装:

export const apiAddress = p => post('api/v1/users/my_address/address_edit_before', p);

我们定义了一个apiAddress方法,这个方法有一个参数p,p是我们请求接口时携带的参数对象。而后调用了我们封装的post方法,post方法的第一个参数是我们的接口地址,第二个参数是apiAddress的p参数,即请求接口时携带的参数对象。最后通过export导出apiAddress

然后在我们的页面中可以这样调用我们的api接口:

import { apiAddress } from '@/request/api';// 导入我们的api接口
export default {        name: 'Address',    created () {this.onLoad();},methods: {            // 获取数据            onLoad() {// 调用api接口,并且提供了两个参数                apiAddress({                    type: 0,                    sort: 1                }).then(res => {// 获取数据成功后的其他操作………………                })            }        }
}

其他的api接口,就在pai.js中继续往下面扩展就可以了。友情提示,为每个接口写好注释哦!!!

api接口管理的一个好处就是,我们把api统一集中起来,如果后期需要修改接口,我们就直接在api.js中找到对应的修改就好了,而不用去每一个页面查找我们的接口然后再修改会很麻烦。关键是,万一修改的量比较大,就规格gg了。还有就是如果直接在我们的业务代码修改接口,一不小心还容易动到我们的业务代码造成不必要的麻烦。

好了,最后把完成的axios封装代码奉上。

/**axios封装* 请求拦截、相应拦截、错误统一处理*/
import axios from 'axios';import QS from 'qs';
import { Toast } from 'vant';
import store from '../store/index'// 环境的切换
if (process.env.NODE_ENV == 'development') {    axios.defaults.baseURL = '/api';
} else if (process.env.NODE_ENV == 'debug') {    axios.defaults.baseURL = '';
} else if (process.env.NODE_ENV == 'production') {    axios.defaults.baseURL = 'http://api.123dailu.com/';
}// 请求超时时间
axios.defaults.timeout = 10000;// post请求头
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';// 请求拦截器
axios.interceptors.request.use(    config => {// 每次发送请求之前判断是否存在token,如果存在,则统一在http请求的header都加上token,不用每次请求都手动添加了// 即使本地存在token,也有可能token是过期的,所以在响应拦截器中要对返回状态进行判断const token = store.state.token;        token && (config.headers.Authorization = token);        return config;    },    error => {        return Promise.error(error);    })// 响应拦截器
axios.interceptors.response.use(    response => {        if (response.status === 200) {            return Promise.resolve(response);        } else {            return Promise.reject(response);        }    },// 服务器状态码不是200的情况    error => {        if (error.response.status) {            switch (error.response.status) {                // 401: 未登录                // 未登录则跳转登录页面,并携带当前页面的路径                // 在登录成功后返回当前页面,这一步需要在登录页操作。                case 401:                    router.replace({                        path: '/login',                        query: { redirect: router.currentRoute.fullPath } });break;// 403 token过期                // 登录过期对用户进行提示                // 清除本地token和清空vuex中token对象                // 跳转登录页面                case 403:                     Toast({                        message: '登录过期,请重新登录',                        duration: 1000,                        forbidClick: true                    });                    // 清除token                    localStorage.removeItem('token');                    store.commit('loginSuccess', null);                    // 跳转登录页面,并将要浏览的页面fullPath传过去,登录成功后跳转需要访问的页面setTimeout(() => {                        router.replace({                            path: '/login',                            query: { redirect: router.currentRoute.fullPath }                        });                    }, 1000);                    break; // 404请求不存在                case 404:                    Toast({                        message: '网络请求不存在',                        duration: 1500,                        forbidClick: true                    });                    break;                // 其他错误,直接抛出错误提示                default:                    Toast({                        message: error.response.data.message,                        duration: 1500,                        forbidClick: true                    });            }            return Promise.reject(error.response);        }       }
);
/** * get方法,对应get请求 * @param {String} url [请求的url地址] * @param {Object} params [请求时携带的参数] */
export function get(url, params){    return new Promise((resolve, reject) =>{        axios.get(url, {            params: params        })        .then(res => {            resolve(res.data);        })        .catch(err => {            reject(err.data)        })    });
}
/** * post方法,对应post请求 * @param {String} url [请求的url地址] * @param {Object} params [请求时携带的参数] */
export function post(url, params) {    return new Promise((resolve, reject) => {         axios.post(url, QS.stringify(params))        .then(res => {            resolve(res.data);        })        .catch(err => {            reject(err.data)        })    });
}

这个axios和之前的大同小异,做了如下几点改变:

1.去掉了之前get和post方法的封装,通过创建一个axios实例然后export default方法导出,这样使用起来更灵活一些。

2.去掉了通过环境变量控制baseUrl的值。考虑到接口会有多个不同域名的情况,所以准备通过js变量来控制接口域名。这点具体在api里会介绍。

3.增加了请求超时,即断网状态的处理。说下思路,当断网时,通过更新vuex中network的状态来控制断网提示组件的显示隐藏。断网提示一般会有重新加载数据的操作,这步会在后面对应的地方介绍。

4.公用函数进行抽出,简化代码,尽量保证单一职责原则。

下面说下api这块,考虑到一下需求:

1.更加模块化

2.更方便多人开发,有效减少解决命名冲突

3.处理接口域名有多个情况

这里这里呢新建了一个api文件夹,里面有一个index.js和一个base.js,以及多个根据模块划分的接口js文件。index.js是一个api的出口,base.js管理接口域名,其他js则用来管理各个模块的接口。

先放index.js代码:

/** * api接口的统一出口*/
// 文章模块接口
import article from '@/api/article';
// 其他模块的接口……// 导出接口
export default {    article,// ……
}

index.js是一个api接口的出口,这样就可以把api接口根据功能划分为多个模块,利于多人协作开发,比如一个人只负责一个模块的开发等,还能方便每个模块中接口的命名哦。

base.js:

/*** 接口域名的管理*/
const base = {    sq: 'https://xxxx111111.com/api/v1',    bd: 'http://xxxxx22222.com/api'
}export default base;

通过base.js来管理我们的接口域名,不管有多少个都可以通过这里进行接口的定义。即使修改起来,也是很方便的。

最后就是接口模块的说明,例如上面的article.js:

/*** article模块接口列表*/import base from './base'; // 导入接口域名列表
import axios from '@/utils/http'; // 导入http中创建的axios实例
import qs from 'qs'; // 根据需求是否导入qs模块const article = {    // 新闻列表    articleList () {        return axios.get(`${base.sq}/topics`);    },    // 新闻详情,演示    articleDetail (id, params) {        return axios.get(`${base.sq}/topic/${id}`, {            params: params        });    },// post提交    login (params) {        return axios.post(`${base.sq}/accesstoken`, qs.stringify(params));    }// 其他接口…………
}export default article;

1.通过直接引入我们封装好的axios实例,然后定义接口、调用axios实例并返回,可以更灵活的使用axios,比如你可以对post请求时提交的数据进行一个qs序列化的处理等。

2.请求的配置更灵活,你可以针对某个需求进行一个不同的配置。关于配置的优先级,axios文档说的很清楚,这个顺序是:在 lib/defaults.js 找到的库的默认值,然后是实例的 defaults 属性,最后是请求的 config 参数。后者将优先于前者。

3.restful风格的接口,也可以通过这种方式灵活的设置api接口地址。

最后,为了方便api的调用,我们需要将其挂载到vue的原型上。在main.js中:

import Vue from 'vue'
import App from './App'
import router from './router' // 导入路由文件
import store from './store' // 导入vuex文件
import api from './api' // 导入api接口Vue.prototype.$api = api; // 将api挂载到vue的原型上

然后我们可以在页面中这样调用接口,eg:

methods: {    onLoad(id) {      this.$api.article.articleDetail(id, {        api: 123      }).then(res=> {// 执行某些操作      })    }  
}

再提一下断网的处理,这里只做一个简单的示例:

<template>  <div id="app">    <div v-if="!network">      <h3>我没网了</h3>      <div @click="onRefresh">刷新</div>      </div>    <router-view/>      </div>
</template><script>import { mapState } from 'vuex';export default {  name: 'App',  computed: {    ...mapState(['network'])  },  methods: {    // 通过跳转一个空页面再返回的方式来实现刷新当前页面数据的目的onRefresh () {      this.$router.replace('/refresh')    }  }}
</script>

这是app.vue,这里简单演示一下断网。在http.js中介绍了,我们会在断网的时候,来更新vue中network的状态,那么这里我们根据network的状态来判断是否需要加载这个断网组件。断网情况下,加载断网组件,不加载对应页面的组件。当点击刷新的时候,我们通过跳转refesh页面然后立即返回的方式来实现重新获取数据的操作。因此我们需要新建一个refresh.vue页面,并在其beforeRouteEnter钩子中再返回当前页面。

// refresh.vue
beforeRouteEnter (to, from, next) {next(vm => {            vm.$router.replace(from.fullPath)        })    
}

这是一种全局通用的断网提示,当然了,也可以根据自己的项目需求操作。具体操作就仁者见仁智者见智了。

如果更多的需求,或者说是不一样的需求,可以根据自己的需求进行一个改进。

如果感觉对你有帮助,那就收藏❤❤吧!

转发在看就是最大的支持❤️

相关文章:

Vue中Axios的封装和API接口的管理

一、axios的封装 在vue项目中&#xff0c;和后台交互获取数据这块&#xff0c;我们通常使用的是axios库&#xff0c;它是基于promise的http库&#xff0c;可运行在浏览器端和node.js中。他有很多优秀的特性&#xff0c;例如拦截请求和响应、取消请求、转换json、客户端防御XSR…...

MLIR面试题

1、请简要解释MLIR的概念和用途&#xff0c;并说明MLIR在编译器领域中的重要性。 MLIR(Multi-Level Intermediate Representation)是一种多级中间表示语言&#xff0c;提供灵活、可扩展和可优化的编译器基础设施。MLIR的主要目标是为不同的编程语言、领域专用语言(DSL)和编译器…...

***杨辉三角_yyds_LeetCode_python***

1.题目描述&#xff1a; 给定一个非负整数 numRows&#xff0c;生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 示例 1: 输入: numRows 5 输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]] 示例 2: 输入: numRows …...

Mac使用DBeaver连接达梦数据库

Mac使用DBeaver连接达梦数据库 下载达梦驱动包 达梦数据库 在下载页面随便选择一个系统并下载下来。 下载下来的是zip的压缩包解压出来就是一个ISO文件&#xff0c;然后我们打开ISO文件进入目录&#xff1a;/dameng/source/drivers/jdbc 进入目录后找到这几个驱动包&#x…...

spring.expression 随笔0 概述

0. 我只是个普通码农&#xff0c;不值得挽留 Spring SpEL表达式的使用 常见的应用场景:分布式锁的切面借助SpEL来构建key 比较另类的的应用场景:动态校验 个人感觉可以用作控制程序的走向&#xff0c;除此之外&#xff0c;spring的一些模块的自动配置类&#xff0c;也会在Cond…...

从Cookie到Session: Servlet API中的会话管理详解

文章目录 一. Cookie与Session1. Cookie与Session2. Servlet会话管理操作 二. 登录逻辑的实现 一. Cookie与Session 1. Cookie与Session 首先, 在学习过 HTTP 协议的基础上, 我们需要知道 Cookie 是 HTTP 请求报头中的一个关键字段, 本质上是浏览器在本地存储数据的一种机制,…...

docker数据管理与网络通信

一、管理docker容器中数据 管理Docker 容器中数据主要有两种方式:数据卷(Data Volumes)和数据卷容器( DataVolumes Containers) 。 1、 数据卷 数据卷是一个供容器使用的特殊目录&#xff0c;位于容器中。可将宿主机的目录挂载到数据卷上&#xff0c;对数据卷的修改操作立刻…...

怎么查询电脑的登录记录及密码更改情况?

源头是办公室公用的电脑莫名其妙打不开了&#xff0c;问别人也都不知道密码是多少 因为本来就没设密码啊&#xff01;&#xff08;躺倒&#xff09; 甚至已经想好了如果是50万想攻破电脑&#xff0c;被po抓住要怎么花这笔钱了 是我想太多 当然最后也没解决&#xff0c;莫名…...

《三》TypeScript 中函数的类型

TypeScript 允许指定函数的参数和返回值的类型。 函数声明的类型定义&#xff1a;function 函数名(形参: 形参类型, 形参: 形参类型, ...): 返回值类型 {} function sum(x: number, y: number): number {return x y } sum(1, 2) // 正确 sum(1, 2, 3) // 错误。输入多余的或者…...

深入学习 Mysql 引擎 InnoDB、MyISAM

tip&#xff1a;作为程序员一定学习编程之道&#xff0c;一定要对代码的编写有追求&#xff0c;不能实现就完事了。我们应该让自己写的代码更加优雅&#xff0c;即使这会费时费力。 &#x1f495;&#x1f495; 推荐&#xff1a;体系化学习Java&#xff08;Java面试专题&#…...

【华为OD统一考试B卷 | 100分】阿里巴巴找黄金宝箱(V)(C++ Java JavaScript Python)

题目描述 一贫如洗的樵夫阿里巴巴在去砍柴的路上,无意中发现了强盗集团的藏宝地,藏宝地有编号从0~N的箱子,每个箱子上面贴有一个数字。 阿里巴巴念出一个咒语数字k(k<N),找出连续k个宝箱数字和的最大值,并输出该最大值。 输入描述 第一行输入一个数字字串,数字之间…...

六步快速搭建个人网站

目录 第一步、选择搭建平台WordPress 第二步、选域名 1&#xff09;域名在哪买&#xff1f; 2&#xff09;域名怎么选&#xff1f; 3&#xff09;以阿里云为例&#xff0c;讲解怎么买域名 第三步、选择服务器 第四步、申请主机、安装WordPress 第五步、选择WordPress模…...

TypeScript 中的 type 关键字有什么用?

创建类型别名 在 TypeScript 中&#xff0c;type 关键字用于创建类型别名&#xff08;Type Alias&#xff09;。类型别名可以给一个类型起一个新的名字&#xff0c;使代码更具可读性和可维护性。 类型别名可以用于定义各种类型&#xff0c;包括基本类型、复合类型和自定义类型…...

27 getcwd 的调试

前言 同样是一个 很常用的 glibc 库函数 不管是 用户业务代码 还是 很多类库的代码, 基本上都会用到 获取当前路径 不过 我们这里是从 具体的实现 来看一下 测试用例 就是简单的使用了一下 getcwd rootubuntu:~/Desktop/linux/HelloWorld# cat Test04Getcwd.c #inc…...

使用IDEA使用Git:Git使用指北——实际操作篇

Git使用指北——实际操作 &#x1f916;:使用IDEA Git插件实际工作流程 &#x1f4a1; 本文从实际使用的角度出发&#xff0c;以IDEA Git插件为基座讲述了如果使用IDEA的Git插件来解决实际开发中的协作开发问题。本文从 远程仓库中拉取项目&#xff0c;在本地分支进行开发&…...

java boot将一组yml配置信息装配在一个对象中

其实将一组yml数据封进一个对象中才是以后的主流开发方式 我们创建一个springboot项目 找到项目中的启动类所在目录 在同目录下创建一个类 名字你们可以随便取 我这里直接叫 dataManager 然后 在yml中定义这样一组数据信息 然后 我们在类中定义三个和这个配置信息相同的字段…...

【裸机开发】链接脚本(.lds文件)的基本语法

目录 一、什么是链接脚本&#xff1f; 二、链接脚本的基本语法格式 1、常用命令 2、内置变量 三、链接脚本的简单案例 一、什么是链接脚本&#xff1f; 一段程序的编译需要经历四个阶段&#xff08;预处理—编译—汇编—链接&#xff09;&#xff0c;而链接脚本管理的就是…...

Java 进阶 -- 集合(三)

4、实现 实现是用于存储集合的数据对象&#xff0c;它实现了接口部分中描述的接口。本课描述了以下类型的实现: 通用实现是最常用的实现&#xff0c;是为日常使用而设计的。它们在标题为“通用实现”的表格中进行了总结。特殊目的实现是为在特殊情况下使用而设计的&#xff0…...

【华为OD机试真题 C语言】5、TLV解析 | 机试真题+思路参考+代码解析

文章目录 一、题目&#x1f383;题目描述&#x1f383;输入输出&#x1f383;样例1 二、思路参考三、代码参考&#x1f3c6;C语言 作者&#xff1a;KJ.JK &#x1f342;个人博客首页&#xff1a; KJ.JK &#x1f342;专栏介绍&#xff1a; 华为OD机试真题汇总&#xff0c;定期…...

(七)CSharp-刘铁锰版-事件

一、初步了解事件 定义&#xff1a;单词 Event &#xff0c;译为“事件” 《牛津词典》中的解释是“a thing that happens,especially something important”通顺的解释就是“能够发生的什么事情” 角色&#xff1a; 使对象或类具备通知能力的成员 &#xff08;中译&#x…...

【ROS】郭老二博文之:ROS目录

1、ROS2 【ROS】Ubuntu22.04安装ROS2&#xff08;Humble Hawksbill&#xff09; 【ROS】ROS2命令行工具详解 【ROS】ROS2中的概念和名词解释 【ROS】ROS2编程示例&#xff1a;话题订阅-发布-C版 【ROS】ROS2编程示例&#xff1a;服务和客户端-C版 【ROS】ROS2编程示例&#xf…...

Android应用程序进程的启动过程

Android应用程序进程的启动过程 导语 到这篇文章为止&#xff0c;我们已经简要地了解过了Android系统的启动流程了&#xff0c;其中比较重要的内容有Zygote进程的启动和SystemService以及Launcher的启动&#xff0c;接下来我们将要学习的是Android应用程序的启动过程&#xff…...

【2】Midjourney注册

随着AI技术的问世&#xff0c;2023年可以说是AI爆炸性成长的一年&#xff0c;近期最广为人知的AI服务除了chatgpt外&#xff0c;就是从去年五月就已经问世的AI绘画工具mid journey了。 ▲几个AI工具也代表了人工智能的热门阶段 只要输入一段文字&#xff0c;AI就会根据语意计算…...

第六十八天学习记录:高等数学:导数(宋浩板书)

导数是微积分中的一个概念&#xff0c;描述了函数在某一个点上的变化率。具体地说&#xff0c;函数 f ( x ) f(x) f(x)在 x a xa xa处的导数为 f ′ ( a ) f(a) f′(a)&#xff0c;表示当 x x x在 a a a处发生微小的变化 Δ x \Delta x Δx时&#xff0c; f ( x ) f(x) f(x)对…...

unreal 5 实现角色拾取功能

要实现角色拾取功能&#xff0c;我们需要实现蓝图接口功能&#xff0c;蓝图接口主要提供的是蓝图和蓝图之间可以通信&#xff0c;接下来&#xff0c;跟着教程&#xff0c;实现一下角色的拾取功能。 首先&#xff0c;我们要实现一个就是可视区的物品在朝向它的时候&#xff0c;会…...

chatgpt赋能python:如何使用Python升序排列一个列表?

如何使用Python升序排列一个列表&#xff1f; 在Python编程中&#xff0c;我们经常需要对列表进行排序。列表排序是一种常见的操作&#xff0c;可以帮助我们对数据进行分析和管理。在这篇文章中&#xff0c;我们将学习如何使用Python对一个列表进行升序排列。 什么是升序排列…...

Lecture 20 Topic Modelling

目录 Topic ModellingA Brief History of Topic ModelsLDAEvaluationConclusion Topic Modelling makeingsense of text English Wikipedia: 6M articlesTwitter: 500M tweets per dayNew York Times: 15M articlesarXiv: 1M articlesWhat can we do if we want to learn somet…...

ThreadPoolExecutor线程池

文章目录 一、ThreadPool线程池状态二、ThreadPoolExecutor构造方法三、Executors3.1 固定大小线程池3.2 带缓冲线程池3.3 单线程线程池 四、ThreadPoolExecutor4.1 execute(Runnable task)方法使用4.2 submit()方法4.3 invokeAll()4.4 invokeAny()4.5 shutdown()4.6 shutdownN…...

chatgpt赋能python:Python实践:如何升级pip

Python实践&#xff1a;如何升级pip Python作为一门高效的脚本语言&#xff0c;被广泛应用于数据分析、人工智能、Web开发等领域。而pip则是Python的包管理工具&#xff0c;是开发Python应用的必备工具。但是pip在使用过程中&#xff0c;有时候会出现版本不兼容或者出现漏洞等…...

【JavaEE进阶】mybatis

目录&#xff1a; 一、Mybatis是什么 三个映射关系如下图&#xff1a; 二、mybatis的使用&#xff08;前置工作简单案例&#xff09; 第一步&#xff1a;导入MAVEN依赖 第二步&#xff1a; 在spring项目当中新建数据源 第三步&#xff1a;新建一个实体类&#xff0c;是和…...

制作器/抖音优化排名

ID&#xff1a;fuchen1994 姓名&#xff1a;江军 作业要求&#xff1a; 理解Linux系统中进程调度的时机&#xff0c;可以在内核代码中搜索schedule()函数&#xff0c;看都是哪里调用了schedule()&#xff0c;判断我们课程内容中的总结是否准确&#xff1b; 使用gdb跟踪分析一…...

网站建设个人总结/在百度平台如何做营销

小编觉得吧证件照这种东西就有一种“让人露出真面目”的魔力身份证照片更是证件照里的重灾区超过八成的网友表示身份证照是世界上最丑的照片它掀起你的减龄刘海将卡姿兰大眼睛照成死鱼眼让你的脸看起来像被车碾过一样又平又宽很多人对身份证照深恶痛绝绞尽脑汁想换照片某市民谎…...

360度搜索建站网/网站推广公司排名

今天弄了一上午的python-ldap,发现要么安装vc&#xff0c;要么用其他比较麻烦的方法&#xff0c;都比较麻烦。幸好找到这个地址&#xff1a; http://www.lfd.uci.edu/~gohlke/pythonlibs/ http://www.voidspace.org.uk/python/modules.shtml 这上面有很多python第三方包的二进制…...

做asp动态网站制作流程/建站软件可以不通过网络建设吗

栈与队列就像一对兄弟一样&#xff0c;学习的时候可以一块学习。 栈的特点&#xff1a;先进后出 队列的特点&#xff1a;先进先出 一、头文件 栈的头文件 #include<stack> 队列的头文件 #include<queue> 二、定义 栈的定义&#xff1a;stack<TYPE> s; 队列…...

品牌网球拍有哪些/宁波seo网络推广咨询价格

https://codeleading.com/article/2794704035/ 本文转自如上网址。 1.对于mysql数据库&#xff0c;driverurl中加入:allowMultiQueriestrue&rewriteBatchedStatementstrue; 这样在使用jdbctemplate插入的时候&#xff0c;类似: private void insertData(JdbcTemplate in…...

WordPress多域名登录/搜索引擎优化排名技巧

Monica◆ ◆ ◆ 神经质外加控制欲的莫妮卡 莫妮卡是《六人行》的中心人物&#xff0c;其他五人可以说就是由她延伸出来的。 [个性]像是妈妈般的照顾大家&#xff0c;爱管闲事&#xff0c;让她成为大家的支柱。在市区最炫餐厅担任厨师&#xff0c;不论工作和生活上&#xff0c;凡…...