• vue+ts下集----ts配置路由、路由守卫、数据交互-axios、登录验证逻辑、状态管理


    ### ts配置路由

        ①安装:npm i vue-router -S
        ②src下新建pages/Home.vue(还有Goods.vue、Detail.vue等页面):
            <template>
                <div class="home">
                    <h2>首页</h2>
                </div>
            </template>
            <script lang="ts">
            import Vue from 'vue';
            import {Component} from "vue-property-decorator";
            @Component({})
            export default class Home extends Vue{
                
            }
            </script>
        ③src下新建plugins/router.ts:(注意Reg.vue和Detail.vue分别是以import和require的方式实现路由懒加载)
            import Vue from "vue";
            import VueRouter from "vue-router";
            Vue.use(VueRouter);// 安装插件
    
            import Home from "../pages/Home.vue";
            import Goods from "../pages/Goods.vue";
            import User from "../pages/User.vue";
            import Login from "../pages/Login.vue";
            import NoPage from "../pages/NoPage.vue";
            let routes=[
                {path:"/home",component:Home},
                {path:"/goods",component:Goods},
                {path:"/user",component:User},
                {path:"/login",component:Login},
                {path:"/reg",component:()=>import("../pages/Reg.vue")},
                {path:"/detail",component:(resolve:any)=>{require(["../pages/Detail.vue"],resolve)}},
                {path:"*",component:NoPage},
                {path:"/",redirect:"/home"},
            ];
    
            let router=new VueRouter({
                mode:"history",
                routes
            });
    
            export default router;
        ④main.js中引入router并注册:
            import router from "./plugins/router"
    
            new Vue({
                render: h => h(App),
                router
            }).$mount('#app')
        ⑤App.vue中开辟路由空间:
            <router-view></router-view>

    ### 路由守卫

        router.ts中:
            /*
            全局守卫
            */
            router.beforeEach((to,from,next)=>{
                console.log("全局前置守卫")
                next();
            })
            router.afterEach((to,from)=>{
                console.log("全局后置守卫")
            })
    
            // 路由独享守卫
            {path:"/user",component:User,beforeEnter: (to:Route, from:Route, next:Function) => {
                console.log("路由独享前置守卫")
                next();
            }},
            注意:设置路由独享守卫时,定义的Route类型是ts自动引入的(import VueRouter, { Route } from "vue-router";)
        组件内部守卫:(注意这里的Route类型是手动引入的)
            (1)User.vue中:
                import {Route} from "vue-router";
                @Component({
                    /*
                        这里写自定义指令、过滤器、守卫钩子函数
                    */
                    beforeRouteEnter (to:Route, from:Route, next:Function) {
                        // 由于写在装饰器中,钩子函数可以自动推测出to、from、next的类型,所以可以加类型也可以不加
                        console.log("组件内前置守卫")
                        next();
                    }
                })
            (2)Reg.vue中:
                import {Route} from "vue-router";
                @Component({
                    beforeRouteLeave (to:Route, from:Route, next:Function) {
                        console.log("组件内后置守卫")
                        next();
                    }
                })

    ### 数据交互-axios

        安装:npm i axios @types/axios -S
        注意:不是所有的插件都带有类型声明文件,只有类型声明文件才能保证支持ts,没有类型声明文件的插件需要安装类型声明文件。
        (1)axios初步使用:
            ①public下新建data/user.json:
                {
                    "data":[
                        {"username":"wxm"}
                    ]
                }
            ②Home.vue中:
                import axios from "axios";
                export default class Home extends Vue{
                    mounted():void {
                        axios({
                            url:"/data/user.json" // public中的数据可以直接访问
                        }).then(
                            res=>console.log(res.data)
                        )
                    }
                }
        (2)访问json-server数据:
            需要先将json-server开启数据服务,再设置url:url:"http://localhost:3000/data"
        (3)访问tiantian-api数据:
            ①开启tiantian-api数据服务:npm run start
            ②设置跨域代理(根目录下新建vue.config.js):
                module.exports={
                    devServer:{
                        proxy:{
                            "/v3":{
                                target:"http://localhost:3000",
                                changeOrigin:true
                            }
                        }
                    }
                }
            ③代理地址替代原地址:
                url:"/v3/homepage"
        (4)axios拦截器:
            ①plugins下新建axios.ts:
                import axios, { AxiosRequestConfig, AxiosResponse } from "axios";
                import router from './router';
                import { TUser } from '@/types';
    
                //请求拦截器
                axios.interceptors.request.use((config:AxiosRequestConfig):AxiosRequestConfig=>{
                    /*
                        抓取token,携带到响应头
                        显示loading
                    */
                    let user:TUser=window.localStorage.getItem("user");
                    user=user?JSON.parse(user):"";
                    config.headers={token:user?.token}// 携带到请求头
                    return config;
                },(error)=>{
                    return Promise.reject(error)
                })
    
                //响应拦截器
                axios.interceptors.response.use((response:AxiosResponse<any>):AxiosResponse<any>=>{
                    /*
                        token过期,跳转login,保留当前地址
                        关闭loading
                    */
                    // 判断如果有错误(token过期),并且当前路径不是login,则跳转到login页面,并且将当前的全路径带过去
                    if(response.data.err==2 && !router.currentRoute.fullPath.includes("/login")){
                        router.push({path:"/login",query:{path:router.currentRoute.fullPath}});
                    }
                    return response;
                },(error)=>{
                    return Promise.reject(error)
                })
    
                // 对外暴露
                export default axios;
            ②Home.vue中使用时用封装的axios替代原来的axios:
                import axios from "../plugins/axios";
        (5)将axios挂载到window下:
            ①src/types/index.ts中:
                // 定义全局变量,重定义了Window接口
                declare global{
                    interface Window{
                        axios(config:AxiosRequestConfig):AxiosPromise<any>
                    }
                }
            ②axios拦截器中对外暴露的时候添加:
                window.axios=axios;
            ③main.js中引入:
                import "./plugins/axios"
            ④Home.vue中使用时不用引入任何的axios,直接用window.axios()使用:
                mounted():void {
                    window.axios({
                        url:"/v3/homepage"
                    }).then(
                        res=>console.log(res.data)
                    )
                }
            

    ### 登录验证逻辑

        ①axios.ts的响应拦截器中利用router.currentRoute.fullPath可以拿到当前要去往的路由,保留当前地址:
            // 判断如果有错误(token过期),并且当前路径不是login,则跳转到login页面,并且将当前的全路径带过去
            if(response.data.err==2 && !router.currentRoute.fullPath.includes("/login")){
                router.push({path:"/login",query:{path:router.currentRoute.fullPath}});
            }
        ②Login.vue中点击登录时进行请求,如果没有错误,则将token存到localStorage中,并且跳转到响应拦截器中保留的路由:
            <button @click="login">登录</button>
            export default class Login extends Vue{
                public login():void {
                    window.axios({
                        url:"/api/login",
                        method:"post",
                        data:{username:"chenghao",password:"chenghao123"}
                    }).then(
                        res=>{
                            if(res.data.err==0){
                                // 种token到localStorage中
                                window.localStorage.setItem("user",JSON.stringify(res.data))
                                // 跳转到之前的页面
                                this.$router.replace(this.$route.query.path as string)
                            }
                        }
                    )
                }
            }

    ### 状态管理

        ①安装:npm i vuex vuex-class -S
        未完待续……




  • 相关阅读:
    解决eclipse自动格式化影响svn提交的问题
    XShell下载安装并连接阿里云
    阿里云服务器购买选择
    三线程循环打印ABC流程解释
    eclipse个人开发较常用的快捷键
    eclipse调试的一些技巧
    Java序列化与反序列化
    vmware vsphere添加磁盘,不重启检测
    win10国内生态-恶心的经历
    本地win10 vmware 虚拟机centos7系统初始化网络配置
  • 原文地址:https://www.cnblogs.com/wuqilang/p/12508315.html
Copyright © 2020-2023  润新知