Vite + Vue3 + TS 第四章 模板语法和指令1. login.vue html部分
<template>
<div class="login-box">
<el-form ref="ruleFormRef" :model="ruleForm" status-icon :rules="rules" label-width="120px"
class="demo-ruleForm">
<h2>blog</h2>
<el-form-item label="用户名" prop="username">
<el-input v-model="ruleForm.username" type="username" autocomplete="off" />
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input v-model="ruleForm.password" type="password" autocomplete="off" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm(ruleFormRef)">Submit</el-button>
<el-button @click="resetForm(ruleFormRef)">Reset</el-button>
</el-form-item>
<p class="forget">
忘记密码?
<el-link @click="handleClick('11')" type="primary">点击这里</el-link>
</p>
<p class="forget">
没有用户
<el-link @click="handleClick('blog_reg')" type="success">点击注册</el-link>
</p>
</el-form>
</div>
</template>
2.login.vue ts
<script lang="ts" setup> import { reactive, ref } from 'vue' import { login } from "@/request/api";//登录api接口 import { useRouter } from "vue-router"; //router跳转 import { ElNotification,FormInstance } from 'element-plus'//弹框消息 const ruleFormRef = ref<FormInstance>() const router = useRouter() const handleClick = (name: string) => router.push({ name }) // 校验 const user = (rule: any, value: any, callback: any) => { if (value === '') { callback(new Error('请输入用户名')) } else { if (ruleForm.username !== '') { if (!ruleFormRef.value) return ruleFormRef.value.validateField('username', () => null) } callback() } } const user2 = (rule: any, value: any, callback: any) => { if (value === '') { callback(new Error('请输入密码')) } else { callback() } } const rules = reactive({ username: [{ validator: user, trigger: 'blur' }], password: [{ validator: user2, trigger: 'blur' }], }) // 参数 const ruleForm = reactive({ username: '', password: '', }) // 登录 const submitForm = (formEl: FormInstance | undefined) => { if (!formEl) return formEl.validate((valid) => { if (valid) { login(ruleForm).then((res: any) => { console.log("获取登录信息", res); //保存token localStorage.setItem("token", res.data.userInfo.token) ElNotification({ message: res.msg, type: 'success', }) //跳转 router.push('Home') }) } else { return false } }) } </script>
3.request/api.ts
//request/api.ts
import service from "./index";
// 登录
interface loginData {
username: string
password: string
}
export function login(params:loginData) {
return service(
{
url: '/user/login',
method: 'get',
params,
},
)
}
4.request/index.ts
import axios from 'axios'
import { ElNotification } from 'element-plus'
//创建axios实例
const service = axios.create({
baseURL: '/api',
timeout: 5000,
headers: { 'Content-Type': 'application/json;charset=utf-8' }
});
//请求拦截
service.interceptors.request.use((config) => {
config.headers = config.headers || {}
if (localStorage.getItem('token')) {
config.headers.token = localStorage.getItem('token') || ''
}
return config
})
//响应拦截
service.interceptors.response.use((res) => {
const code: number = res.data.code
if (code !== 200) {
ElNotification({
message: res.data.msg,
type: 'warning',
})
return Promise.reject(res.data)
}
return res.data
}, (error) => {
console.log(error)
})
export default service
5.解决跨域 vite.config.ts
import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import { resolve } from 'path' export default defineConfig({ plugins: [vue()], resolve: { alias: [ { find: '@', replacement: resolve(__dirname, "./src") } ] }, server: { // host设置为true才可以使用network的形式,以ip访问项目 host: true, // 自动打开浏览器 open: false, // 跨域设置允许 cors: true, // 如果端口已占用直接退出 strictPort: true, proxy: { '/api': { target: 'http://localhost:9991', changeOrigin: true, cookiePathRewrite: { '^/api': "/", method: 'post' }, rewrite: (path) => path.replace(/^\/api/, ""), } }, }, })