存放日常开发所撰写的Markdown文件。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

6.2 KiB

Vite + Vue3 + Pinia + Vue-Router 项目分析


该项目来自CSDN 的 前端大斗师的一个dome Project。这个项目对于初学Vite + Vue3、自学Vite+Vue3、拥有Vue2或Vue3一定知识想尝试官方建议的Vite脚手架的小伙伴,是一个不错的项目模板。

前言

该分析是本人在自学中,所分析的结果。仅是本人学习中的一种记录📝。可以用于参考,有不对的地方,请多多指教。


截屏2023-05-12 上午2.01.43

这是用WebStorm 打开项目的目录结构。


分析:

.env 、.env.prod、.gitignore的文件就不过多余的解释了。用来配置项目的环境和git的相关文件。

package.json 是配置项目的配置文件。【主要用来执行框架的和存放开发中所用的包。】

vite.config.js 是配置Vite脚手架的配置文件。【主要实例Vue3 和导入 开发常用的插件。】

Main.js 是vite+ vue3 的主要的核心。这用来创建vue3的。但具体的实例过程是交付给Vite脚手架实例化的,而脚手架的实例化过程可以看看里面的内容。【以及定义全局属性的地方】

其余的文件就挨个分析。


Views 文件夹:

主要存放Vue的组件【视图】

目录结构:

截屏2023-05-12 上午2.12.55

admin 是 存放 管人员的;home 是存放用户的;List 是表单的;Login 是登录界面;NotFound是错误界面的;

截屏2023-05-12 上午2.14.50

这是展开的结果。

唔~感觉这个划分应该可以优化一下。但这可能是博主的开发习惯。我比较习惯于;组件+页面+角色 的方式来划分。不做过多评价。

首先看Login 界面的代码:

// index.vue
<template>
  <div class="login">
    <loginForm @LoginEmit="LoginEmit" />
  </div>
</template>
<script setup>
import { defineComponent, onMounted, onUnmounted, ref } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import { useStore } from '@/store/index.js'
import { handleLogin } from '@/api/login.js'
import { animationRoute } from '@/api/common.js'
import loginForm from './components/loginForm.vue'


const Component = defineComponent({
  loginForm
})

const Mounted = onMounted(() => {
  let type = Math.ceil(Math.random() * 10)
  if (type % 2 !== 0) {
    document.querySelector('.login').style.background = '#000'
    for (let i = 0; i < 200; i++) {
      createSnow()
    }
  }
})

const Unmounted = onUnmounted(() => {
  clearInterval(timer.value)
  timer.value = null
})

/**
 * @type Router
 * @description 所有数据都在此体现
 * **/

const Router = useRouter()
const store = useStore()
const timer = ref(null)
const windowWidth = window.screen.width
const windowHeight = window.screen.height

/**
* @type methods
* @description 所有方法、事件都在此层中体现
* **/


//创建雪花
const createSnow = () => {
  let left = 0
  let top = 0

  //定义一个初始化随机数,使雪花在屏幕中
  let left_random = Math.random() * windowWidth
  let top_random = Math.random() * windowHeight
  let div = document.createElement('div')
  div.style.color = '#fff'
  div.style.fontSize = Math.round(Math.random() * 60) + 'px'
  div.style.position = 'absolute'
  div.style.userSelect = 'none'
  div.innerText = '❄'
  div.style.transform = 'scale(' + (Math.random()) + ')'
  document.querySelector('.login').appendChild(div)

  //雪花飘落
  timer.value = setInterval(() => {
    div.style.left = left_random + left + 'px'
    div.style.top = top_random + top + 'px'
    left += 0.2
    top += 0.2

    //如果雪花跑到屏幕外面了,让雪花重新返回屏幕顶部
    if (left_random + left >= windowWidth) {
      left_random = Math.random()
      left = 0
    }

    if (top_random + top >= windowHeight) {
      top_random = Math.random()
      top = 0
    }
  }, 20)
}

const LoginEmit = async form => {
  const { username, password } = form
  //   这里定义一个get请求。
  let res = await handleLogin()
  //   这里就是通过get请求中的过滤器来判断所传入的item 中的item。username是否相同。【注释:这里的过滤器是JavaScript自带的。是用于对数组进行过滤的】
  let currentUser = res.data.filter(item => { return item.username === username })
  if (currentUser.length < 1) return ElMessage.error('用户不存在')
  if (currentUser[0].password !== password) return ElMessage.error('密码错误')
  store.SAVE_USER_MESSAGE(currentUser[0])
  let routerList = await animationRoute(username)
  store.SAVE_ANIMATION_ROUTER([...routerList.data])
  await Router.push('/home')
}
</script>
<style lang="less" scoped>
.login {
  position: relative;
  height: 100%;
  background-image: url("../../assets/images/login_bg.webp");
  background-repeat: no-repeat;
  background-size: cover;
  overflow: hidden;
}
</style>

从该代码中结合前面的项目结构,可以联想到整项目的界面仿佛像是一个卡槽。只要通过功能文件夹下的component的组件进行插入,这样的好处是在后面维护中,可以快速替换某个区域的功能。

从代码中看出,这里是通过一个emit的事件方式来获取子组件所传过来的数据。

<loginForm @LoginEmit="LoginEmit" /> 通过事件方式传递数据

调用了LoginEmit 的函数接收到的form 数据对象,并对form对象进行了过滤,和判断数据的是否存在,以及校验密码的是否正确的一系列操作后,通过Store的SAVE_USER_MESSAGE的函数进行存入到Store中。同理的下面的SAVE_ANIMATION_ROUTER也是存入的操作。

随后接着请求一个animation路由。并跳转到Home路径。

至此结束登录操作。

但我个人认为这个登录操作还是有优化的空间的。我们可以对子组件所发送过来的对象进行校验是否和初始化获取的用户角色信息进行比对。如果一直则选择不同路由跳转,来跳转到用户的响应的jie