|
|
|
|
# Vite + Vue3 + Pinia + Vue-Router 项目分析
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
> 该项目来自[CSDN 的 前端大斗师](http://t.csdn.cn/SnJbg)的一个dome Project。这个项目对于初学Vite + Vue3、自学Vite+Vue3、拥有Vue2或Vue3一定知识想尝试官方建议的Vite脚手架的小伙伴,是一个不错的项目模板。
|
|
|
|
|
|
|
|
|
|
### 前言
|
|
|
|
|
|
|
|
|
|
该分析是本人在自学中,所分析的结果。仅是本人学习中的一种记录📝。可以用于参考,有不对的地方,请多多指教。
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
这是用WebStorm 打开项目的目录结构。
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
分析:
|
|
|
|
|
|
|
|
|
|
.env 、.env.prod、.gitignore的文件就不过多余的解释了。用来配置项目的环境和git的相关文件。
|
|
|
|
|
|
|
|
|
|
package.json 是配置项目的配置文件。【主要用来执行框架的和存放开发中所用的包。】
|
|
|
|
|
|
|
|
|
|
vite.config.js 是配置Vite脚手架的配置文件。【主要实例Vue3 和导入 开发常用的插件。】
|
|
|
|
|
|
|
|
|
|
Main.js 是vite+ vue3 的主要的核心。这用来创建vue3的。但具体的实例过程是交付给Vite脚手架实例化的,而脚手架的实例化过程可以看看里面的内容。【以及定义全局属性的地方】
|
|
|
|
|
|
|
|
|
|
其余的文件就挨个分析。
|
|
|
|
|
|
|
|
|
|
----
|
|
|
|
|
|
|
|
|
|
#### Views 文件夹:
|
|
|
|
|
|
|
|
|
|
主要存放Vue的组件【视图】
|
|
|
|
|
|
|
|
|
|
目录结构:
|
|
|
|
|
|
|
|
|
|

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

|
|
|
|
|
|
|
|
|
|
这是展开的结果。
|
|
|
|
|
|
|
|
|
|
唔~感觉这个划分应该可以优化一下。但这可能是博主的开发习惯。我比较习惯于;组件+页面+角色 的方式来划分。不做过多评价。
|
|
|
|
|
|
|
|
|
|
首先看Login 界面的代码:
|
|
|
|
|
|
|
|
|
|
```vue
|
|
|
|
|
// 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的组件进行插入,这样的好处是在后面维护中,可以快速替换某个区域的功能。而index卡槽只需要对后方的状态的
|