完整创建一个vite前端项目

目录

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">&nbsp;</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包。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/47531.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C#】| 与 及其相关例子

按位或&#xff08;|&#xff09; 按位或运算符 | 对两个数的每一位进行比较&#xff0c;如果两个数中至少有一个为 1&#xff0c;则结果位为 1&#xff1b;否则&#xff0c;结果位为0。 1010 (10 in decimal) | 1100 (12 in decimal) ------1110 (14 in decimal) 力扣相关…

【MySQL进阶之路 | 高级篇】EXPLAIN的进一步使用

1. EXPLAIN的四种输出格式 EXPLAIN可以输出四种格式&#xff1a;传统格式&#xff0c;JSON格式&#xff0c;TREE格式以及可视化输出。用户可以根据需要选择使用于自己的格式。 1). 传统格式 传统格式简单明了&#xff0c;输出是一个表格形式。 2). JSON格式 第一种格式中介…

面向对象练习题

代码&#xff1a; public class LL {public static void main(String[] args) { Teacher tnew Teacher("Mike",32,"前端页面",20000);Professor P new Professor("Jack",58,"嵌入式开发",20000);pro p new pro("Bob",34,&q…

【规范】小程序发布,『小程序隐私保护指引』填写指南

前言 &#x1f34a;缘由 『小程序隐私保护指引』小程序发布&#xff0c;每次都躲不开&#xff01; &#x1f3c0;事情起因&#xff1a; 最近在帮朋友弄一个小项目&#xff0c;uniappunicloud壁纸小程序。虽然之前做过不少小程序&#xff0c;但是每次发布正式版本时都有一步『…

WSL的安装

&#x1f3bc;个人主页&#xff1a;金灰 &#x1f60e;作者简介:一名简单的大一学生;易编橙终身成长社群的嘉宾.✨ 专注网络空间安全服务,期待与您的交流分享~ 感谢您的点赞、关注、评论、收藏、是对我最大的认可和支持&#xff01;❤️ &#x1f34a;易编橙终身成长社群&#…

网络初识和网络编程(Java版)

前言 网络已经成为我们日常生活中不可分割的一部分&#xff0c;我们每天都会从网络上得到各种各样的信息&#xff0c;我们也会在网络上传播各种各样的信息&#xff0c;可以说我们使用的软件都是依赖于网络的。作为一个程序猿&#xff0c;在我们未来部署的软件中&#xff0c;客…

【存储学习笔记】1:机械硬盘(Hard Drive Disk)结构和寻址方式

目录 HDD的结构HDD的寻址方式CHS寻址&#xff08;不适用于等密度结构磁盘&#xff09;LBA寻址&#xff08;目前普遍使用的线性寻址方式&#xff09; HDD的寻址速度 HDD的结构 盘面&#xff08;Platter&#xff09;&#xff1a;单面或者双面覆盖着用于记录数据的磁性物质&#x…

《昇思25天学习打卡营第25天|第23天》

今天是打卡的第二十三天&#xff0c;今天学习的是应用实践篇中的计算机视觉中FCN图像语义分割。 首先&#xff0c;是对全卷积网络&#xff08;FCN&#xff09;的简介&#xff0c;语义分割的简介&#xff0c;模型简介&#xff08;1、卷积化&#xff0c;2、上采样&#xff0c;3、…

51单片机嵌入式开发:15、STC89C52RC操作蜂鸣器实现一个music音乐播放器的音乐盒

STC89C52RC操作蜂鸣器实现一个music音乐播放器的音乐盒 1 概述2 蜂鸣器操作方法3 蜂鸣器发出音声4 硬件电路5 软件实现6 整体工程&#xff1a;7 总结 1 概述 要实现一个基于STC89C52RC单片机的音乐盒&#xff0c;可以按照以下步骤进行&#xff1a; &#xff08;1&#xff09;硬…

STM32项目分享:智能宠物喂食系统

