vue电商实战-黑马-01

文章目录

  • 项目概述
      • 1.电商系统基本业务概述
      • 2.电商系统后台管理系统的功能划分
      • 3项目的开发模式及技术选型
  • 项目初始化
      • 前端项目初始化
      • 后端项目的环境安装配置
  • 登录、退出功能
      • 登录概述
      • 表单验证
      • 路由守卫
      • 退出
      • 语法格式化
  • 主页布局
      • header:
      • menu:
      • 用户、角色、权限
      • 商品管理-参数管理

b站: https://www.bilibili.com/video/BV1bE411p7As?p=2

项目概述

1.电商系统基本业务概述

电商系统一般都提供了:pc端、移动app端、移动web端、微信小程序等多种终端访问方式。
eg:京东:
1.pc端:https://www.jd.com/
2.移动web:https://m.jd.com/ (手机浏览器打开京东网站)
3.app:
4.小程序:
5.pc后台管理:后台管理员使用的,使我们准备学习的。

2.电商系统后台管理系统的功能划分

vue电商实战-黑马-01_第1张图片

3项目的开发模式及技术选型

电商后台管理系统整体采用前后端分离的开发模式,其中前端项目是基于Vue技术栈的SPA项目。

后端:主要操作数据库,并向前端暴露一些api接口。
前端:绘制页面,并通过ajax调用api接口。

技术选型:

  • 前端技术栈:
    Vue
    Vue-router
    Element-UI
    Axios
    Echarts

  • 后端技术栈
    Node.js
    Express
    Jwt:状态保持的一个工具,模拟session的一个登陆记录功能。
    Mysql:数据库
    Sequelize:操作数据库的一个框架。

项目初始化

前端项目初始化

1.vue-cli
2.通过cli创建项目
3.配置路由
4.配置Element-UI
5.配置Axios
6.初始化git远程仓库
7.托管项目到Github或者码云中

vue及cli的版本查看:

  • vue版本查看:
npm list vue // 进入项目中,使用这个命令

或者:进入项目中package.json文件直接查看

  • vue/cli版本查看:
vue -V  // 查看cli的版本,不是vue的版本  vue --version

npm uninstall vue-cli -g  // 卸载cli-2.x
npm install @vue/cli -g // 安装cli-3.x

项目地址:https://github.com/ly1994lyy/Vue_Element_ShopManage

我是使用的版本:

@vue/cli 4.2.2 
vue@2.6.11
vue ui

vue电商实战-黑马-01_第2张图片

vue电商实战-黑马-01_第3张图片

手动配置

1.babel和linter/formatter默认是选中的,那么必须安装的。
2.选择router,使用配置文件,下一步(选的比较少)

1.选择模式:hash还是history的,我们用hash的(兼容性更强,所以关闭状态),
2.linter/formatter使用standard的,
3.lint on save // 保存后,就格式化文件

  • 安装element-ui(在ui界面)- 插件中:
    vue电商实战-黑马-01_第4张图片

搜索:element,
结果:vue-cli-plugin-element 1.0.1 安装即可,安装完成后需要配置一下:

vue电商实战-黑马-01_第5张图片

按需导入:import on demand

  • 安装axios - UI界面- 在依赖中:
    安装依赖,
    vue电商实战-黑马-01_第6张图片
    启动项目:(运行成功后,启动app)
    vue电商实战-黑马-01_第7张图片

  • 码云

https://gitee.com/
注册登录后,是要配置公钥的。
vue电商实战-黑马-01_第8张图片

vue电商实战-黑马-01_第9张图片

vue电商实战-黑马-01_第10张图片

生成公钥:ssh-keygen -t rsa -C "[email protected]",替换为自己码云的邮箱(自己去设置中找去:基本设置-多邮箱管理)
路径:/Users/likaipeng/.ssh/id_rsa
查看文件内容:cat ~/.ssh/id_rsa.pub // cat就有权限查看了,根sodu很像。

复制内容到公钥中即可(码云后面的描述不正确)。

ssh -T git@gitee.com  // 添加信任

mac使用:
查找文件路径:
拖拽文件到terminal中,会显示文件路径。
command+shift+g:跳转到地址的快捷键。

创建仓库:

注:使用readme文件初始化这个仓库 ,一定不要选中。

