vue实战项目-ego商城

搭建项目

提前cmd查一下vue -V查看vuecli的版本,我本来的版本太高跟这个教程完全对不上,所以重新下载了低版本的vuecli
从5.0.4降到3.11.0,因为elementUI只能支持到vuecli3的版本
低版本vuecli安装教程
在VScode里面直接输入vue create ego_cz即可,后面的ego_cz是项目名

但是一开始报错Error: command failed: npm install --loglevel error --legacy-peer-deps
后来发现需要用管理员身份打开IDEA才可以。
搭建项目过程就不讲了,有router和vuex就可以了。
创建好项目之后,cd ego_cz,进入自己的项目目录。
接下来去安装依赖
1.axios //npm install --save axios
2.element //vue add element 选择部份依赖即可
安装完依赖,直接去element官网,快速上手部分找到全部组件,用这些替换plugins目录下的element.js内容


里面全是vue2的写法,所以想用这个必须降低vuecli的版本号。唉,搞这个也搞半天。
之后执行npm run serve,查看能否正常进入vue展示页面,并且在中间有个el-button的按钮。这代表依赖都装好了。

页面搭建

views目录下是我们的页面文件,把里面的aboutview删掉以及component目录下的helloword都删掉。
注意:文件name设置不能使用简单的一个词,不然会报错,类似下图:

所以我把每个view文件后面都添加了View让其变得复杂。
首先在views目录下建立LayoutView.vue文件,作为整体的布局。
里面包含首页、产品管理、规格参数、广告分类四大子模块
因此我们为这四个模块建立了一个目录交main,首页就是HomeView.vue不用动,另外要在目录里创建三个文件
分别是:ProductView.vue,ParamsView.vue,ADCategory.vue
为了解决报错问题,我们要将与之前删掉的aboutbiew和helloword相关的文件内容都删掉,并且要改变router设置。

//App.vue
<template><div id="app"><router-view></router-view></div>
</template>
//LayoutView.vue
<template><div><!-- 登录界面 --><router-view></router-view></div>
</template><script>
export default {name:'LayoutView',
}
</script>
//ProductView.vue
<template><div>商品管理</div>
</template>
<script>
export default {name:'ProductView',
}
</script>

其他两个同理,先简单写出来,测试路由是否可行
接下来去解决路由问题,打开router里面的index.js,首先从文件中引入LayoutView,把本来的homeview改成我们的LayoutView,在给这个路径下面添加子模块路由。

