Table of Contents
vue3 ts axios pinia achieves senseless refresh
vue3 painless refresh (senseless refresh)
Implementation process
Home Web Front-end Vue.js How to use vue3+ts+axios+pinia to achieve senseless refresh

How to use vue3+ts+axios+pinia to achieve senseless refresh

May 25, 2023 pm 03:37 PM
vue3 axios pinia

vue3 ts axios pinia achieves senseless refresh

1. First download aiXos and pinia in the project

1

2

npm i pinia --save

npm install axios --save

Copy after login

2. Encapsulate axios request-----

Download js-cookie

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

npm i JS-cookie -s

//引入aixos

import type { AxiosRequestConfig, AxiosResponse } from "axios";

import axios from 'axios';

import { ElMessage } from 'element-plus';

import { useUserInfoStore } from '@/stores/modules/UserInfo'

import router from '@/router';

import qs from 'qs';

import Cookie from "js-cookie";

let baseURL = "";

// console.log(process.env.NODE_ENV);//判断环境

if (process.env.NODE_ENV === 'development') {

    baseURL = '/m.api'//后台请求接口地址

} else {

    baseURL = 'http://xxxx.cn:8080';//这里是项目上线后的地址

    

}

declare interface TypeResponse extends AxiosResponse {

    /**

     * 错误号,200表示成功,10006令牌过期

     */

    errno: number,

    /**

     * 返回的信息

     */

    errmsg: string

}

  

//创建axios实例

  

const instance = axios.create({

    baseURL,  // 接口地址

    timeout: 3000,

    headers: {

        "Content-Type": 'application/x-www-form-urlencoded'

    }

  

});

  

  

//添加拦截器

instance.interceptors.request.use((config) => {

    // 在发送请求之前做些什么--给请求头添加令牌token

    (config as any).headers['AdminToken'] = Cookie.get('token')//从cookie中拿token值,

//这里是使用了js-cookie插件。

    // console.log(config, "请求拦截器")

    return config

}, reeor => {

    // 对请求错误做些什么

    return Promise.reject(reeor);

});

// 需要无痛刷新的操作页面

const METHOD_TYPE = ["_mt=edit", "_mt=create", "_mt=delete"]

// //响应拦截器

instance.interceptors.response.use(async (response: AxiosResponse) => {

    // 对响应数据做点什么

    let data = response.data;

    let { errno, errmsg } = data;

    console.log(response, "响应拦截器");

    let path = router.currentRoute.value.fullPath;//当前路由路径

    if (10006 === errno) {

        const configData = response.config.data || ''

        // 判断请求类型是否需要无痛刷新,index !== -1则需要无痛刷新

        let index = METHOD_TYPE.findIndex(item => configData.includes(item))

        if (-1 === index) {//需要重新登入获取令牌

            router.replace({ path: "/login", query: { back: path } })//登入后需要跳回的地址

            return

        } else {//需要无痛刷新令牌

            const store = useUserInfoStore();

            const { username, password } = store.LoginInfo//在状态管理里面定义一个loginInfo

            // 1.重新获取令牌

            let loginData = { _gp: 'admin', _mt: 'login', username, password };

            const { errno, errmsg, data } = await post(loginData)//这里是通过async 将异步序列化改为同步

            if (200 == errno) {

                Cookie.set('token', data)//保存令牌

            } else {

                router.replace({ path: "/login", query: { back: path } })//登入后需要跳回的地址

                return Promise.reject({ errno, errmsg, data })

            }

            return instance.request(response.config)

        }

    // ElMessage.error(errmsg);//错误信息

    }

    return data;

}, reeor => {

    console.log(reeor);

  

    return Promise.reject(reeor);

})

  