// Git 全局设置:

git config --global user.name "神zhi殇"
git config --global user.email "[email protected]"


// 本地没有项目的时候:创建 git 仓库:
mkdir vue_admin
cd vue_admin
git init
touch README.md
git add README.md
git commit -m "first commit"
git remote add origin https://gitee.com/lkp_ksbk/vue_admin.git
git push -u origin master

// 本地已经通过cli生成项目的:已有仓库
cd existing_git_repo
git remote add origin https://gitee.com/lkp_ksbk/vue_admin.git
git push -u origin master

后端项目的环境安装配置

1.安装MySQL数据库
2.安装Node.js环境
3.配置项目相关信息
4.启动项目
5.使用Postman测试后端项目接口是否正常

1.初始化mySql。
2.启动node。
3.使用postman验证接口是否成功。

phpStudy没有mac版本的。

// node项目:
npm install 
node app.js

登录、退出功能

登录概述

登录业务流程
1.登录,2.调接口验证,3.根据响应状态跳转到页面,

登录业务的技术点:
1.http是无状态的。登录成功后,需要记录登录的状态。cookie、session方式,token方式。
2.通过cookie在客户端记录状态。
3.通过session在服务端记录状态。
4.通过token方式维持状态。

什么情况下用cookie和session,什么情况下用token???

  • 前后端不存在跨域问题的时候,用cookie和session。
  • 前后端存在跨域问题,使用token方式。

vue电商实战-黑马-01_第11张图片

登录页面:

  • 语法错误vscode报一堆错误:
error  Trailing spaces not allowed     no-trailing-spaces // 空对象,不用有空行
Too many blank lines at the end of file. Max of 0 allowed  no-multiple-empty-lines // 文件结尾不能太多空行,只能有一个

Strings must use singlequote  quotes // 都是用单引号(vscode,搜索singlequote,修改为单引号,格式化后就ok了)

error  Extra semicolon  semi  // 结尾有分号,那么报错;vscode,搜索semi,修改为结尾不用分号,格式化后就ok了)
  • 路由报错:
vue-router.esm.js?8c4f:16 [vue-router] Non-nested routes must include a leading slash character. Fix the following routes: 
- login

注:非嵌套路由必须包含前导斜杠字符

vue电商实战-黑马-01_第12张图片

  • css解析错误
Error: Can't resolve 'less-loader' 

UI视图中:开发依赖中安装less和less-loader,然后重启项目。
vue电商实战-黑马-01_第13张图片

全局样式:
src/assets/css/global.css,在main.js中import后,可以生效。

  • element-ui 报错
[Vue warn]: Unknown custom element: <el-form> - did you register the component correctly? For recursive components, make sure to provide the "name" option.

按需导入的,所以要自己加组件。

imported multiple times  import/no-duplicates

// error, eg:
import { Button } from 'element-ui'
import { Form, FormItem } from 'element-ui'
import { Input } from 'element-ui'

// ok
import { Button, Form, FormItem, Input } from 'element-ui'

iconfont的使用:
src/assets/fonts/iconfont.css,直接在main.js中引用即可。

// fonts文件直接全部复制粘贴在assets下面。
import './assets/fonts/iconfont.css'
data() {} // data后面没有空格,语法报错。

// 错误信息
Missing space before function parentheses  space-before-function-paren

// 解决:
// 1.id方式,js的:
javascript.format.insertSpaceBeforeFunctionParenthesis

// 2.json方式,ts的:
"typescript.format.insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": false

el-form绑定数据:

//  // :model
<el-form label-width="0px" class="login_form" :model="loginForm">

  <el-form-item>
    <el-input
      v-model="loginForm.username"
      placeholder="请输入账号"
      prefix-icon="iconfont icon-user"
    ></el-input>
  </el-form-item>
  
  <el-form-item>
    <el-input
    type="password"
      v-model="loginForm.password"
      placeholder="请输入密码"
      prefix-icon="iconfont icon-3702mima"
    ></el-input>
  </el-form-item>
  
  <el-form-item class="btns">
    <el-button type="primary">登录</el-button>
    <el-button type="info">重置</el-button>
  </el-form-item>
  
</el-form>