//  src/router/index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import HomeView from '../views/main/HomeView.vue'
import LayoutView from '../views/LayoutView.vue'
Vue.use(VueRouter)const routes = [{path: '/',name: 'LayoutView',component: LayoutView,children: [//以下都是layout子元素{//path啥也不加进来的就是home这个页面path: '',name: 'Home',component:HomeView},{// 加上product就进入了产品页面path: 'product',name: 'ProductView',component:() => import('../views/main/ProductView.vue')},{path: 'params',name: 'ParamsView',component:() => import('../views/main/ParamsView.vue')},{path: 'ad',name: 'ADCategory',component:() => import('../views/main/ADCategory.vue')},]},
]

路由设置完成,运行路由加上path部分查看页面跳转。

为了实现基本的css
我们在assets下面新建css目录,在里面新建common.css文件

body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, form, fieldset, legend, input, textarea, button, p, blockquote, th, td
{margin: 0;padding: 0;}
body{text-align: center;}
li{ list-style: none;}
a{text-decoration: none;}
input,button,img{border: none}
.active{color:#409EFF
}

并且记得在main.js里面导入这个css文件

登录UI实现

路由限制(没有登陆时不得进入主页)

在router目录下建立permission.js

import router from "./index";   //引入路由对象  在index.js文件里面export default router
//用户未登录时,无法进入这个首页,所以要设置路由权限
router.beforeEach((to, from, next) => {if (to.meta.isLogin) {let token = false;if (token) {// 已经登陆直接进入next();} else {next({// 没有登陆就改变路由进入登录界面name:'LoginView'})}} else {next();}
})

在main.js里面添加引用

import './router/permission'

登录注册页面(写到同一个页面上)

在最外层写一层div确定登陆注册框大概位置,在里面写一层elementUI里面的card,并确定好其大小。
lang='less’会报错,npm安装依赖即可

//html部分
<template><!-- 登录注册界面,与Layout级别一样 --><div class="login"><el-card class="box-card"><!-- slot插槽,可以往里面填写想要的内容 --><div slot="header" class="clearfix"><span>Ego商城</span></div>内容部分</el-card></div>
</template>
//css样式
<style scoped lang='less'>
// lang=“less” 可以敲层级关系的样式
// scoped 使style内的样式只作用于当前的界面
.login{width: 1200px;margin:0 auto;.box-card{width: 500px;margin: 100px auto;}
}
</style>

希望能够展现出使用tab键更改登陆注册页面的功能,所以找到tabs标签页组件,将其写入内容部分。
因为tabs标签绑定了currentIndex代表当前页面对应内容,所以我们要在data里添加currentIndex,currentIndex是与name值绑定的,我们设其默认值为login,默认进入登录界面。

<template><!-- 登录注册界面,与Layout级别一样 --><div class="login"><el-card class="box-card"><!-- slot插槽,可以往里面填写想要的内容 --><div slot="header" class="clearfix"><span>Ego商城</span></div><el-tabs v-model="currentIndex" :stretch='true'><!-- 与name相对应,v-model双向绑定 --><el-tab-pane label="登录" name="login">登录</el-tab-pane><el-tab-pane label="注册" name="register">注册</el-tab-pane></el-tabs></el-card></div>
</template>data(){return{currentIndex:'login',}
}


往登录内容里面写入表单,从elementUI里面找表单即可。
把登陆内容改成如下内容
解释下表单的属性,model双向绑定LoginForm表单对象内容,rules代表对每个输入值的判定规则
status icon是表单后面的小叉号,不满足条件执行回调函数
ref是指的获取这个dom元素,点击提交时绑定的方法参数就是ref设定的值
prop设置的需要被校验的字段名

<el-form :model="LoginForm" :rules="rules" status-icon ref="LoginForm"><!-- ref与model绑定对象要是相同的 --><el-form-item label="用户名"  label-width="80px" prop="username"><!-- prop代表的是验证规则 --><el-input type="text" v-model="LoginForm.username"></el-input></el-form-item><el-form-item label="密码"  label-width="80px" prop="password"><el-input type="password" v-model="LoginForm.password"></el-input></el-form-item><el-form-item ><!-- 此处点击事件传的时ref的对象 --><el-button type="primary" @click="submitForm('LoginForm')">提交</el-button></el-form-item></el-form>

这其中不仅绑定了数据,也绑定了方法
具体用法如下
首先把LoginForm对象写入data内部

LoginForm:{password:'',username:'',},

写字段校验的方法:

// 用户名验证规则var validateUserName=(rule,value,callback)=>{if(value===''){callback(new Error('请输入用户名'));}else if(value.length<6){callback(new Error('用户名太短'))}else{callback();}}// 密码验证规则var validatePassWord=(rule,value,callback)=>{if(value===''){callback(new Error('请输入密码'));}else{callback();}}

将rules写入data,使得字段名对应自己的校验方法

rules:{//验证规则对应表示username:[{validator: validateUserName,trigger: 'blur'}],password:[{validator: validatePassWord,trigger: 'blur'}]}

最后在方法里面写入绑定的点击事件submitForm函数

submitForm(formName){this.$refs[formName].validate((valid)=>{if(valid){console.log(this.LoginForm);}else{return;}})}



注册UI实现与登陆相似
表单内容添加一个确认密码输入框,并为其添加确认密码验证规则

<el-form-item label="确认密码"  label-width="80px" prop="checkPassword"><el-input type="password" v-model="RegisterForm.checkPassword"></el-input></el-form-item>
//确认密码验证规则var checkPass=(rule,value,callback)=>{if(value===''){callback(new Error('请输入密码'));}else if(value !=this.RegisterForm.password){callback(new Error('两次输入密码不一致'))}else{callback();}}

rules部分添加确认密码的校验规则

rules:{//验证规则对应表示username:[{validator: validateUserName,trigger: 'blur'}],password:[{validator: validatePassWord,trigger: 'blur'}],checkPassword:[{validator: checkPass,trigger: 'blur'}]}

此时出现的问题是我们之前提交之后输出的都是登陆的信息,想要根据不同标签输出不同的对象值,需要在tabs标签上添加点击事件

<el-tabs v-model="currentIndex" :stretch='true' @tab-click="handleTabsClick">

用来获取当前处于哪个标签上
首先在data上添加一个activetabs变量,默认值设置为login,点击标签改变当前的标签值

handleTabsClick(tab){this.activeTab=tab.name}

对应的标签输出对应的对象值内容

submitForm(formName){this.$refs[formName].validate((valid)=>{if(valid){if(this.activeTab==='login'){console.log(this.LoginForm);}if(this.activeTab==='register'){console.log(this.RegisterForm)}}else{return;}})},

目前为止,登陆注册的前端页面已经基本实现

登录注册后台接口

小细节很多,注意不要出错
首先在ego目录下建立server目录,用来存放后台信息,与前端的src文件是独立开来的
里面建立三个文件,index(建立express对象,处理跨域及端口)、router(不同路由,调用不同方法)和config(连接数据库以及设置数据库操作方法)
事先需要安装好express、mysql、jsonwebtoken、cors、body-parse
直接使用npm install --save 依赖名

1.连接数据库(数据库里的表是直接导入进mysql的,所以不需要自己手写表格)

//config.js
//调用mysql
const mysql = require('mysql');
//连接数据
const client = mysql.createConnection({host: 'localhost',user: 'root',  //数据库用户名password: '1234',  //数据库密码database:'ego'   //数据库的名字
})// 传一个sql语句、arr数组参数以及回调函数
const sqlClient = (sql, arr, callback) => {client.query(sql, arr, (error, result) => {if (error) {console.log(error);return;} else {callback(result);// 没错就直接返回result值}})}
module.exports = sqlClient```
2.定义注册登录前后端交互方法```javascript
//router.js
const express = require('express');
const router = express.Router();
//引入数据库方法
const sqlClient = require('./config')
// 前端响应
const jwt=require('jsonwebtoken')// 注册
router.post('/register', (req, res) => {const { username, password, email } = req.body;const sql = 'insert into user values(null,?,?,?)';const arr = [username, password, email]sqlClient(sql, arr, result => {// result.affectedRows影响行数大于0则代表插入成功了if (result.affectedRows > 0) {res.send({status: 200,msg:'注册成功'})} else {res.send({status: 401,msg:'注册失败'})}})
})// 登录
router.post('/login', (req, res) => {const { username, password } = req.body;const sql = 'select * from user where username=? and password=?'const arr = [username, password];sqlClient(sql, arr, result => {if (result.length > 0) {//登陆成功获得tokenlet token = jwt.sign({username,id:result[0].id}, 'somekeys')res.send({status: 200,token,username})} else {res.send({status: 401,msg:'登陆失败'})}})
})
module.exports = router

3.调用express对象,应用路由、设置端口以及跨域处理

//index.js
// 引入express和app
const express = require('express');
const app = express();
// 引入跨域处理
const cors = require('cors');
// express获取post传参数据
const bodyParser = require('body-parser')
// 路由对象
const router = require('./router')app.use(cors());
app.use(bodyParser.urlencoded({extended:true
}))
// 前面添加/api就可以加载router,进行跨域了
app.use('/api', router);
//后端响应端口
app.listen(9090, () => {console.log(9090);
})

后端基本完成,为了使前后端可以同时运行
打开package.json,再scripts里面添加一句

"dev": "concurrently \"npm run serve\" \"nodemon server/index.js\""

这样我们在终端运行npm run dev就会同时运行前后端服务
后台接口基本完成

前后端交互

打开src,新建目录utils里面存放工具模块,新建request.js
直接复制来即可,使用axios发送请求

//request.js
// 网络请求
import axios from "axios"
import qs from "qs"
import router from "../router"
// import store from "../store"const toLogin = () =>{router.push("/login")
}const errorHandle = (status,info) =>{switch(status){case 400:console.log("服务器收到客户端通过PUT或者POST请求提交的表示,表示的格式正确,但服务器不懂它什么意思");toLogin();break;case 401:console.log("客户端试图对一个受保护的资源进行操作,却又没有提供正确的认证证书");toLogin();break;case 403:console.log("客户端请求的结构正确,但是服务器不想处理它");toLogin();break;case 404:console.log("资源被围定义(网络请求地址错误)");break;case 500:console.log("执行请求处理代码时遇到了异常,它们就发送此响应代码");break;case 503:console.log("最可能的原因是资源不足:服务器突然收到太多请求,以至于无法全部处理");break;default:console.log(info);break;}
}const instance = axios.create({timeout:5000
})instance.all = axios.all;
instance.spread = axios.spread
instance.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';instance.interceptors.request.use(config =>{if(config.method === 'post'){config.data = qs.stringify(config.data);}// 判断token是否存在,存在就添加到请求头上// const token = store.state.loginModule.user.token;// if(token){//     config.headers.authorization = store.state.loginModule.user.token;// }return config;},error => Promise.reject(error)
)instance.interceptors.response.use(response => response.status === 200 ? Promise.resolve(response) : Promise.reject(response) ,error =>{const { response } = error;if(response){errorHandle(response.status,response.data);return Promise.reject(response);}else{console.log("请求被中断");}}
)export function get(url,params){return new Promise((resolve,reject) =>{instance.get(url,{params}).then(res =>{resolve(res.data);}).catch(err =>{reject(err.data);})})
}export function post(url,params){return new Promise((resolve,reject) =>{instance.post(url,params).then(res =>{resolve(res.data)}).catch(err =>{reject(err.data)})})
}export default instance

打开登录注册页面,LoginView页面,引入api以及vuex
建立了vuex,在store下面建立modules目录,新建login.js

//login.js
// 写vuex结构
export default {namespaced: true,state: {user: {username: "",token:"",}},mutations: {setUser(state, user) {state.user=user}}
}

外面的index引入login

import Vue from 'vue'
import Vuex from 'vuex'
import login from './modules/login'Vue.use(Vuex)export default new Vuex.Store({modules: {login}
})

在LoginView界面引入api和vuex

import api from '../api'
import { mapMutations } from 'vuex'
methods: {...mapMutations('login',['setUser']),submitForm(formName){this.$refs[formName].validate((valid)=>{if(valid){if(this.activeTab==='login'){// 登录api.login(this.LoginForm).then(res => {if(res.data.status===200){this.setUser(res.data);localStorage.setItem('ego',JSON.stringify(res.data));// 登陆成功后跳转首页this.$router.push('/')}else{const h = this.$createElement;this.$notify({title:"登陆失败",message: h('i','用户名密码错误'),});}})}if(this.activeTab==='register'){// 注册api.register(this.RegisterForm).then(res =>{if(res.data.status ===200){const h = this.$createElement;this.$notify({title:'注册成功',message: h('i','请前往登陆页面登录'),});}else{const h = this.$createElement;this.$notify({title:'注册失败',message: h('i','请重新注册'),});}})}}else{return;}})},

解决强制刷新问题,登陆后再进入该界面需要直接跳转到主页,首先再utils里面新建init.js文件

// 解决强制刷新的问题,登陆后再进入页面直接跳转到主页面
import store from "@/store";if (localStorage.getItem('ego')) {store.commit('login/setUser',JSON.parse(localStorage.getItem('ego')))
}

在main里面引用这个init

import './utils/init'

router的permission里面改变token内容

import router from "./index";   //引入路由对象  在index.js文件里面export default router
//用户未登录时,无法进入这个首页,所以要设置路由权限
import store from '../store'router.beforeEach((to, from, next) => {if (to.meta.isLogin) {let token = store.state.login.user.token;if (token) {// 已经登陆直接进入next();} else {next({// 没有登陆就改变路由进入登录界面name:'LoginView'})}} else {next();}
})

到此为止登陆注册页面已经完成

vue实战项目-ego商城相关推荐

  1. 最新《Laravel5.4电商实战项目-联想商城》

    Laravel5.4电商实战项目-联想商城 官方付费地址:http://edu.51cto.com/course/10500.html 课程目标 本课程学习的目标是利用laravel框架做出一个电商项 ...

  2. 推荐一些vue实战项目

    好的,下面是一些推荐的 Vue 实战项目: 待办事项应用:这是一个简单的 Vue 项目,可以帮助你熟悉 Vue 的基础知识,并学习如何使用 Vue 实现增删改查功能. 电商网站:这是一个更复杂的 Vu ...

  3. Node+Vue实战项目

    一.Node+Vue实战项目 1.1 创建Node项目.Vue项目 mkdir classweb cd classweb/express servervue init webpack vueclien ...

  4. vue实战项目:电商管理系统实现步骤笔记(一)

    vue实战项目 视频地址以及项目文件 一.项目概述 1.1电商项目基本业务概述 1.2电商后台管理系统的功能 1.3电商后台管理系统的开发模式(前后端分离) 1.4电商后台管理系统的技术选型 1.4. ...

  5. android项目实战博学谷源码_Vue框架:史上最详细的Vue实战项目之喵喵电影(视频+源码)...

    Vue是web前端中重要的框架之一,与其他重量级框架不同的是,Vue 采用自底向上增量开发的设计,Vue 的核心库只关注视图层,并且非常容易学习,非常容易与其它库或已有项目整合.所以,对于web前端开 ...

  6. 高仿网易云音乐(vue实战项目)

    高仿网易云音乐(Vue实战项目)

  7. vue实战项目-电商商城前台-(学习尚硅谷的)尚品汇

    文章目录 最好使用视频上的账号密码,13700000000 密:111111 最新服务端接口地址:http://gmall-h5-api.atguigu.cn 脚手架使用 1.创建项目 2.脚手架默认 ...

  8. 初级项目vue实战项目 收银系统

    Vue实战视频-快餐店收银系统 (共11集) 2017-05-22 分类:Vue.js视频教程 / 视频教程 阅读(126832) 评论(136)  课程前言 这是我网站恢复后写的第一篇文章,在关站这 ...

  9. 【Vue 实战项目】后台管理系统登录页详解附源码

    提示:前端查漏补缺,仅代表个人观点. 文章目录 一.先看效果图 二.实战步骤 1. 创建项目 2. 引入库 3. 登录页关键代码 三.页面源代码 总结 提示:项目源代码除了登录页面还有动态路由 一.先 ...

  10. Vue实战项目个人总结

    根据网上别人提供的视频,我模仿着做了一个适用于手机端的电影网站,参考链接为: https://www.bilibili.com/video/BV1u4411Y7t4?p=5 开发项目流程 1.项目需求 ...

最新文章

  1. Win7下Event_Log服务4201错误的有效解决方法
  2. Windows XP任务管理器内进程名详解
  3. 四步相移法怎么获得相位信息_如何拥有超强的学习能力?世界公认的费曼学习法了解一下...
  4. Android 统一View样式,textview样式
  5. Python类属性访问的魔法方法
  6. 移动端报表JS开发示例
  7. react-native升级到0.63ios图片不展示
  8. java udp socket编程_JavaSocket编程UDP
  9. Qhsusb Dload驱动
  10. ansys 命令流基础—— 点线面体基本操作
  11. 树莓派 能干啥_大神们都用树莓派做了哪些事
  12. 生成arp报文的verilog实现
  13. 瑞幸的野望,小鹿茶的突袭
  14. 【MATLAB】绘制矢量场图
  15. 从零开始开发SSM项目-博客系统实战
  16. 苹果原壁纸高清_手机壁纸巨型神兽系列全面屏壁纸图片
  17. BW的登录错误解决实例
  18. Office-001 Word中如何插入章节Chapter?
  19. AToken每日简讯 1.17 星期四
  20. 三国杀(1):VS2017 C/C++ lua tolua++ 编译 集成,及使用介绍

热门文章

  1. ionic html5 上传图片,ionic文件选择与ionic文件上传
  2. shc -f xxx.sh shc: invalid first line in scrip
  3. Trajan求割边,强连通分量
  4. plc程序调试的顺序
  5. 微信指纹支付设置java_微信指纹支付怎么设置?微信指纹支付设置方法介绍
  6. 毕业设计记录(二):基于VUE框架与ECharts和Axios技术结合的Web移动高校实验室管理系统设计与实现
  7. 安装ubuntu后没有windows启动项
  8. 关于easyx库中怎样贴出透明图片
  9. 从零开始学PCR技术(四):常见问题
  10. Gorm Model FindFirstWhere等查询函数的区别