function get(params?: object): Promise<TypeResponse> {

    return instance.get(&#39;&#39;, { params });

};

function post(data: object, params?: object): Promise<TypeResponse> {

    return instance.post(&#39;&#39;, qs.stringify(data), { params });

};

  

  

//暴露实列

export {

    post, get,

}

Copy after login

3.qs.stringify(data) is to convert the requested data into a form format. If you don’t need it, just remove it directly;

4. Log in again and jump Routing needs to be set, if not needed you can remove

5. State management--data

Download persistence tool

1

npm install pinia-plugin-persistedstate --s

Copy after login

Configure persistence in main.js

1

2

3

4

5

//引入数据持久化插件

import piniaPluginPersistedstate from &#39;pinia-plugin-persistedstate&#39;;

const pinia = createPinia()

pinia.use(piniaPluginPersistedstate);

app.use(pinia)

Copy after login

1

2

3

4

5

6

7

8

9

10

11

12

import { defineStore } from &#39;pinia&#39;

export const useUserInfoStore = defineStore(&#39;UserInfo&#39;, {

    state:() => ({

        

        LoginInfo:{

            username:&#39;&#39;,

            password:&#39;&#39;

        }

      }),

      

      persist:true;//状态存储持久化

})

Copy after login

6. Login page--Storage form data, that is, user Name and password

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

npm i lodash --s

import Cookies from &#39;js-cookie&#39;;//引入cookie

import * as _ from &#39;lodash&#39;;//防抖节流插件

import {post} from &#39;@/util&#39;;

import {useUserInfoStore} from &#39;@/stores/modules/UserInfo&#39; ;//用户信息

import { useRouter,useRoute } from &#39;vue-router&#39; ;//引入路由

//这里是表单输入的数据

const ruleForm = reactive({

    password: &#39;123456&#39;,

    username: &#39;admin&#39;

});

//请求接口数据

let data = {

    _gp: "admin",

    _mt: &#39;login&#39;,

    ...ruleForm

};

  

let LoginInfo = useUserInfoStore().LoginInfo;//状态管理定义的数据

async function init() {

    await post(data).then((res:any) => {

        let { data: token, errno, errmsg } = res

        if (200 === errno) {

            let time = new Date() //设置过期时间

            time.setTime(time.getTime() + 1000 * 60 * 30)

            Cookies.set(&#39;token&#39;, token, { expires: time });

            Object.assign(LoginInfo,ruleForm)

            if (route.query.back) { //如果存在参数

             let paths = route.query.back+&#39;&#39;//拼接字符串

             console.log(paths);

             if (paths==&#39;/&#39;) {

//因为我的home是&#39;/&#39;,所有需要判断

                router.replace(&#39;/Surface&#39;)//跳转至主页

                return

             }else{

                router.replace(paths)//则跳转至进入登录页前的路由

             }

              

           } else {

            router.replace(&#39;/Surface&#39;)//否则跳转至首页

           }

             

        } else {

            ElMessage.error(errmsg)

        }

    }).catch((err:any) => {

        ElMessage.error(&#39;登录异常!&#39;)

    })

    let info = {//用户信息请求信息接口数据

        _gp: "admin",

        _mt: &#39;info&#39;,

    }

//下面这个函数是请求用户信息的,不需要可以不写

    await post(info).then((res:any) => {

        let {data} = res

        console.log(data);

        infos(data)

  

    }).catch((err:any)=>{

        ElMessage.error(&#39;登录异常!&#39;)

    })

}

//防抖节流

const fangdou = _.debounce(init, 1500, {

    leading: true,  // 延长开始后调用

    trailing: false  // 延长结束前调用

})

//移除组件时,取消防抖

onUnmounted(() => {

    fangdou.cancel()

})

Copy after login

7.main.js Set routing guard

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

import Cookie from &#39;js-cookie&#39;

import router from &#39;./router&#39;//引入路由

  

//路由守卫

router.beforeEach(async (to, from ) => {

    let tokent:string|undefined = Cookie.get(&#39;token&#39;)

    if (!tokent && to.path == &#39;/login&#39;) {

        return  true

    }

    // 没有登录,强制跳转登录页

    if (!tokent && to.path !== &#39;/login&#39;) {

        router.replace({path:&#39;/login&#39;,query:{back:to.path}});

    }

    // 防止重复登录

    if (tokent && to.path === &#39;/login&#39;) {

        return {

            path: from.path ? from.path : &#39;/Surface&#39;

        }

    }

    return true

})

Copy after login

That’s about it

vue3 painless refresh (senseless refresh)

The principle of painless refresh: when the token expires, the response interceptor re-makes the login request through judgment

Implementation process

Define a loginInfo object in the state management state to store the user's account and password

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

//在状态管理文件中

import { defineStore } from &#39;pinia&#39;

import Cookies from "js.cookie"

import {post} from &#39;@/http&#39;

  

import router from &#39;@/router&#39;;

import { ElMessage } from &#39;element-plus&#39;;

export const useUserStore = defineStore({

  id: "userStore",

  persist: {

    paths:[&#39;user&#39;]

  },//持久化

  state: () => ({

    loginInfo:{

      username:&#39;&#39;,

      password:&#39;&#39;

    }

  }),

  getters: {},

  actions: {

    setUser(user:UserInfo) {

      this.user = user;

    },

    loginOut(){

      const data ={

        _gp:"admin",

        _mt:"logout"

      }

      post({},data).then((res:any)=>{

        let {errmsg,errno} = res

        if(200==errno){

          localStorage.removeItem("userStore")

          Cookies.remove("token")

          router.replace(&#39;/login&#39;)

          ElMessage.success(errmsg);

        }else{

          ElMessage.error(errmsg);

        }

      }).catch(res=>{

      console.log(res,"退出登入失败");

      })

    }

  }

})

Copy after login

In the login page, after the login request is successful, the user's account and password are stored in the status management

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

//在登入页面文件中

const data = { ...ruleForm, _gp: "admin", _mt: "login" }//转换成字符串

post({}, data).then(res => {

    let { data: token, errmsg, errno } = res as any;//获取登录状态

    if (200 == errno) {//登录成功的判断

        ElMessage.success("登录成功!")//消息提示登录成功

        let now = new Date();//获取当前时间

        now.setTime(now.getTime() + 1000 * 60 * 30);//转成时间类型

        Cookies.set("token", res.data, { expires: now })//获取token存到cookie

        Object.assign(store.loginInfo, ruleForm)//将账号密码存储到状态管理

        return Promise.resolve(token)

    } else {

        ElMessage.error(errmsg);//登入失败

        return Promise.reject(errmsg)

    }

})

Copy after login

3. In http, first define an array variable, which stores Operations that require painless refresh include: delete, add, edit

4. In the response interceptor, determine whether 10006 is equal to errno. If equal, the token has expired, otherwise it has not expired

5. The token expires. Get the interface request data and search it in the defined array to determine whether the request type requires painless refresh.

6.index===-1 means it is not found in the array, so there is no need to refresh it. Painful refresh, jump directly to the login page to log in

7.index! ==-1 means a painless refresh is required, deconstructing the user account and password stored in the status management, making a login interface request to re-obtain the token, and then making a login request without entering the login page. The effect of painless refresh

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

//在封装的http文件中

import axios, { type AxiosResponse } from &#39;axios&#39;;

import qs from &#39;qs&#39;

import Cookies from "js.cookie"

import router from &#39;@/router&#39;;

import { ElMessage } from &#39;element-plus&#39;;

import { useUserStore } from &#39;@/stores/admin&#39;;

  

declare interface TypeResponse extends AxiosResponse {

    url(url: any): unknown;

    [x: string]: any;

    /**

     * 错误号,200表示成功,10006令牌过期

     */

    errno: number,

    /**

     * 失败返回的消息

     */

    error: string,

    /**

     * 成功后返回的消息

    */

    errmsg: string

  

}

let baseURL = &#39;&#39;

  

if (process.env.NODE_ENV === "development") {

    baseURL = &#39;/m.api&#39;

} else {

    baseURL = "http://zxwyit.cn:8080/m.api"//上线后的路径

}

  

const instance = axios.create({//创建实例

    baseURL,

    headers: { "content-type": "application/x-www-form-urlencoded" }

})

  

// 请求拦截器

instance.interceptors.request.use(function (config) {

    if (config.headers) {

        config.headers[&#39;AdminToken&#39;] = Cookies.get("token") + &#39;&#39;

    }

    return config

}, function (error) {

    console.error(&#39;请求错误&#39;, error)

    return Promise.reject(error)

}

)

// 无痛刷新的原理:当token过期后,在响应拦截器通过判断重新进行登入请求

// 实现过程:

// 1.在状态管理state中定义一个loginInfo对象用于存储用户的账号和密码

// 2.登入页面中,在登入请求成功后将用户的账号和密码存储在状态管理

// 3.在http中,先定义一个数组变量,该数组存放需要无痛刷新的操作如:删除、添加、编辑

// 4.在响应拦截器中,判断10006是否等于errno,如果相等说明令牌过期了,否则没过期

// 5.令牌过期,获取接口请求数据在定义的数组中查找判断请求类型是否需要无痛刷新

// 6.index===-1则表示在数组中没有找到也就不需要无痛刷新,直接跳到登入页面进行登入

// 7.index!==-1则表示需要无痛刷新,将状态管理中存储的用户账号和密码解构出来,

// 进行登入接口请求从而达到重新获取令牌,进而达到不需要进入登入页面就可以进行登入请求也就达到无痛刷新的效果

  

// 需要无痛刷新的操作页面

const METHOD_TYPE = ["_mt=edit", "_mt=create", "_mt=delete"]

// 响应拦截器

instance.interceptors.response.use(async function (response) {

    let data = response.data//强解

    let { errno, errmsg } = data//结构赋值

    let path = router.currentRoute.value.fullPath//获取路径

    console.log(errno,&#39;errno&#39;);

     

    if (10006 == errno) {

        // 获取接口请求数据

        const configData = response.config.data || &#39;&#39;

        // 判断请求类型是否需要无痛刷新,index !== -1则需要无痛刷新

        let index = METHOD_TYPE.findIndex(item => configData.includes(item))

        if (-1 === index) {//需要重新登入获取令牌

            router.replace({ path: "/login", query: { back: path } })//登入后需要跳回的地址

            return

        } else {//需要无痛刷新令牌

            const store = useUserStore();

            const { username, password } = store.loginInfo//在状态管理里面定义一个loginInfo

            // 1.重新获取令牌

            let loginData = { _gp: &#39;admin&#39;, _mt: &#39;login&#39;, username, password };

            const { errno, errmsg, data } = await post(loginData)//这里是通过async 将异步序列化改为同步

            if (200 == errno) {

  

                Cookies.set(&#39;token&#39;, data)//保存令牌

            } else {

        console.log(55);

  

                router.replace({ path: "/login", query: { back: path } })//登入后需要跳回的地址

                return Promise.reject({ errno, errmsg,data})

            }

            return instance.request(response.config)

        }

    }

    return data

}, function (error) {

    console.error(&#39;响应错误&#39;, error)

    return Promise.reject(error)

}

)

function get(params?: object): Promise<TypeResponse> {

    return instance.get("", { params })

}

function post(data: object, params?: object): Promise<TypeResponse> {

    return instance.post("", qs.stringify(data), { params })

}

  

/**

 * 富文本框图片上传请求

 */

export function upload(data: object): Promise<TypeResponse> {

    return instance.post("http://192.168.1.188:8080/upload/admin", data);

}

  

export { get, post }

Copy after login

The above is the detailed content of How to use vue3+ts+axios+pinia to achieve senseless refresh. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

What should I do if 'Uncaught (in promise) Error: Request failed with status code 500' occurs when using axios in a Vue application? What should I do if 'Uncaught (in promise) Error: Request failed with status code 500' occurs when using axios in a Vue application? Jun 24, 2023 pm 05:33 PM

It is very common to use axios in Vue applications. axios is a Promise-based HTTP client that can be used in browsers and Node.js. During the development process, the error message "Uncaught(inpromise)Error: Requestfailedwithstatuscode500" sometimes appears. For developers, this error message may be difficult to understand and solve. This article will explore this

Choice of data request in Vue: Axios or Fetch? Choice of data request in Vue: Axios or Fetch? Jul 17, 2023 pm 06:30 PM

Choice of data request in Vue: AxiosorFetch? In Vue development, handling data requests is a very common task. Choosing which tool to use for data requests is a question that needs to be considered. In Vue, the two most common tools are Axios and Fetch. This article will compare the pros and cons of both tools and give some sample code to help you make your choice. Axios is a Promise-based HTTP client that works in browsers and Node.

What should I do if 'TypeError: Failed to fetch' occurs when using axios in a Vue application? What should I do if 'TypeError: Failed to fetch' occurs when using axios in a Vue application? Jun 24, 2023 pm 11:03 PM

Recently, during the development of Vue applications, I encountered a common problem: "TypeError: Failedtofetch" error message. This problem occurs when using axios to make HTTP requests and the backend server does not respond to the request correctly. This error message usually indicates that the request cannot reach the server, possibly due to network reasons or the server not responding. What should we do after this error message appears? Here are some workarounds: Check your network connection due to

How to solve the problem of 'Error: Network Error' when using axios in Vue application? How to solve the problem of 'Error: Network Error' when using axios in Vue application? Jun 25, 2023 am 08:27 AM

How to solve the problem of "Error: NetworkError" when using axios in Vue application? In the development of Vue applications, we often use axios to make API requests or obtain data, but sometimes we encounter "Error: NetworkError" in axios requests. What should we do in this case? First of all, you need to understand what "Error:NetworkError" means. It usually means that the network connection

Efficiently utilize Vue and Axios to implement batch processing of front-end data Efficiently utilize Vue and Axios to implement batch processing of front-end data Jul 17, 2023 pm 10:43 PM

Efficiently utilize Vue and Axios to implement batch processing of front-end data. In front-end development, data processing is a common task. When we need to process a large amount of data, processing the data will become very cumbersome and inefficient if there is no effective method. Vue is an excellent front-end framework, and Axios is a popular network request library. They can work together to implement batch processing of front-end data. This article will introduce in detail how to efficiently use Vue and Axios for batch processing of data, and provide relevant code examples.

How to select an avatar and crop it in Vue3 How to select an avatar and crop it in Vue3 May 29, 2023 am 10:22 AM

The final effect is to install the VueCropper component yarnaddvue-cropper@next. The above installation value is for Vue3. If it is Vue2 or you want to use other methods to reference, please visit its official npm address: official tutorial. It is also very simple to reference and use it in a component. You only need to introduce the corresponding component and its style file. I do not reference it globally here, but only introduce import{userInfoByRequest}from'../js/api' in my component file. import{VueCropper}from'vue-cropper&

What should I do if 'Error: timeout of xxxms exceeded' occurs when using axios in a Vue application? What should I do if 'Error: timeout of xxxms exceeded' occurs when using axios in a Vue application? Jun 24, 2023 pm 03:27 PM

What should I do if "Error: timeoutofxxxmsexceeded" occurs when using axios in a Vue application? With the rapid development of the Internet, front-end technology is constantly updated and iterated. As an excellent front-end framework, Vue has been welcomed by everyone in recent years. In Vue applications, we often need to use axios to make network requests, but sometimes the error "Error: timeoutofxxxmsexceeded" occurs.

How to use defineCustomElement to define components in Vue3 How to use defineCustomElement to define components in Vue3 May 28, 2023 am 11:29 AM

Using Vue to build custom elements WebComponents is a collective name for a set of web native APIs that allow developers to create reusable custom elements (customelements). The main benefit of custom elements is that they can be used with any framework, even without one. They are ideal when you are targeting end users who may be using a different front-end technology stack, or when you want to decouple the final application from the implementation details of the components it uses. Vue and WebComponents are complementary technologies, and Vue provides excellent support for using and creating custom elements. You can integrate custom elements into existing Vue applications, or use Vue to build

See all articles