小白系列Vite-Vue3-TypeScript:011-登录界面搭建及动态路由配置

这篇具有很好参考价值的文章主要介绍了小白系列Vite-Vue3-TypeScript:011-登录界面搭建及动态路由配置。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前面几篇文章我们介绍的都是Vite+Vue3+TypeScript项目中环境相关的配置,接下来我们开始进入系统搭建部分。本篇我们来介绍登录界面搭建及动态路由配置,大家一起撸起来......

搭建登录界面

登陆接口api

项目登陆接口是通过mockjs前端来模拟的

模拟服务接口LoginApi

首先在src/mock文件夹下新建login.ts文件,模拟两个服务接口(验证码获取+用户登录)

import { MockMethod } from 'vite-plugin-mock';

export const LoginApi: Array<MockMethod> = [
  {
    url: '/api/captchaImage',
    method: 'get',
    response: () => {
      return {
        msg: 'OK',
        img: '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',
        code: 200,
        uuid: '37e7a189a9b14be6a5cbae80af43abaa',
      };
    },
  },
  {
    url: '/api/login',
    method: 'post',
    response: () => {
      return {
        msg: 'OK',
        code: 200,
        token:
          'eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6Ijc2YzYzNzczLWY2ZWEtNDlkMC05MDIyLTg4ZmUxNjI1NmMzNyJ9.XUeTaH-VZu_Mm0Rm1m_lST4YH1-ovX5Gg9w_Z4nA04agzxzeTdb5XxKCIhMr8pPatCKmiCql9E7afMY96oGYfQ',
      };
    },
  },
];

LoginApi引入

修改src/mock文件夹下的index.ts文件,添加内容如下

import { LoginApi } from './login';
const mock: Array<MockMethod> = [...LoginApi];
使用vue3创建一个登录界面,小白系列Vite-Vue3-TypeScript,typescript,前端,javascript,Powered by 金山文档

创建登录API

在src/api文件夹下新建login.ts文件,创建获取验证码接口captchaImage和用户登录api接口login

import request from '@/utils/request';

export const captchaImage = () => {
  return request.get('/api/captchaImage');
};
export const login = () => {
  return request.post('/api/login');
};

登录界面Login.vue

在src/views路径下新建Login.vue文件,这个文件就是我们的登录界面文件

<template>
  <div class="login-main">
    <el-form ref="ruleFormRef" :model="ruleForm" status-icon :rules="rules" label-width="120px" class="ruleForm">
      <el-form-item prop="user">
        <el-input :prefix-icon="User" v-model="ruleForm.user" clearable />
      </el-form-item>
      <el-form-item prop="pass">
        <el-input :prefix-icon="Lock" v-model="ruleForm.pass" type="password" />
      </el-form-item>
      <el-form-item prop="code">
        <el-input :prefix-icon="Lock" v-model="ruleForm.code" class="code-value" />
        <img :src="img" alt="" class="code-img">
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="submitForm(ruleFormRef)">登录</el-button>
        <el-button @click="resetForm(ruleFormRef)">重置</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script setup lang='ts'>
// 方法引入
import { reactive, ref, onMounted } from 'vue'
import router from '@/router';
import { setLocalStorage } from "@/utils/localstorage";
import type { FormInstance } from 'element-plus'
// 组件引入
import { User, Lock } from '@element-plus/icons-vue'
// 接口引入
import { captchaImage, login } from "@/api/login";

onMounted(() => {
  captchaImage().then(datas => {
    console.log(datas)
    img.value = 'data:image/gif;base64,' + datas.img
    uuid.value = datas.uuid
  })
})
let img = ref<any>("")
let uuid = ref<string>("")
const ruleFormRef = ref<FormInstance>()
const validateUser = (rule: any, value: any, callback: any) => {
  if (value === '') {
    callback(new Error('用户名不能为空'))
  } else {
    callback()
  }
}
const validatePass = (rule: any, value: any, callback: any) => {
  if (value === '') {
    callback(new Error('密码不能为空'))
  } else {
    callback()
  }
}
const validateCode = (rule: any, value: any, callback: any) => {
  if (value === '') {
    callback(new Error('验证码不能为空'))
  } else {
    callback()
  }
}
const ruleForm = reactive({
  user: 'wangjianlei',
  pass: '123456',
  code: '4'
})