目录 一、前言 二、项目简介 1.功能详解 2.主要器件 三、原理图设计 四、PCB硬件设计 1.PCB图 五、程序设计 六、实验效果 七、资料内容 项目分享 一、前言 项目成品图片&#xff1a; 哔哩哔哩视频链接&#xff1a; https://www.bilibili.com/video/BV1zy411z7…

关于对CSDN的谴责

关于对CSDN的谴责 如果不是心血来潮登了一次旧帐号我是万万不会想到&#xff0c;所有的文章都被设置成了仅VIP可见。 CSDN你的VIP有多不受人待见您不知道吗&#xff1f;为什么要把我用于你开通VIP刷绩效的工具&#xff1f; 这种东西不应该首先经过同意再开启吗&#xff1f;默认…

JavaWeb day01-HTML入门

Web前端 课程安排 HTML、CSS简介 HTML快速入门 实现标题排版 新闻标题样式

深度学习程序环境配置

深度学习环境配置 因为之前轻薄本没有显卡跑不起来&#xff0c;所以换了台电脑重新跑程序&#xff0c;故记录一下配置环境的步骤及常见错误 本人数学系&#xff0c;计算机部分知识比较匮乏&#xff0c;计算机专业同学可以略过部分内容 深度学习环境配置 深度学习环境配置 CUD…

MATLAB算法实战应用案例精讲-【数模应用】多元方差分析MANOVA(附MATLAB、python和R语言代码实现)

目录 知识储备 方差分析 一、单因素方差分析 二、双因素方差分析 三、多因素方差分析 四、事后多重比较 五、重复测量方差 六、协方差分析 七、多元方差分析 算法原理 多元方差分析的特点 多元方差分析的使用条件 应用案例 代码实现 MATLAB python R语言 知…

StringBuilder, Stringbuffer,StringJoiner

StringBuilder StringBuilder 代表可变字符串对象&#xff0c;相当于是一个容器&#xff0c;里面装的字符串是可以改变的&#xff0c;就是用来操作字符串的。 StringBuilder 比String更适合做字符串的修改操作&#xff0c;效率更高&#xff0c;代码更加的简洁。 public clas…

在结束的地方重新开始:十指之梢与新的轮回

一、前述 如果你想感受人潮汹涌&#xff0c;那么就请到大城市繁华街区的十字路口去看一看&#xff0c;尤其是节假日。 所以&#xff0c;交警对于城市交通的通畅&#xff0c;人们出行顺利的保障&#xff0c;是异常重要的。 交警&#xff0c;指挥交通有很多工具和方法&#xff0…

vscode 文件颜色变绿色

解决&#xff1a;关闭git功能 在设置中搜索Git:Enabled&#xff0c;取消Decorations: Enabled的勾选

04-用户画像+sqoop使用

优点 sqoop的作用是实现数据的导入和导出&#xff0c;主要是对数据库和数据仓库之间的操作 只要是支持jdbc连接的数据库都可以使用sqoop操作 添加Sqoop到环境变量中 export SQOOP_HOME/export/server/sqoop export PATH$PATH:$SQOOP_HOME/bin:$SQOOP_HOME/sbinsource /etc/…

嵌入式单片机软件与硬件的结合方法分析

不知道大家有没有疑惑,为什么软件能控制硬件?关于这个问题,给出直观解释的文章:本文分析STM32单片机到底是如何软硬件结合的,分析单片机程序如何编译,运行。 软硬件结合 初学者,通常有一个困惑,就是为什么软件能控制硬件?就像当年的51,为什么只要写P1=0X55,就可以…

Leetcode3212. 统计 X 和 Y 频数相等的子矩阵数量

Every day a Leetcode 题目来源&#xff1a;3212. 统计 X 和 Y 频数相等的子矩阵数量 解法1&#xff1a;二维前缀和 维护二维前缀和&#xff0c;分别统计 ‘X’ 和 ‘Y’ 的个数。 统计足以下条件的子矩阵数量&#xff1a; 包含 grid[0][0]‘X’ 和 ‘Y’ 的频数相等。至少…