表单验证

  • 表单验证:参考项目。
    1.表单绑定rules。:rules="loginRules"
    2.编写rules规则。
    3.el-form-item增加prop属性。rop="username"

  • 重置表单数据:参考项目。
    1.el-form添加一个ref引用(eg:loginFormRef)。
    2.使用:this.$refs.loginFormRef.resetFields()。resetFields是 form中的methods。

  • 提交前的校验(表单预验证)

this.$refs.loginFormRef.validate((valid) => {
  console.log(valid)
})

validate是 form中的methods。

  • 请求数据
    axios安装包了,但是还没配置。
// main.js中:
import axios from 'axios' // 引入包
axios.defaults.baseURL = 'http://127.0.0.1:8888/api/private/v1/' // 设置根路径
Vue.prototype.$http = axios // 挂载到原型对象上,使用:this.$http
  • 接口的处理
const result = this.$http.post('login', this.loginForm)
console.log(result) // result返回是Promise。

如果方法返回值是promise,可以使用async和await方法来简化这次promise操作。
await只能用在被async修饰的方法中。

// 箭头函数修饰为异步函数,返回值为await。
this.$refs.loginFormRef.validate(async valid => {
  console.log(valid) // 返回false,验证不通过;返回true,调用登录接口
  if (!valid) return false
  const result = await this.$http.post('login', this.loginForm)
  console.log(result) // {data:{},config:{},headers:{},request:{},status:200,statusText:'OK'}
})

返回的result是一个axios修饰过的对象,我们只要data就好了。所以,结构赋值:

const { data: res } = await this.$http.post('login', this.loginForm)
console.log(res) // res就是data(我们想要的数据)

注:async和await
解构赋值

message的使用:

// main.js
import { Message } from 'element-ui'
Vue.prototype.$message = Message

// 使用:
this.$message.error('登录了要')

登录后,token存储在客户端,存在session中,然后跳转到home页面。

sessionStorage.setItem('token', '123abc')
window.sessionStorage.setItem('token', '123abc')

文件最后一行是newLine:

"files.insertFinalNewline": true

路由守卫

全局前置守卫:

router.beforeEach((to, from, next) => {
  console.log(to) // 要访问的路径
  console.log(from) // 从哪个路径来的额
  next() // next();放行。next('/login');强制跳转。
})

退出

语法格式化

根目录下新建.prettierrc文件,这是一个json格式的配置文件:

{
  "semi": false, // 末尾不加分号
  "singleQuote": true // 使用单引号
}

禁用部分语法规则,eg:

logout() {} // logout与括号之间没有空格,但是也会报错,eg:

Missing space before function parentheses  space-before-function-paren

复制:space-before-function-paren,在.eslintrc.js中,rules:

'space-before-function-paren':0

重新编译后,就ok了。

element-ui,按需导入的时候,import语句合并。

主页布局

header:

Container布局容器,参考项目。

menu:

  • 布局和样式:菜单树,NavMenu导航菜单,参考项目。
  • 请求数据
    通过axios请求拦截器添加token。
// axios请求拦截
axios.interceptors.request.use(config => {
  console.log(config) // {baseURL:'xxx',data:{},headers:{},method:'post'}
  // 为请求头对象,添加Token验证的Authorization
  config.headers.Authorization = window.sessionStorage.getItem('token')
  return config // 最后必须return config
})

baseURL:是自己配置的。
data:接口的body。
header:头部信息。

注:
1.路由守卫:token
2.拦截器:token

调用菜单接口(异步及结构赋值):

methods: {
  async getMenuList () {
    const { data: res } = await this.$http.get('menus')
    if (res.meta.status !== 200) return this.$message.error(res.meta.msg)
    this.menuList = res.data
    console.log(res)
  }
},

问题:
1.vscode:console.log的快捷键
2.复制了一个菜单list在vue中,但是语法报错,且太多报错,不能挨个解决,怎么办?
3.

设置代码片段:
首选项->用户代码判断->javascript,设置(有一个默认注释的example):

"Print to console": {
  "prefix": ".log",
  "body": [
    "console.log('$1')$2"
  ],
  "description": "Log output to console"
}

// .log是快捷键,迅速调到$1,且有引号,tab后,调到$2,没加引号。

如果太多错误,不想解决了的话:

You may use special comments to disable some warnings.
1.Use // eslint-disable-next-line to ignore the next line.
2.Use /* eslint-disable */ to ignore all warnings in a file. 

修改菜单的icon:
接口没有返回,怎么改icon呢?
1.可以直接使用iconfont的图标。
2.使用一个对象,根据id匹配icon。

<i :class="icnosObj[item.id]"></i>

icnosObj: {
  125: 'iconfont icon-users',
  103: 'iconfont icon-tijikongjian',
  101: 'iconfont icon-danju',
  102: 'iconfont icon-shangpin',
  145: 'iconfont icon-baobiao',
}

菜单默认只能展开一个,其他的关闭:

// el-menu加一条属性:
unique-opened='true'

菜单默认右多1px:

.el-menu {
    border-right: solid 1px #e6e6e6; // 去掉border即可。
}

折叠和展开菜单的问题:
el-menucollapse属性可以控制.
折叠动画可以关闭掉:collapse-transition

路由重定向:

  {
    path: '/home',
    component: Home,
    redirect: '/welcome', // 显示路由:/welcome;显示/home重定向到了/welcome
    children: [
      { path: '/welcome', component: Welcome }
      // { path: '/', redirect: 'welcome' } // 显示路由:/home/welcome
    ]
  }

菜单开启路由模式:

       <el-menu
          unique-opened="true"
          background-color="#333744"
          text-color="#fff"
          active-text-color="#409eff"
          :collapse="isCollapse"
          :collapse-transition="false"
          router
        >
// router:相当于:`:router="true"`,index就是跳转地址。
  • 菜单高亮:default-active 当前激活菜单的 index
:default-active="activePath"
  • card的使用(带box-shadow的):
<el-card class="box-card">
      123
</el-card>
  • table的使用
<el-table-column label="状态">
  // 作用域插槽,scope.row:当前行数据的所有内容
  <template slot-scope="scope">
    {{scope.row}}
  </template>
</el-table-column>
<el-table-column label="状态">
  // 作用域插槽
  <template slot-scope="scope">
    <el-switch v-model="scope.row.status" active-color="#13ce66" inactive-color="#ff4949"></el-switch>
  </template>
</el-table-column>

序号列:

<el-table-column type="index"></el-table-column>

tooltip划入消失:

enterable	// 鼠标是否可进入到 tooltip 中

vscode快捷键:
ctr+b:折叠目录栏

input的事件:

Input Events
事件名称	说明	                    回调参数
blur	在 Input 失去焦点时触发	(event: Event)
focus	在 Input 获得焦点时触发	(event: Event)
change	仅在输入框失去焦点或用户按下回车时触发	(value: string | number)
input	在 Input 值改变时触发	(value: string | number)
clear	在点击由 clearable 属性生成的清空按钮时触发

添加用户:

  • 自定义校验器
  • 弹框(事件)
  data () {
    // 校验邮箱
    var checkEmail = (rule, value, cb) => {
      var reg = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-])+/
      if (reg.test(value)) {
        return cb()
      }
      cb(new Error('请输入合法的邮箱'))
    }
    // 校验手机号
    var checkMobile = (rule, value, cb) => {
      var reg = /^1[34578]\d{9}$/
      if (reg.test(value)) {
        return cb()
      }
      cb(new Error('请输入合法的手机号'))
    }
    return {
      userList: [],
      total: 10
    }
  },

        email: [
          { required: true, message: '请输入邮箱', trigger: 'blur' },
          { validator: checkEmail, trigger: 'blur' }
        ],
Events
事件名称	说明	   回调参数
open	Dialog 打开的回调	—
opened	Dialog 打开动画结束时的回调	—
close	Dialog 关闭的回调	—
closed	Dialog 关闭动画结束时的回调	—

confirm的使用:
confirm返回是一个promise,可以使用async-await的方法。
确认的时候,返回:confirm(一个字符串)
但是cancel的时候,报错,所以需要一个catch方法,返回错误信息。


    async removeUserById (id) {
      const confirmResult = await this.$confirm('此操作将永久删除该用户,是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .catch(err => {
          return err
        })
        // .catch(err => err) // 去除{},然后省略return。
      console.log(confirmResult) // confirm || cancel
    }