const rules = reactive({
  pass: [{ validator: validatePass, trigger: 'blur' }],
  user: [{ validator: validateUser, trigger: 'blur' }],
  code: [{ validator: validateCode, trigger: 'blur' }],
})

const submitForm = (formEl: FormInstance | undefined) => {
  if (!formEl) return
  formEl.validate((valid) => {
    if (valid) {
      login()
        .then(res => {
          console.log(res)
          setLocalStorage("LH_TOKEN", res.token)
          router.push("/")
        })
        .catch(err => {
          throw new Error(err);
        })
    } else {
      return false
    }
  })
}

const resetForm = (formEl: FormInstance | undefined) => {
  if (!formEl) return
  formEl.resetFields()
}
</script>

<style lang="scss" scoped>
.login-main {
  display: flex;
  padding: 25px;

  .ruleForm {
    width: 500px;

    .code-value {
      width: 260px;
    }

    .code-img {
      margin-left: 10px;
      width: 75px;
      height: 30px;
    }
  }
}
</style>

配置动态路由

动态路由接口

项目动态路由接口同样是通过mockjs前端来模拟的

模拟服务接口HomeApi

首先在src/mock文件夹下新建home.ts文件,模拟动态路由返回服务接口

import { MockMethod } from 'vite-plugin-mock';

export const HomeApi: Array<MockMethod> = [
  {
    url: '/api/routerList',
    method: 'get',
    response: () => {
      const routes = [
        {
          path: '/main/PageOne',
          name: 'PageOne',
          component: 'PageOne.vue',
        },
        {
          path: '/main/PageTwo',
          name: 'PageTwo',
          component: 'PageTwo.vue',
        },
        {
          path: '/main/PageThree',
          name: 'PageThree',
          component: 'PageThree.vue',
        },
      ];

      return {
        msg: 'OK',
        code: 200,
        data: routes,
      };
    },
  },
];

这里我们可以看到共返回了三个路由“PageOne”,“PageTwo”和“PageThree”。

HomeApi引入

修改src/mock文件夹下的index.ts文件,添加内容如下

import { MockMethod } from 'vite-plugin-mock';
import { HomeApi } from './home';
import { LoginApi } from './login';

const mock: Array<MockMethod> = [...LoginApi, ...HomeApi];

export default mock;
使用vue3创建一个登录界面,小白系列Vite-Vue3-TypeScript,typescript,前端,javascript,Powered by 金山文档

创建动态路由API

在src/api文件夹下新建home.ts文件,创建获取动态路由接口GetDynamicRoutes

import request from '@/utils/request';

export const GetDynamicRoutes = () => {
  return request.get('/api/routerList');
};

新增路由界面

根据我们利用mockjs模拟的动态路由接口返回的数据,在src/views文件夹下创建modules文件夹,新建PageOne.vue,PageTwo.vue和PageThree.vue界面文件。

使用vue3创建一个登录界面,小白系列Vite-Vue3-TypeScript,typescript,前端,javascript,Powered by 金山文档

动态路由配置

我们的动态路由数据应由一个公共的地方进行管理,所以呢这里我选择利用vue的状态管理器pinia来实现这个功能。

首先我们在pinia的state中添加一个路由项routes(RouteRecordRaw类型的数组):

state: (): storeHome => {
  return {
    //路由表
    routes: [],
  };
},

然后在action中还需要添加一个根据路由数据加载动态路由的方法(updateRoutes),方法所需的路由数据和router对象由外部传入。(这里用外部传入router是为了避免循环调用router,毕竟需要进行加载动态路由的地方基本都有个router的示例对象,而外部传入的话,只需要调用然后传入一次router就可以了)

