当前位置: 首页 > news >正文

Django_Vue3_ElementUI_Release_003_前端Vue3项目初始化

1. 概念扫盲

  1. Node.js是基于ChromeV8引擎,让JS在服务端运行的开发平台,就是JS的一种解释器
  2. WebPack就是模块打包机,把浏览器不能直接运行的拓展语言找到并打包为合适的格式给浏览器直接使用
  3. Vue基于WebPack构件项目的,并带有合理默认配置的,可以快速开发的完整系统
  4. npm就是JS的包管理工具

2. 环境准备

2.1 nodejs下载安装及配置

nodejs download

在这里插入图片描述

2.2 安装Vue脚手架

npm install -g @vue/cli

在这里插入图片描述

2.3 创建Vue3项目并运行

cd E:\project2024\shopping_carvue create shopping_car_forecd shopping_car_forenpm run serve

在这里插入图片描述
在这里插入图片描述

2.4 安装相关包

在这里插入图片描述

2.5 vue开发者必备vscode插件【2024最新】

在这里插入图片描述

https://blog.csdn.net/liyananweb/article/details/135958361

3. 一个小demo

3.1 public文件夹css,js等文件

在这里插入图片描述

3.2 index.html

<!DOCTYPE html>
<html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1.0"><!-- Favicon and Touch Icons--><link rel="shortcut icon" href="xxyy.ico"/><link rel="stylesheet" href="bootstrap.css"><title>数据平台</title></head><body><div id="app"></div><!-- Javascript Files --><script src="jquery-3.3.1.js"></script><script src="bootstrap.js"></script></body>
</html>

3.3 配置main.js

// 导入Vue
import { createApp } from 'vue'
// 导入Vue扩展插件
import axios from 'axios'
import VueAxios from 'vue-axios'
import { createRouter, createWebHistory } from 'vue-router'
// 导入组件
import App from './App.vue'
// import Product from './components/Product.vue'
import Signin from './components/Signin.vue'// 定义路由
const routes = [{ path: '/', component: Signin },// { path: '/product', component: Product },
]
// 创建路由对象
const router = createRouter({// 设置历史记录模式history: createWebHistory(),// routes: routes的缩写routes,
})
// 创建Vue对象
const app = createApp(App)
// 将路由对象绑定到Vue对象
app.use(router)
// 将vue-axios与axios关联并绑定到Vue对象
app.use(VueAxios,axios)
// 挂载使用Vue对象
app.mount('#app')

3.4 app.vue

<template><div id="app"><router-view/></div>
</template><script>
export default {name: 'App'
}
</script>

3.5 Signin.vue