提交新分支:

git push -u origin user

用户、角色、权限

vue电商实战-黑马-01_第14张图片
用户:登录的每一个账号
权限:账号拥有的能力,eg:列表的增、删、改、查的某个权限。
没有把权限直接绑定在用户上,而是通过角色。
权限分配给角色,然后角色分配给用户。

表格展开用:

<el-table-column type="expand"></el-table-column> // 展开列
<el-table-column type="index"></el-table-column> // 索引列

角色列表:
新增、编辑和删除功能跟用户列表一样,自己去做。

权限折叠显示:
1.先渲染一级菜单,然后修改样式(tag,border,右箭头icon)
2.渲染二级彩打,修改样式(tag,border,右箭头icon)
3.渲染三级
4.样式优化
4.1:页面加min-width
4.2:垂直居中对齐(el-row加flex布局样式)
5.删除后,刷新列表,但是会折叠住,体验不好;
删除后返回是最新权限的内容,直接替换是不是就可以了。

class类:

// 125: 'iconfont icon-users',
<i :class="icnosObj[item.id]"></i>
:class="['bdbottom',index1===0?'bdtop':'']"

tree的实现:
1.树渲染
2.改变label字段
3.checkbox
4.选中是id
5.折叠展开
6.默认选中的(回写)

// 代码
<!-- 树结构 -->
<el-tree
  :data="rightsList"
  :props="treeProps"
  show-checkbox
  node-key="id"
  default-expand-all
  default-checked-keys="defKeys"
></el-tree>
>
>
// 变量:默认选中的节点id值
defKeys: [105, 116]

// 错误信息
Invalid prop: type check failed for prop "defaultCheckedKeys". Expected Array, got String with value "defKeys".

如果树结构的数据使用一个,那么会有问题的:
树结构都是一样的(整个tree),所以准备请求一次,放在data中,那么每次关闭弹框后,重新打开弹框显示的还是之前的数据(checkbox选中状态的),哪怕我checked的list为空,都不行了。
解决方法:
1.每次弹框打开都重新赋值一次。
2.使用重新赋值checked的方法。

// 使用setCheckedKeys方法(element官网有使用方法)
this.$refs.rightsTree.setCheckedKeys(this.defKeys) 

// 获取节点:
this.$refs.tree.getCheckedNodes() // 有参数,是否只获取leaf节点
this.$refs.tree.getCheckedKeys() // 有参数,是否只获取leaf节点

商品分类,eg:
1.一级分类:家用电器
2.二级分类:电视、空调、洗衣机、等
3.三级分类:

  • 曲面电视,超薄电视,OLED电视,55英寸,65英寸
  • 中央空调,悬挂式空调,柜式空调
  • 洗衣机一体机,滚筒洗衣机,烘干机

vue电商实战-黑马-01_第15张图片

git push -u origin goods_cate // 提交到远程,且没有该分支
git push --set-upstream origin goods_params // 默认提示的

路由没有跳转成功的问题:

// com=>快捷生成的居然死 comments,艹 
{ path: '/categories', comments: Cate }

刚他妈发现该用人家接口地址的,不一定用本地的…好蠢。

产品分类中,使用了树状的table,需要用第三方的:
vue电商实战-黑马-01_第16张图片

columns而不是column

总是把函数写在了data中,这样总是报错!!!!

商品管理-参数管理

动态参数:颜色,版本(可以选择的)
静态属性:重量,长宽,上市年份,(用户不可选择的,只读的)
vue电商实战-黑马-01_第17张图片

参数列表:
1.切换tab的时候,如果是当前tab,那么不用调用函数了,不做处理就是了。

编辑器快捷键:
选中某个字段,ctr+d,快速选中下一个这个字段(多选,可以用来多个替换)

添加tag的时候,每一行的input显示和值需要都有一个:
给list的每一项绑定一个flag和value,自己维护自己的,就可以啦。

// input自动获取焦点:点击btn后,更改了flag,但是input还没渲染,等渲染后在执行focus事件。
// $nextTick:当页面上的元素被重新渲染之后,才会执行回调函数中的代码
this.$nextTick(_ => {
  this.$refs.saveTagInput.$refs.input.focus();
});

你可能感兴趣的:(vue_shop)