感谢Vue3,让我遇见了这些知识-灵析社区

武士先生

前言

最近在学习Vue3,现在来说一下自己的学习感受,并且分享一些小知识点。

可能这些知识点并不是那么属于Vue3的知识范畴,但是这是我在学习过程中遇到并且记录下来的,对于我而言,是Vue3让我遇到了这些知识,哈哈哈哈,我就这么归类辣!

感想

这次使用的是Vite,之前都是用的vue-cli,Vite使用起来就一个字,快!

认真的去做一个自己的全栈项目,所以能封装起来用的地方,都尽量去封起来了,减少以后的代码量。

后端使用的是koa,也是第一次自己尝试去写后端。等这个项目写完,会继续分享一些踩坑小技巧的。

开始了,奇奇怪怪的小知识

封装两种习惯使用request

我们平时封装请求的时候,一般都会结合自己习惯来封装,冷不丁换人封装的时候,使用起来就非常不舒服,我问了问我的小伙伴们,大都是习惯以下这两种方式,所以我就对axios进行了封装,使他能够满足我们的使用习惯。

this.$request({ obj })

将参数用一个对象的方式进行解构。

this.$request({
      methods: 'get',
      url: '/login',
      data:{
        name:'Ned'
      }
    }).then((res)=>{
      console.log(res)
    })

封装如下

/**
 * axios二次封装
 */
import axios from 'axios'
import config from './../config'
import router from './../router';
import { ElMessage } from 'element-plus'

const TOKEN_INVALID = 'Token认证失败,请从新登陆'
const NETWORK_ERROR = '网络请求异常,请稍后重试'

// 创建axios实例对象,添加全局配置
const service = axios.create({
     baseURL:config.baseApi,
     timeout:8000
})

// 请求拦截器
service.interceptors.request.use((req) => {
    // to do
    const headers = req.headers
    if(!headers.Authorization) headers.Authorization = 'Bear token'
    return req
})

// 响应拦截器
service.interceptors.response.use((res) => {
    // to do
    /**
     * 注意状态码一共有两个
     * 一为http状态码
     * 二为接口返回状态码
     */
    const { code, data, msg } = res.data
    if(code === 200){
        return data
    }else if(code === 40001){
        ElMessage.error(TOKEN_INVALID)
        setTimeout(() => {
            router.push('/login')
        }, 15000);
        return Promise.reject(TOKEN_INVALID)
    }else{
        ElMessage.error(msg || NETWORK_ERROR)
        return Promise.reject(msg || NETWORK_ERROR)
    }
})

/**
 * 请求核心函数
 * @param {*} options  请求配置
 */
function request(options){
    // 判断get/post
    options.method = options.method || 'get'
    // 防止有时候写了GET
    if(options.method.toLowerCase() === 'get'){
        // 如果是get就将data直接赋值给params
        // 类型转换
        options.params = options.data;
    }
    if(config.env === 'prod'){
        service.defaults.baseURL = config.baseApi
    }else{
        service.defaults.baseURL = config.mock ? config.mockApi:config.baseApi
    }
    return service(options)
}

export default request

this.$request.get/post('/api',{ obj })

将get/post用.的方式取出,一个参数是接口路径,另一个参数是数据对象。

this.$request.get('/login',{name:Ned}).then((res)=>{
      console.log(res)
    })

在上一步的封装上,支持这种习惯

增加如下:

['get','post','put','delete','patch'].forEach((item)=>{
    request[item] = (url,data,options) =>{
        return request({
            url,
            data,
            method:item,
            ...options
        })
    }
})

路由跳转的三种方式

在此之前确实我就知道两种,Composition API的这种方式是我所不知道的,涨知识了!

router-link

<router-link to"/login">去登陆</router-link>

传统跳转(options API)

<template>
	<el-button @click="goLogin">去登陆</el-button>
</template>
<script>
	export default{
        name:'home',
        methods:{
            goLogin(){
				this.$router.push('/login')
            }
        }
    }
</script>

Composition API跳转

<script setup>
import { useRouter } from 'vue-router'
let router = userRouter()
const goLogin = ()=>{
    router.push('/login')
}
</script>

注意:setup是钩子函数,如果像第三个例子写的话,里面的函数都属于钩子范畴,可以像第二种方式那样,setup类似于methods,完后将它return出去应该也是可以的。

下面为上面注意中,方法的实现代码

大体上还是options API的写法,只是setup的思想属于composition API范畴,应该属于框架迁移过程中的写法吧

<template>
  <el-button @click="goLogin">去登陆</el-button>
</template>

<script>
import { useRouter } from 'vue-router'
export default{
  setup(){
    let router = useRouter()
    function goLogin(){
      router.push('./login')
    }
    return { goLogin }
  }
}
</script>

配置config

我们的请求地址通常应该会有三种,在前后端开发分离的情况,第一种就是mock地址,方便我们在没有后端的情况下进行前端开发,第二种是测试地址,也就是后端写好了之后,我们请求的从mock地址变成了后端写好后挂载的服务地址,最后,当测试没问题了,部署到线上,我们请求的就是部署好的线上地址了。

所以文件中的三种环境分别与开发环境,测试环境和部署环境相对应。

mock的重要性,我觉得mock很重要,他可以帮助我们在没有后端的时候,依据接口文档进行前端开发并测试。

以下为程序介绍: 默认是生产环境 prod,如果有值就赋值到env变量上,当做当前的环境变量。
最后将EnvConfig以解构的方式导出,方便根据当前环境直接调取两种Api

const env = import.meta.env.MODE || 'prod'
const EnvConfig = {
    dev:{
        baseApi:'',
        mockApi:''
    },
    test:{
        baseApi:'',
        mockApi:''
    },
    prod:{
        baseApi:'',
        mockApi:''
    }
}
export default {
    env:env,
    mock:true,
    ...EnvConfig[env]
}

关于storage

大家都应该很熟悉了,他可以与jwt token联系起来,来做一些权限的操作,或者当我们的数据需要跨组件共享的时候,也会用到它。

跨组件数据共享: 在Vue中使用Vuex,但是存在一个问题,因为数据此时存在js内存中,页面刷新后数据就会丢失,所以我们用Vuex和storage联合起来完善此功能。

下面是对storage进行封装,方便自己使用:

它自身带的api好像不支持清除单独的数据,只能全清理掉,所以我特意封装了个单独的emm,希望不是我没注意到它自带,那就哭了。
  • setItem()
  • getItem()
  • clearItem()
  • clearAll()

import config from './../config'
export default {
    setItem(key,val){
        let storage = this.getStorage()
        storage[key] = val
        window.localStorage.setItem(config.namespace,JSON.stringify(storage))
    },
    getItem(key){
        return this.getStorage()[key]
    },
    getStorage(){
       return  JSON.parse(window.localStorage.getItem(config.namespace)) || "{}"
    },
    clearItem(key){
        let storage = this.getStorage()
        delete storage[key]
        window.localStorage.setItem(config.namespace,JSON.stringify(storage))
    },
    clearAll(){
        window.localStorage.clear()
    }
}


阅读量:321

点赞量:0

收藏量:0