<template><div class="main-layout card-bg-1"><div class="container d-flex flex-column"><div class="row no-gutters text-center align-items-center justify-content-center min-vh-100"><div class="col-12 col-md-6 col-lg-5 col-xl-4"><h1 class="font-weight-bold">用户登录</h1><p class="text-dark mb-3">民主、文明、和谐、自由、平等</p><div class="mb-3"><div class="form-group"><label for="username" class="sr-only">账号</label><input type="text" class="form-control form-control-md" id="username" placeholder="请输入账号"v-model="username"></div><div class="form-group"><label for="password" class="sr-only">密码</label><input type="password" class="form-control form-control-md" id="password"placeholder="请输入密码" v-model="password"></div><button class="btn btn-primary btn-lg btn-block text-uppercase font-weight-semibold" type="submit"@click="login()">登录</button></div></div></div></div></div>
</template><script>
export default {name: 'Signin',data () {return {username: '',password: ''}},methods: {login: function () {// 判断是否输入账号if (this.username.length > 0 && this.password.length > 0) {// 向后端发送POST请求let data = new FormData();data.append('username',this.username);data.append('password',this.password);this.axios.post('http://127.0.0.1:8000/', data).then((res)=> {// POST请求发送成功则获取响应结果的result// 如果result为true,则说明存在此用户if (res.data.result) {// 将访问路由chat,并设置参数this.$router.push({path: '/product'})} else {// 当前用户不存在后端的数据库window.alert('账号不存在或异常')// 清空用户输入的账号和密码this.username = ''this.password = ''}}).catch(function () {// PSOT请求发送失败window.alert('账号获取失败')// 清空用户输入的账号和密码this.username = ''this.password = ''})} else {// 提示没有输入账号或密码window.alert('请输入账号或密码')}}}
}
</script><style scoped>.text-center {text-align: center!important;}.min-vh-100 {min-height: 100vh!important;}.align-items-center {align-items: center!important;}.justify-content-center {justify-content: center!important;}.no-gutters {margin-right: 0;margin-left: 0;}.row {display: flex;flex-wrap: wrap;margin-right: -15px;margin-left: -15px;}*, :after, :before {box-sizing: border-box;}
</style>

3.6 如碰到报错

error Component name “index” should always be multi-word vue/multi-word-component-names

解决方案
其一、在项目的根目录找到vue.config.js文件,没有就新创建;
其二、需要添加的代码为:
在这里插入图片描述

3.7 运行效果

在这里插入图片描述

3.8 总结vue运行原理

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4. 正式开始项目

4.1 创建Vue3项目并运行

cd E:\project2024\shopping_carvue create shopping_car_forecd shopping_car_forenpm run serve

4.2配置vue.config.js

const path = require('path')
module.exports = {publicPath: '/',outputDir: 'dist',assetsDir: 'static',productionSourceMap: false,devServer: {hot: true,port: 8010,open: true,proxy: {'/': {target: 'http://127.0.0.1:8000/',changeOrigin: true,pathRewrite: { '^/': '' },},},},configureWebpack: {name: 'system',resolve: {alias: {"~@": __dirname,"@": path.resolve(__dirname, "./src")}}},
}

4.3 public文件夹中放入文件:css,js,img,layui

在这里插入图片描述

4.4 src文件夹中创建项目文件夹

axios:配置vue-axios
router:配置和定义Vue的路由信息
store:配置vuex,实现vue状态管理
sytle.css:编写异常页面的样式,仅在异常页面使用,因此不能放在public的css文件夹
在这里插入图片描述

4.4 配置Axios和Vuex

4.4.1 安装

npm i axios vue-axios

4.4.2 axios中创建index.js

import axios from 'axios'axios.defaults.baseURL = '/'  //设置HTTP请求地址
axios.defaults.headers.post["Content-Type"] = 'application/json' //设置POST请求的数据类型
axios.defaults.timeout = 60000 //设置HTTP请求超时,单位是毫秒
axios.defaults.withCredentials = true; //默认false,代表跨域请求不提供凭据export default axios

在这里插入图片描述

4.5 实现vue数据持久化

4.5.1 安装

npm i vuex vuex-persistedstate

在这里插入图片描述

4.5.2 store中创建index.js

在这里插入图片描述

import {createStore} from 'vuex'  //从Vuex导入函数createStore并实例化生成store对象
import createPersistedState from "vuex-persistedstate";const store = createStore({state: {  //设置Vuex需要保存的数据lookImgUrl: 'http://127.0.0.1:8000',username: '',last_login: ''},mutations: {  //修改参数state的数据,并且只能同步执行setUserName(state, username){state.username = username},setLastLogin(state, last_login){state.last_login = last_login},},actions: {}, // 解决参数mutations无法执行的异步问题modules: {}, // 用于模块化处理// 所有数据缓存到本地plugins: [createPersistedState()], //用于为Vuex引入插件
})
export default store

4.6 编写路由

4.6.1 安装vue-router

npm i vue-router

在这里插入图片描述

4.6.2 编写router/index.js

在这里插入图片描述

import {createRouter, createWebHashHistory} from 'vue-router'
// import Home from '../components/Home.vue'
// import Commodity from '../components/Commodity.vue'
// import Detail from '../components/Detail.vue'
// import Shopper from '../components/Shopper.vue'
import Login from '../components/Login.vue'
// import Shopcart from '../components/Shopcart.vue'
// import Error from '../components/Error.vue'// 定义路由
const routes = [// {path: '/', component: Home, meta: {title: '首页'}},// {path: '/commodity', component: Commodity, meta: {title: '商品列表页'}},// // :id是设置路由变量// {path: '/commodity/detail/:id', component: Detail, meta: {title: '商品详细页'}},// {path: '/shopper', component: Shopper, meta: {title: '个人中心页'}},{path: '/shopper/login', component: Login, meta: {title: '用户登录页'}},// {path: '/shopper/shopcart', component: Shopcart, meta: {title: '我的购物车'}},// // 路由匹配// {path: '/:pathMatch(.*)*', component: Error, meta: {title: '页面丢失'}},
]// 创建路由对象
const router = createRouter({// 设置历史记录模式history: createWebHashHistory(),// routes: routes的缩写routes,
})
export default router

4.7 编写组件

4.7.1 基础组件base.vue

<template><div class="header"><div class="headerLayout w1200"><div class="headerCon"><h1 class="mallLogo"><a href="/" title="首页"><img src="img/logo.png"></a></h1><div class="mallSearch"><div class="layui-form"><input type="text" v-model="search" required lay-verify="required" autocomplete="off"class="layui-input"placeholder="请输入需要的商品"><button class="layui-btn" lay-submit lay-filter="formDemo" @click="mySearch"><i class="layui-icon layui-icon-search"></i></button></div></div></div></div></div><div class="content content-nav-base" :class="activation"><div class="main-nav"><div class="inner-cont0"><div class="inner-cont1 w1200"><div class="inner-cont2"><router-link :to="`/`" :class="activation == '' ?'active':''">首页</router-link><router-link :to="`/commodity`" :class="activation == 'commodity' ?'active':''">所有商品</router-link><router-link :to="`/shopper/shopcart`" :class="activation == 'shopcart' ?'active':''">购物车</router-link><router-link :to="`/shopper`" :class="activation == 'shopper' ?'active':''">个人中心</router-link></div></div></div></div></div>
</template><script>export default {data() {return {search: ''}},props: {activation: {type: String,default: ''},},methods: {// 搜索商品mySearch: function () {this.$router.push({path: '/commodity', query: {search: this.search, page: 1}})},}}
</script><style scoped></style>

4.7.2 底边栏footer.vue

<template><div class="footer"><div class="ng-promise-box"><div class="ng-promise w1200"><p class="text"><a class="icon1" href="javascript:;">7天无理由退换货</a><a class="icon2" href="javascript:;">满99元全场免邮</a><a class="icon3" style="margin-right: 0" href="javascript:;">100%品质保证</a></p></div></div><div class="mod_help w1200"><p><a href="javascript:;">关于我们</a><span>|</span><a href="javascript:;">帮助中心</a><span>|</span><a href="javascript:;">售后服务</a><span>|</span><a href="javascript:;">母婴资讯</a><span>|</span><a href="javascript:;">关于货源</a></p></div></div>
</template><script>export default {name: "Footer"}
</script><style scoped></style>

4.8 实例化vue对象main.js

import { createApp } from 'vue'
import VueAxios from 'vue-axios'
import App from './App.vue'
import router from './router'
import store from './store'
import axios from './axios'
import base from './components/Base'
import footer from './components/Footer'// 创建Vue对象
const app = createApp(App)
// 注册组件
app.component('base-page', base)
app.component('footer-page', footer)
// 将路由对象绑定到Vue对象
app.use(router)
app.use(store)
// 将vue-axios与axios关联并绑定到Vue对象
app.use(VueAxios, axios)
// 挂载使用Vue对象
app.mount('#app')

4.9 根组件app.vue

<template><div id="app"><router-view/></div>
</template><script>
export default {name: 'App'
}
</script>

4.10 默认首页index.html

<!DOCTYPE html>
<html lang="zh-CN">
<head><title>母婴商城</title><link rel="stylesheet" type="text/css" href="<%= BASE_URL %>css/main.css"><link rel="icon" href="<%= BASE_URL %>favicon.ico"><link rel="stylesheet" type="text/css" href="<%= BASE_URL %>layui/css/layui.css"><script type="text/javascript" src="<%= BASE_URL %>layui/layui.js"></script>
</head>
<body><div id="app"></div></body>
</html>

4.11 业务组件

4.11.1 用户注册和登陆页面,login.vue

<template><base-page :activation="activation"></base-page><div class="login-bg"><div class="login-cont w1200"><div class="form-box"><div class="layui-form"><legend>手机号注册登录</legend><div class="layui-form-item"><div class="layui-inline iphone"><div class="layui-input-inline"><i class="layui-icon layui-icon-cellphone iphone-icon"></i><input name="username" id="username" v-model="username"lay-verify="required|phone" placeholder="请输入手机号"class="layui-input"></div></div><div class="layui-inline iphone"><div class="layui-input-inline"><i class="layui-icon layui-icon-password iphone-icon"></i><input id="password" type="password" v-model="password"name="password" lay-verify="required|password"placeholder="请输入密码" class="layui-input"></div></div></div><p>{{ msg }}</p><div class="layui-form-item login-btn"><div class="layui-input-block"><button class="layui-btn" lay-submit="" @click="loginAndRegister">注册/登录</button></div></div></div></div></div></div><footer-page></footer-page>
</template><script>export default {name: "Login",data() {return {activation: "login",msg: "",username: "",password: ""}},methods: {loginAndRegister: function () {console.log(this.username)console.log(this.password)this.axios.post('/api/v1/index/login/', {username: this.username, password: this.password}).then(response => {this.msg = response.data.msgif (response.data.state === 'success') {// 登录成功跳转个人主页this.$store.commit('setUserName',this.username)this.$store.commit('setLastLogin',response.data.last_login)console.log(this.state)this.$router.push({path: '/shopper'})}}).catch(function (error) {console.log(error)})}}}
</script><style scoped></style>

4.11.2 用户详情页面,shopper.vue

<template><base-page :activation="activation"></base-page><div class="info-list-box"><div class="info-list"><div class="item-box layui-clear"><div class="item"><div class="img"><img src="img/portrait.png"></div><div class="text"><h4>用户:{{ username }}</h4><p class="data">登录时间:{{ last_login }}</p><div class="left-nav"><div class="title"><router-link :to="`/shopper/shopcart`">我的购物车</router-link></div><div class="title" @click="logout"><a>退出登录</a></div></div></div></div><div class="item1"><div class="cart"><div class="cart-table-th"><div class="th th-items"><div class="th-inner">订单编号</div></div><div class="th th-price"><div class="th-inner">订单价格</div></div><div class="th th-amount"><div class="th-inner">购买时间</div></div><div class="th th-sum"><div class="th-inner">订单状态</div></div></div><div class="OrderList"><div class="order-content" id="list-cont"><ul class="item-contents layui-clear" v-for="(o, key) in orders" :key="key"><li class="th th-items">{{ o.id }}</li><li class="th th-price">¥{{ o.price }}</li><li class="th th-amount">{{ o.created }}</li><li class="th th-sum">{{ o.state }}</li></ul></div></div></div></div></div></div><div style="text-align: center;"><div class="layui-box layui-laypage layui-laypage-default" id="layui-laypage-1"><a href="javascript:;" class="layui-laypage-prev">上一页</a><a href="javascript:;">1</a><span class="layui-laypage-curr"><em class="layui-laypage-em"></em><em>2</em></span><a href="javascript:;">3</a><a href="javascript:;" class="layui-laypage-next">下一页</a></div></div></div>
</template><script>export default {name: "Shopper",data() {return {activation: 'shopper',orders: [{}],username: this.$store.state.username,last_login: this.$store.state.last_login,}},mounted: function () {if (this.$store.state.username === '') {this.$router.push({path: '/shopper/login'})}this.getcode(); //页面加载时自动执行},methods: {getcode: function () {var url = '/api/v1/shopper/home/'var href = window.location.href.split('?')[1]var t = new URLSearchParams('?' + href).get('t')if (t !== null){url += '?t=' + t}console.log(url)this.axios.get(url).then(response => {this.orders = response.data.data.ordersif (typeof(this.orders) == "undefined") {this.orders = [{}]}console.log(this.orders)}).catch(function (error) {console.log(error)})},logout: function () {this.axios.post('/api/v1/shopper/logout/').then(response => {if (response.data.state === 'success') {// 退出登录跳转个人主页this.$store.commit('setUserName','')this.$store.commit('setLastLogin','')console.log(this.state)this.$router.push({path: '/'})}}).catch(function (error) {console.log(error)})}},}</script><style scoped></style>

4.11.3 报错页面,error.vue

<template><nav><div class="menu"><p class="website_name">母婴商城</p></div>
</nav>
<div class="wrapper"><div class="container"><div id="scene" class="scene" data-hover-only="false"><div class="circle" data-depth="1.2"></div><div class="one" data-depth="0.9"><div class="content"><span class="piece"></span><span class="piece"></span><span class="piece"></span></div></div><div class="two" data-depth="0.60"><div class="content"><span class="piece"></span><span class="piece"></span><span class="piece"></span></div></div><div class="three" data-depth="0.40"><div class="content"><span class="piece"></span><span class="piece"></span><span class="piece"></span></div></div><p class="p404" data-depth="0.50">404</p><p class="p404" data-depth="0.10">404</p></div><div class="text"><article><button><router-link :to="`/`">返回首页</router-link></button></article></div></div>
</div>
</template><script>export default {name: "Error"}
</script><style src="@/assets/style.css" scoped>
</style>

4.12 测试页面

4.12.1 测试链接

http://localhost:8010/#/shopper/login

5. 常见报错

5.1 如果后台一直报错

“GET /ws HTTP/1.1”

则修改vue.config.js
在这里插入图片描述

5.2 后台接收不到数据

前端是这样的形式
在这里插入图片描述
报错要改成绿色方框的内容
在这里插入图片描述


http://www.mrgr.cn/news/28420.html

相关文章:

  • 游戏引擎学习第10天
  • java排序算法汇总
  • github和Visual Studio
  • ThriveX 博客管理系统前后端项目部署教程
  • Photoshop(PS)——人像磨皮
  • Yocto - 使用Yocto开发嵌入式Linux系统_13 创建定制层
  • 【系统架构设计师】软件架构的概念(经典习题)
  • shopify主题开发之template模板解析
  • 【JAVA干货店】带你玩转数组与递归
  • IAPP发布《2024年人工智能治理实践报告》
  • 算法题解:斐波那契数列(C语言)
  • 15. 三数之和(实际是双指针类型的题目)
  • 支持升降压型、升压、降压、60V的1.2MHz频率LED恒流驱动器LGS63040、LGS63042
  • C/C++实现植物大战僵尸(PVZ)(打地鼠版)
  • 配置cobbler服务提供centos7安装源
  • [OpenCV] 数字图像处理 C++ 学习——15像素重映射(cv::remap) 附完整代码
  • 初中生物--5.单细胞生物
  • 大数据新视界 --大数据大厂之MongoDB与大数据:灵活文档数据库的应用场景
  • 建设世界一流财务管理体系【数字化顶层设计】【持续更新】
  • 大学生看过来,必备4款写论文AI写作网站先稿后付
  • 【AI小项目5】使用 KerasNLP 对 Gemma 模型进行 LoRA 微调
  • 开题报告的流程
  • Go语言开发im-websocket服务和vue3+ts开发类似微信pc即时通讯
  • 背包问题(如何定义dp状态)
  • CSS调整背景
  • 绝缘检测原理