PS:做项目时在n次忘记掉一些写过的知识点后于是终于决定记录笔记但是不知道在哪里记笔记同时又觉得CSDN上写东西很舒服于是决定在CSDN上写笔记的某菜菜敲下了TA的第一行字
1.项目初始化
安装and配置一大堆东东真的很麻烦的有木有www
创建vue3项目
pnpm create vue
安装sass依赖
pnpm add sass -D
引入element
pnpm add element-plus
安装插件
pnpm add -D unplugin-vue-components unplugin-auto-import
安装pinia插件
pnpm add pinia-plugin-persistedstate
安装axios
pnpm install axios
配置文件 .eslintrc.cjsp
/* eslint-env node */
require('@rushstack/eslint-patch/modern-module-resolution')
module.exports = {
root: true,
extends: [
'plugin:vue/vue3-essential',
'eslint:recommended',
'@vue/eslint-config-prettier/skip-formatting'
],
parserOptions: {
ecmaVersion: 'latest'
},
rules: {
'prettier/prettier': [
'warn',
{
singleQuote: true, // 单引号
semi: false, // 无分号
printWidth: 80, // 每行宽度至多80字符
trailingComma: 'none', // 不加对象|数组最后逗号
endOfLine: 'auto' // 换行符号不限制(win mac 不一致)
}
],
'vue/multi-word-component-names': [
'warn',
{
ignores: ['index'] // vue组件名称多单词组成(忽略index.vue)
}
],
'vue/no-setup-props-destructure': ['off'], // 关闭 props 解构的校验
// 💡 添加未定义变量错误提示,create-vue@3.6.3 关闭,这里加上是为了支持下一个章节演示。
'no-undef': 'error'
},
globals: {
ElMessage: 'readonly',
ElMessageBox: 'readonly',
ElLoading: 'readonly'
}
}
配置文件Vite
import { fileURLToPath, URL } from 'node:url'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
AutoImport({
resolvers: [ElementPlusResolver()]
}),
Components({
resolvers: [ElementPlusResolver()]
})
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
}
})
main.js
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
import router from './router'
import persist from 'pinia-plugin-persistedstate'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
const app = createApp(App)
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.component(key, component)
}
app.use(createPinia().use(persist))
app.use(createPinia())
app.use(router)
app.mount('#app')
App.vue
<script setup></script>
<template>
<div>
<router-view></router-view>
</div>
</template>
<style scoped></style>
router.js
import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: []
})
export default router
request.js
import axios from 'axios'
//import { useUserStore } from '../stores'
const baseURL = 'http://big-event-vue-api-t.itheima.net'
const instance = axios.create({
baseURL,
timeout: 1000
})
// 添加请求拦截器
instance.interceptors.request.use(
function (config) {
// 在发送请求之前做些什么
//const userStore = useUserStore()
//if (userStore.token) {
// config.headers.Authorization = userStore.token
//}
return config
},
function (error) {
// 对请求错误做些什么
return Promise.reject(error)
}
)
// 添加响应拦截器
instance.interceptors.response.use(
function (response) {
// 2xx 范围内的状态码都会触发该函数。
// 对响应数据做点什么
return response
},
function (error) {
// 超出 2xx 范围的状态码都会触发该函数。
// 对响应错误做点什么
return Promise.reject(error)
}
)
export default instance
2.登录 | 注册
2.1静态界面
没错,就是每次懒得重写欸嘿,能copy就copy是一个程序员的美好品德!!!
<el-form
:model="formModel"
:rules="rules"
ref="formRef"
size="large"
autocomplete="off"
v-if="isRegister"
>
<el-form-item>
<h1>注 册</h1>
</el-form-item>
<el-form-item>
<el-input
:prefix-icon="Lock"
type="password"
placeholder="请输入密码"
></el-input>
</el-form-item>
<el-form-item>
<el-input
:prefix-icon="Lock"
type="password"
placeholder="请输入再次密码"
></el-input>
</el-form-item>
<el-form-item>
<el-button class="button" type="primary" auto-insert-space>
注 册
</el-button>
</el-form-item>
<el-form-item class="flex">
<el-link type="info" :underline="false" @click="isRegister = false">
<el-icon><ArrowLeft /></el-icon>登 录
</el-link>
</el-form-item>
</el-form>
<el-form ref="form" size="large" autocomplete="off" v-else>
<el-form-item>
<h1>登 录</h1>
</el-form-item>
<el-form-item>
<el-input :prefix-icon="User" placeholder="请输入用户名"></el-input>
</el-form-item>
<el-form-item>
<el-input
name="password"
:prefix-icon="Lock"
type="password"
placeholder="请输入密码"
></el-input>
</el-form-item>
<el-form-item>
<el-button class="button" type="primary" auto-insert-space
>登 录</el-button
>
</el-form-item>
<el-form-item class="flex">
<el-link type="info" :underline="false" @click="isRegister = true">
注 册 <el-icon><ArrowRight /></el-icon>
</el-link>
</el-form-item>
</el-form>
2.2表单JS代码
<script setup>
import { Lock, User } from '@element-plus/icons-vue'
import { ref, watch } from 'vue'
const isRegister = ref(false)
const formRef = ref()
// 整个表单提交的数据对象
const formModel = ref({
username: '',
password: '',
repassword: ''
})
// 整个表单校验规则
const rules = {
username: [
{ required: true, message: '请输入用户名', trigger: 'blur' },
{ min: 2, max: 6, message: '用户名必须是2-6位的字符', trigger: 'blur' }
],
password: [
{ required: true, message: '请输入密码', trigger: 'blur' },
{
pattern: /^\S{6,15}$/,
message: '密码必须是6-15的非空字符',
trigger: 'blur'
}
],
repassword: [
{ required: true, message: '请再次输入密码', trigger: 'blur' },
{
pattern: /^\S{6,15}$/,
message: '密码必须是6-15的非空字符',
trigger: 'blur'
},
{
validator: (rule, value, callback) => {
if (value === formModel.value.password) {
callback()
} else {
callback(new Error('两次输入密码不一致'))
}
},
trigger: 'blur'
}
]
}
// 登录
const login = async () => {
// 登陆之前进行预校验
await formModel.value.validate()
}
// 注册
const register = async () => {
// 真正注册成功之前,进行检验
await formModel.value.validate()
}
// 切换的时候,重置表单的内容
watch(isRegister, () => {
formModel.value = {
username: '',
password: '',
repassword: ''
}
})
</script>
表单校验需要给el-form加上ref,:model,:rules属性
给el-form-item加上prop属性,给el-input或者其他的输入框加上v-model属性