在src/store/type/home.ts添加状态项routes类型定义:

import { RouteRecordRaw } from 'vue-router';

export type storeHome = {
  routes: Array<RouteRecordRaw>;
};
使用vue3创建一个登录界面,小白系列Vite-Vue3-TypeScript,typescript,前端,javascript,Powered by 金山文档

加载路由的思路其实也很简单,首先解析咱调用接口后传入的路由数据,根据路由的数据类型生成对应的路由表,并存储到pinia中,然后直接遍历这个pinia中的路由表,使用router.addRoute()方法将路由加载进去。router.addRoute()方法支持传如两个参数,方便我们在指定位置的路由中插入children,这种情况下第一个参数是父级路由的name,第二个参数就是要添加的children路由对象。

需要我们注意的是:vite使用动态路由,在动态导入路由组件的时候,需要特别注意不能将页面路径直接作为component导入,虽然开发环境一般是能正常加载,但是打包到生产环境的时候十有八九会报错,所以我们需要添加以下代码:

//根据自己项目实际目录结构组织,注意这里的“../../”不能用“@”别名代替
let modules = import.meta.glob('../../views/modules/*.vue');

然后用modules形式引入,完整动态路由的pinia代码如下:

import { defineStore } from 'pinia';
import { storeHome } from '../types/home';

let modules = import.meta.glob('../../views/modules/*.vue');

export const useHomeStore = defineStore('index', {
  state: (): storeHome => {
    return {
      //路由表
      routes: [],
    };
  },
  getters: {},
  actions: {
    updateRoutes(data: Array<any>, router: any) {
      this.routes = [];
      data.forEach((el) => {
        this.routes.push({
          path: el.path,
          name: el.name,
          component: modules[`../../views/modules/${el.component}`],
        });
      });
      this.routes.forEach((el) => {
        router.addRoute('Home', el);
        // router.addRoute();
      });
    },
  },
});
使用vue3创建一个登录界面,小白系列Vite-Vue3-TypeScript,typescript,前端,javascript,Powered by 金山文档

加载动态路由

上面我们已经配置好了路由接口和加载路由的方法,加载动态路由的思路也很简单,在我们的初始页面中调用路由的数据接口,在获取到数据之后调用加载的方法即可。

// 方法引入
import router from '@/router';
// 接口引入
import { GetDynamicRoutes } from "@/api/home"
// 状态管理器引入
import { useHomeStore } from "@/store/modules/home";

const homeStore = useHomeStore()
onBeforeMount(() => {
  if (!getLocalStorage("LH_TOKEN")) {
    router.push("/login")
  } else {
    alert("登陆成功")
    GetDynamicRoutes().then(res => {
      homeStore.updateRoutes(res.data, router)
    })
    finish.value = true
  }
})

为验证我们的路由是否被加载成功,我们可以在调用动态路由同时创建对应的按钮,以便我们进行路由跳转。

<el-button v-for="item in routes" :key="item.name" @click="handleClick(item.path)">{{ item.name }}</el-button>

const routes = computed(() => homeStore.routes)
// 路由按钮点击事件
const handleClick = (path: string) => {
  router.push(path)
}

完整页面代码如下:

<template>
  <div class="home-main" v-if="finish">
    <div>
      <el-button v-for="item in routes" :key="item.name" @click="handleClick(item.path)">{{ item.name }}</el-button>
    </div>
    <RouterView />
  </div>

</template>
<script setup lang='ts'>
// 方法引入
import { reactive, ref, onBeforeMount, onMounted } from 'vue'
import { computed } from "@vue/reactivity";
import { getLocalStorage } from '@/utils/localstorage'
import router from '@/router';
// 组件引入
import HomeHeader from './home/HomeHeader.vue';
// 接口引入
import { GetDynamicRoutes } from "@/api/home"
// 状态管理器引入
import { useHomeStore } from "@/store/modules/home";

