欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 产业 > Django_Vue3_ElementUI_Release_003_前端Vue3项目初始化

Django_Vue3_ElementUI_Release_003_前端Vue3项目初始化

2024/11/30 15:39:53 来源:https://blog.csdn.net/geji001/article/details/142280507  浏览:    关键词: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 后台接收不到数据

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

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com