目录
1.先创建一个vite项目
2.下载第三方依赖
① 安装路由vue-router
② 安装vuex全局数据管理
③ 安装element-plus
④ 安装element-plus图标
⑤ 安装axios发送请求
⑥ 完整main.js代码模板
3.开发组件
4.登陆页面开发用例
5. 完整项目代码
废话少说,直接上步骤!
1.先创建一个vite项目
2.下载第三方依赖
① 安装路由vue-router
-- 用于页面跳转切换
npm install vue-router
--安装完之后,在src创建router目录, 在router目录创建index.js文件
--创建完后,在index.js文件中导入以下模板
//vue-router配置文件 //1.从vue-router导入createRouter() 创建路由器对象 import { createRouter, createWebHistory, createWebHashHistory} from 'vue-router'//2.配置路由规则: 给组件绑定url const routes = [//默认路由{path:'/',//重定向redirect:'/index'},// 这是一个配置路由的示例{path: "/index",component: ()=>import('../views/index.vue'),name:'indexPage',children:[ //配置子级路径{// 这是resful风格的url写法path:'/infor/:id' , component: ()=>import('../views/information.vue'),name:'infor',},]},//配置404的组件{path:'/:pathMatch(.*)*', component: ()=>import('../views/NotFound.vue'),name:'notFound',} ];//3.创建路由器对象 const router = createRouter({routes, //路由规则history: createWebHashHistory(),linkActiveClass:'active'}); //4. 把路由器对象暴露出去 其他组件文件,导入 export default router;
--最后找到main.js文件,并在里面配置router
② 安装vuex全局数据管理
--通过命令安装vuex
npm install vuex
--安装完成后,在src目录下创建store目录, 在store目录创建一个index.js
--然后再index.js文件中导入以下模板,用于配置全局数据
// 导入函数 import { createStore } from "vuex";// 定义一个状态 const state = {count:0,user:{id:0,username:'张三',age:13} }// 修改状态的函数集合 , 不能异步调用 const mutations = {addCount(state,payload){// 修改state里面的count状态state.count+=payload.num ; } }// actons : 操作集合(定义事件,让组件触发事件) const actions = {increment(context,payload){// 发送ajax请求,异步通信// 它只能调用mutations里面的方法才能修改数据,三个核心对象各司其职(主要是因为mutation不能异步调用,而actions可以,所以我们用actions去调用mutations)context.commit('addCount' , payload)} }// 调用createStore创建Store对象 const store = createStore({state , mutations,actions })// 暴露store对象 export default store //把它挂在到mian.js中去,就可以全局使用它
--最后在main.js文件里面配置store
③ 安装element-plus
--使用命令安装element-plus
npm install element-plus
-- 然后在main.js文件中配置
④ 安装element-plus图标
--命令行安装
npm install @element-plus/icons-vue
--在main.js配置
import * as ElementPlusIconsVue from '@element-plus/icons-vue'for (const [key, component] of Object.entries(ElementPlusIconsVue)) {app.component(key, component) }
⑤ 安装axios发送请求
--使用命令安装axios和qs
npm install axiosnpm install qs
-- 在src目录创建一个http目录, 创建两个文件
--一个是 axios实例配置文件: config.js
并且在里面配置如下模板:
//axios的配置文件 export default {method: 'get',// 基础url前缀baseUrl: 'http://localhost:8080',// 请求头信息headers: {//默认的请求context-type: application/json'Content-Type': 'application/json;charset=UTF-8'},// 参数data: {},// 设置超时时间timeout: 10000,// 携带凭证 是否携带cookiewithCredentials: true,// 返回数据类型responseType: 'json'}
--另外一个封装axios 工具库的文件 request.js
并且在里面配置如下模板:
import { ElLoading,ElMessage } from 'element-plus' import axios from 'axios' import qs from 'qs' //把json进行序列化成key/value import config from './config' import $router from '../router'const instance = axios.create({baseURL: config.baseUrl,headers: config.headers,timeout: config.timeout,withCredentials: config.withCredentials}) // request 拦截器 instance.interceptors.request.use(config => {let token = sessionStorage.getItem("token");// 带上tokenif (token) {config.headers.token = token}return config});const request = async function (loadtip, query) {let loadingif (loadtip) {loading = ElLoading.service({lock: true,text: '正在加载...',background: 'rgba(0, 0, 0, 0.7)',})}const res = await instance.request(query)if (loadtip) {loading.close()}if (res.data.meta.status === 401) {//ElMessage.error();$router.push({ path: '/login' })return Promise.reject(res.data) //reject() catch捕获} else if (res.data.meta.status === 500) {return Promise.reject(res.data)} else if (res.data.meta.status === 501) {return Promise.reject(res.data)} else if (res.data.meta.status === 502) {$router.push({ path: '/login' })return Promise.reject(res.data)} else {return Promise.resolve(res.data) // then()}/*.catch(e => {if (loadtip) {loading.close()}return Promise.reject(e.msg)})*/ } const get = function (url, params) {const query = {url: url,method: 'get',withCredentials: true,timeout: 30000,params: params, //params: queryStringheaders: { 'request-ajax': true }}return request(false, query) } const post = function (url, params) {const query = {url: url,method: 'post',withCredentials: true,timeout: 30000,data: params, //请求体headers: { 'Content-Type': 'application/json', 'request-ajax': true }}return request(false, query) } const postWithLoadTip = function (url, params) {const query = {url: url,method: 'post',withCredentials: true,timeout: 30000,data: params,headers: { 'Content-Type': 'application/json', 'request-ajax': true }}return request(true, query) } const postWithOutLoadTip = function (url, params) {const query = {url: url,method: 'post',withCredentials: true,timeout: 30000,data: params,headers: { 'Content-Type': 'application/json', 'request-ajax': true }}return request(false, query) } const postWithUrlEncoded = function (url, params) {const query = {url: url,method: 'post',withCredentials: true,timeout: 30000,data: qs.stringify(params), //params:json qs.stringify(json) --> 转换key/valueheaders: { 'Content-Type': 'application/x-www-form-urlencoded', 'request-ajax': true }}return request(false, query) }const del = function (url, params) {const query = {url: url,method: 'DELETE',withCredentials: true,timeout: 30000,data: params,headers: { 'Content-Type': 'application/json', 'request-ajax': true }}return request(true, query) } const put = function (url, params) {const query = {url: url,method: 'PUT',withCredentials: true,timeout: 30000,data: params,headers: { 'Content-Type': 'application/json', 'request-ajax': true }}return request(true, query) }const form = function (url, params) {const query = {url: url,method: 'post',withCredentials: true,timeout: 30000,data: params,headers: { 'Content-Type': 'multipart/form-data', 'request-ajax': true }}return request(false, query) }export default {post,postWithLoadTip,postWithOutLoadTip,postWithUrlEncoded,get,form,del,put }
--最后在在main.js配置request.js文件
⑥ 完整main.js代码模板
import { createApp } from 'vue' import './style.css' import App from './App.vue' const app = createApp(App) // 配置路由 import router from './router' app.use(router) // 配置vuex import store from './store' app.use(store) // 配置element-plus import ElementPlus from 'element-plus' import '../node_modules/element-plus/dist/index.css' app.use(ElementPlus) // 配置element-plus图标 import * as ElementPlusIconsVue from '../node_modules/@element-plus/icons-vue' for (const [key, component] of Object.entries(ElementPlusIconsVue)) {createApp(App).component(key, component) } // 配置axios import $http from './http/request.js' app.config.globalProperties.$http = $http // 注册一个全局路由守卫 router.beforeEach((to, from) => {console.log("to:"+to)return true });app.mount('#app')
3.开发组件
组件分类:
局部功能组件: 放在src/components目录下面
页面/视图组件: 放在src/views(pages)目录下面
组合式api获取相关对象:
--组合式不能用this得到当前对象,只能导入。
// router route //第一步 从vue-router导入 useRoute() useRouter() import { useRoute, useRouter } from 'vue-router' //第二步: 调用函数useRouter() 得到router //得到路由对象 const router = useRouter();//store对象 //第一步 从vuex导入 useStore() import {useStore} from 'vuex' //第二步:调用useStore得到store对象 const store = useStore();
4.登陆页面开发用例
① 登录页面开发: Login.vue
<template><div class="login"><div class="login-context"><!--头部图片--><div class="login-logo"><img src="../assets/vue.svg" alt=""></div><!--form表单--><el-form :model="loginForm" :rules="loginFormRul" ref="loginFormRef" label-width="100px" class="login-box"><el-form-item label="用户名:" prop="username"><el-input v-model="loginForm.username"></el-input></el-form-item><el-form-item label="密码:" prop="password"><el-input type="password" v-model="loginForm.password"></el-input></el-form-item><el-form-item><el-col :span="12"><el-form-item prop="captcha"><el-input type="test" v-model="loginForm.captcha" auto-complete="off"placeholder="验证码, 单击图片刷新" style="width: 100%;"></el-input></el-form-item></el-col><el-col class="line" :span="1"> </el-col><el-col :span="11"><el-form-item><img style="width: 100%;" class="pointer" :src="src" @click="refreshCaptcha"></el-form-item></el-col></el-form-item><el-form-item class="login-btn"><el-button type="primary" @click="login(loginFormRef)">登录</el-button><el-button @click="reset(loginFormRef)">重置</el-button></el-form-item></el-form></div></div> </template> <script setup> import { ElMessage } from 'element-plus' import { ref, reactive ,getCurrentInstance } from 'vue' import { useRoute, useRouter } from 'vue-router' import {useStore} from 'vuex' const store = useStore(); const loginForm = reactive({username: '',password: '',captcha: '', }); const src = ref(''); //得到form对象 const loginFormRef = ref();//验证规则 const loginFormRul = reactive({username: [{ required: true, message: '请输入用户名', trigger: 'blur' },{ min: 2, max: 8, message: '长度在 2 到 8 个字符', trigger: 'blur' }],password: [{ required: true, message: '请输入密码', trigger: 'blur' },{ min: 3, max: 8, message: '长度在 3 到 8 个字符', trigger: 'blur' }],captcha: [{ required: true, message: '请输入验证码', trigger: 'blur' }] });//得到路由对象 const router = useRouter();//获取当前组件实例对象 const app = getCurrentInstance(); //获取app上的globalProperties属性 const $http = reactive(app.appContext.config.globalProperties.$http); //登录功能 function login(form) {if(!form) return;//提交表单之前进行表单验证form.validate((valid) => {//校验失败if (!valid) return;//校验成功$http.post('login', loginForm).then((response) => {ElMessage({showClose: true,message: '登录成功',type: 'success',})//状态保存下来window.sessionStorage.setItem("token", response.data);//跳转router.push('/users');}).catch((error) => {ElMessage({showClose: true,message: error.meta.msg,type: 'error',});//清空表单form.resetFields();});});}//重置功能 function reset(form) {if (!form) returnform.resetFields(); }//刷新验证码 function refreshCaptcha() {//防止浏览器缓存src.value = "http://localhost:8080/captcha.jpg?t=" + new Date().getTime(); } //调用这个函数显示验证码 refreshCaptcha(); </script><style scoped> .login {height: 100%;background: rgb(43 75 107); }.login-context {width: 450px;height: 300px;background: #fff;position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);box-shadow: 0 0 3px 2px #DDD;border-radius: 10px; }.login-logo {width: 150px;height: 150px;position: absolute;top: -80px;left: 50%;margin-left: -75px;border: 1px solid #eee;border-radius: 50%;background-color: #fff;padding: 10px;box-shadow: 0 0 3px 2px #fff; }.login-logo img {width: 100%;height: 100%;border-radius: 50%;background-color: rgb(238, 238, 238); }.login-box {width: 100%;position: absolute;bottom: 0;padding: 0 20px;box-sizing: border-box; }.login-btn {display: flex;justify-content: flex-end; } </style>
② 在router/index.js文件中配置这个路由
const routes = [{path:'/login',component:()=>import('../views/Login.vue'),name:'Login'},{path:'/',redirect:'/login'} ];
③ 修改APP.vue页面
<script setup></script><template><router-view/> </template><style scoped></style>
④ 运行项目
npm run dev
⑤ 运行页面效果展示
5. 完整项目代码
完整的项目代码我放在的我的资源《创建一个完整vite前端项目》打包成jar包。