const homeStore = useHomeStore()
onBeforeMount(() => {
  if (!getLocalStorage("LH_TOKEN")) {
    router.push("/login")
  } else {
    alert("登陆成功")
    GetDynamicRoutes().then(res => {
      homeStore.updateRoutes(res.data, router)
    })
    finish.value = true
  }
})
const routes = computed(() => homeStore.routes)
// 路由按钮点击事件
const handleClick = (path: string) => {
  router.push(path)
}
let finish = ref(false)
</script>
<style lang="scss" scoped>
.home-main {}
</style>

动态路由效果

使用vue3创建一个登录界面,小白系列Vite-Vue3-TypeScript,typescript,前端,javascript,Powered by 金山文档

配置路由守卫

其实截止上面,我们的动态路由已经加载成功了。不过仔细测试会发现,还会有一个问题bug,假如我们刷新跳转后的页面,或者直接使用动态路由的路径进行跳转,就会出现报错“no match found for location with path '/PageOne' ”。添加的动态路由失效了,页面也没有显示,这是因为我们的路由和状态管理器pinia在刷新之后都会被重置,而我们加载路由的方法是在系统初始页面被调用的,当我们直接F5刷新页面或者直接输入路由路径的时候,初始页面其实并没有被加载,也就是说我们的动态路由并没有被加载上去,自然这个动态的页面也就丢失了。

这里我们可以通过添加路由守卫的方式来解决这个问题,大致思路:假如我们的页面请求路径不是我们定义的初始路径的时候,我们就在路由守卫中要求在跳转之前先去查询状态管理器中是否存在我们的动态路由,或者该动态路由是否满足我们的初始页面跳转要求,若不满足则请求动态路由接口并加载我们的动态路由,在加载完成后再继续执行页面跳转操作。

路由守卫代码如下:

// 路由守卫
router.beforeEach((to, from, next) => {
  if (to.path !== '/main' && to.path !== '/') {
    const store = useHomeStore();
    if (store.routes.length < 1) {
      GetDynamicRoutes()
        .then((res) => {
          store.updateRoutes(res.data, router);
          next({ path: to.path, replace: true });
        })
        .catch((_) => {
          next();
        });
    } else {
      next();
    }
  } else {
    next();
  }
});
使用vue3创建一个登录界面,小白系列Vite-Vue3-TypeScript,typescript,前端,javascript,Powered by 金山文档

最终效果

使用vue3创建一个登录界面,小白系列Vite-Vue3-TypeScript,typescript,前端,javascript,Powered by 金山文档

至此,登录界面和动态路由基本搭建就完成了。文章来源地址https://www.toymoban.com/news/detail-764885.html

我相信,每天学习一点点,收获成长亿点点!

到了这里,关于小白系列Vite-Vue3-TypeScript:011-登录界面搭建及动态路由配置的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Vue3+Vite+TypeScript常用项目模块详解

      目录 1.Vue3+Vite+TypeScript 概述 1.1 vue3  1.1.1 Vue3  概述 1.1.2 vue3的现状与发展趋势 1.2 Vite 1.2.1 现实问题 1.2 搭建vite项目 1.3 TypeScript 1.3.1 TypeScript 定义 1.3.2 TypeScript 基本数据类型  1.3.3 TypeScript语法简单介绍 2. 项目配置简单概述 2.1 eslint 校验代码工具配置 2.1.1 eslint定义 2.1.2 esl

    2024年02月08日
    浏览(42)
  • Vite4+Typescript+Vue3+Pinia 从零搭建(3) - vite配置

    项目代码同步至码云 weiz-vue3-template 关于vite的详细配置可查看 vite官方文档,本文简单介绍vite的常用配置。 项目初建后, vite.config.ts 的默认内容如下: 比如,修改 App.vue : 根目录下新建 .env 、 .env.development 、 .env.production 三个文件。 .env 文件内新增内容: .env.development 文件内

    2024年02月05日
    浏览(105)
  • Vue 3 + TypeScript + Vite 项目中,实现选中图片移动

    在组件的  script  标签中,定义相关的数据和方法。首先,使用 Vue 的  ref  函数创建一个对图片元素的引用: 接下来,实现选中时出现边框的效果。你可以通过设置 CSS 样式来实现这一点。以下是一个简单的示例: 在组件的  template  中,为选中的容器元素动态绑定  sele

    2024年02月13日
    浏览(33)
  • Vue3 + Vite + TypeScript + dataV 打造可视化大屏

    网上有许多开源的可视化大屏项目,但是分析之后,还是想自己从 0 搭建一个可视化大屏项目,毕竟 Vue 一直在更新,自己搭建的可以使用最新版本的 Vue ,如果对版本没有太多要求的小伙伴们选择那些开源项目的基础上去修改也是很不错的。其次自己搭建一个项目,可以更好

    2024年02月03日
    浏览(46)
  • Vue3 + Vite2 + TypeScript4搭建企业级项目框架

    1. 创建项目 使用命令行工具进入到你想要创建项目的目录,然后执行以下命令: 这将会创建一个新的项目文件夹和一个 package.json 文件。 2. 安装依赖 接下来你需要在项目中安装 Vue、Vite、TypeScript 和其他需要的依赖。执行以下命令: 以上命令会安装最新的 Vue、Vite 和 TypeSc

    2024年02月08日
    浏览(64)
  • Vite4+Typescript+Vue3+Pinia 从零搭建(4) - 代码规范

    项目代码同步至码云 weiz-vue3-template 要求代码规范,主要是为了提高多人协同和代码维护效率,结合到此项目,具体工作就是为项目配置 eslint 和 prettier 。 安装 EditorConfig for VS Code 插件,根目录下新建 .editorconfig 文件,增加以下配置 如果是非windows系统, end_of_line 设置为 cr 安

    2024年02月05日
    浏览(104)
  • Vite4+Typescript+Vue3+Pinia 从零搭建(5) - 路由router

    项目代码同步至码云 weiz-vue3-template Vue Router 是 Vue.js 的官方路由。它与 Vue.js 核心深度集成,让用 Vue.js 构建单页应用变得轻而易举。 在 src/view 下新建 home.vue 和 login.vue ,内容如下: login.vue 里修改下对应name即可 index.ts 作为路由入口, static.ts 作为静态路由, modules 内还可以

    2024年02月05日
    浏览(70)
  • Vite4+Typescript+Vue3+Pinia 从零搭建(2) - ts配置

    项目代码同步至码云 weiz-vue3-template 关于tsconfig的配置字段可查看其他文档,如 typeScript tsconfig配置详解 文件修改如下: 修改文件如下: 新建文件夹 types ,用来存放类型定义。比如新建 index.d.ts : 后续也可以新增其他文件,比如 global.d.ts 存放全局定义, router.d.ts 存放路由定

    2024年02月05日
    浏览(87)
  • Vite4+Typescript+Vue3+Pinia 从零搭建(7) - request封装

    项目代码同步至码云 weiz-vue3-template 基于 axios 封装请求,支持多域名请求地址 utils 目录下新建 request 文件夹,并新建 index.ts 、 request.ts 和 status.ts 文件。 此时,eslint会报 switch 前面的空格错误,需要修改 .eslintrc.cjs 里的 indent ,修改后,错误消失。 src 目录下新建 api 文件夹,

    2024年02月04日
    浏览(94)
  • vue3 + typescript + vite + naive ui + tailwindcss + jsx 仿苹果桌面系统

    基于 vue3.x + typescript + vite + naive ui + tailwindcss + jsx + vue-router + pinia,项目使用 tsx 作为模版输出,全程没有使用vue提供的SFC, 仿macos桌面前端项目,开源免费模版,希望减少工作量和学习新技术,希望能够帮助大家; 本人主要是后端的开发,对于前端我也是刚入门的小白,有很

    2024年02月07日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包