电商项目

Vue的学习过程中,做了这个电商项目练习,在做的过程中做了如下一些笔记,本项目主要用到是 Vue + element-ui框架快速成型.由于还未学习服务器部署等技术,项目只能在本地运行.项目笔记如下.

  1. 创建工程
vue create vue_shop
rd/s/q 强制删除
  1. 运行工程
npm run serve
  1. 删除多余组件内容
  2. 关闭eslinet
打开package.json 用下面替换
"eslintConfig": {
 "root": true,
 "env": {
   "node": true
 },
 "extends": [
   "plugin:vue/essential"
 ],
 "parserOptions": {},
 "rules": {
   "vue/no-unused-components": "off"
 }
  },
  1. 常见的创建目录文件夹
  2. element-ui插件的安装和按需引入

1.安装

1.1 npm install --save element-ui

1.2 npm install babel-plugin-component -D -D表示开发依赖

2.配置babel.config.js

module.exports = { presets: [ '@vue/cli-plugin-babel/preset', ["@babel/preset-env" ,{ "modules": false }] ], "plugins": [ [ "component", { "libraryName": "element-ui", "styleLibraryName": "theme-chalk" } ] ] }

  1. 在使用less出错
<style lang="less" scoped>
.login_container {
  background-color: #eee;
}
</style>

报错
Failed to resolve loader: less-loader
You may need to install it.

解决

1.npm install less --save-dev

2.npm install less-loader@5.0.0 --save 高版本会报错 2021.09.05

  1. 安装路由
    npm install --save vue-router
    路由js文件
// 路由文件

//引入vue
import Vue from 'vue';

//引入vue-router
import VueRouter from 'vue-router';

//第三方库需要use一下才能用
Vue.use(VueRouter)

//引用 login 页面
import login from '../pages/login';

//实例化 VueRouter 并将routes添加进去
export default new VueRouter({
    //ES6简写,等于routes:routes
    routes: [
        // 登录页面
        {
            path: '/login',
            component: login
        },
    ]
});

element-ui 消息弹窗

引入

import { Message} from 'element-ui'; // 登录弹窗提示 Vue.prototype.$message = Message; //挂在原型链上

  1. axios的使用
  1. npm install axios
//方法1:
import axios from 'axios'    引入axios
//原型链产生污染(但是不推荐使用)
Vue.prototype.$http = axios  //挂载在原型上
                        
//请求基地址
axios.defaults.baseURL = 'http://127.0.0.1:8888/api/private/v1/'
                        
// 请求拦截器
axios.interceptors.request.use(
  config => {
    // 携带token
    config.headers.Authorization = window.sessionStorage.getItem('token');
    return config
  },
  error => {
    // 将异常返回给用户处理
    return Promise.reject(error)
  }
);

全局路由守卫

//配置全局路由导航守卫
router.beforeEach((to, from, next) => {
  /* 必须调用 `next` */
  //  访问登录首页则直接放行
  if (to.path === '/login') return next();
  //判断时候有token 
  // sessionStorage.getItem('token')为空时 为undefined 表示未登录
  if (sessionStorage.getItem('token'))
    next();
});
  1. 插件库 vue-table-with-tree-grid-树形表格组件
    官方地址:https://github.com/MisterTaki/vue-table-with-tree-grid

下载

npm i vue-table-with-tree-grid -S
//引入
import Vue from 'vue'
import TreeTable from 'vue-table-with-tree-grid'
Vue.component('tree-table', TreeTable)

Or
import Vue from 'vue'
import ZkTable from 'vue-table-with-tree-grid'
Vue.use(ZkTable)

//使用
 <!-- 表格 -->
     <tree-table
       :data="cateList"
       :columns="columns"
       :selection-type="false"
       :expand-type="false"
       show-index
       index-text="#"
       border
     >
       <template v-slot:isok="scope">
         <i
           class="el-icon-success"
           style="color: lightgreen"
           v-if="scope.row.cat_deleted === false"
         ></i>
         <i class="el-icon-error" style="color: red" v-else></i
       ></template>
     </tree-table>


<script>
export default {
 columns: [
       {
         label: '分类名称',
         prop: 'cat_name'
       },
       {
         label: '是否有效',
         // 表示将当前列定义为模板列
         type: 'template',
         // 表示当前这一列的模板名称
         template: 'isok'
       }
     ]
</script>
  1. 转化时间格式

全局注册:

// 时间过滤器
Vue.filter('dateFormat', function (originaVal) {
  const dt = new Date(originaVal)
  const y = dt.getFullYear();
  const m = (dt.getMonth() + 1 + '').padStart(2, '0');
  const d = (dt.getDate() + '').padStart(2, '0');

  const hh = (dt.getHours() + '').padStart(2, '0');
  const mm = (dt.getMinutes() + '').padStart(2, '0');
  const ss = (dt.getSeconds() + '').padStart(2, '0');
  return `${y}-${m}-${d} ${hh}: ${mm}: ${ss}`
});<el-table-column align="center" prop="add_time" label="创建时间">
     <template slot-scope="scope">
         {{ scope.row.add_time | dateFormat }}
     </template>
</el-table-column>
  1. filter用于对数组进行过滤

filter用于对数组进行过滤
它创建一个新数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。

注意:filter()不会对空数组进行检测、不会改变原始数组

this.addForm.pics.filter((i) => i.pic !== picsPath);

数组中的每个元素都会执行这个函数。且如果返回值为 true,则该元素被保留;
  函数的第一个参数 i也为必须,代表当前元素的值。

  1. 富文本插件名
    地址:https://github.com/surmon-china/vue-quill-editor
  1. 下载

npm install vue-quill-editor --save

  1. 导入

全局注册

import VueQuillEditor from 'vue-quill-editor'

import 'quill/dist/quill.core.css' // import styles
import 'quill/dist/quill.snow.css' // for snow theme
import 'quill/dist/quill.bubble.css' // for bubble theme

Vue.use(VueQuillEditor, /* { default global options } */)

按需注册

import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'

import { quillEditor } from 'vue-quill-editor'

export default {
  components: {
    quillEditor
  }
}
html
<template>
  <!-- Two-way Data-Binding -->
  <quill-editor
    ref="myQuillEditor"
    v-model="content"
    :options="editorOption"
    @blur="onEditorBlur($event)"
    @focus="onEditorFocus($event)"
    @ready="onEditorReady($event)"
  />

  <!-- Or manually control the data synchronization -->
  <quill-editor
    :content="content"
    :options="editorOption"
    @change="onEditorChange($event)"
  />
</template>
  1. 深拷贝

lodash 是一个 JavaScript 实用工具库,提供一致性,及模块化、性能和配件等功能。

地址: https://www.lodashjs.com/

Lodash 消除了处理数组的麻烦,从而简化了 JavaScript、 数字、对象、字符串等。

它的模块化方法非常适合:

  • 迭代数组,对象和字符串
  • 操作和测试值
  • 创建复合功能
  1. 下载

npm i --save lodash

  1. 注册

import _ from 'lodash';

  1. 城市信息

地址: https://github.com/iceyangcc/provinces-china

  1. echarts插件

地址https://echarts.apache.org/zh/index.html

下载:

npm install echarts --save

全局引入:

// 引入echarts import echarts from 'echarts' Vue.prototype.$echarts = echarts

按需引入:

import Breadcrumb from "../../components/Breadcrumb.vue"; // 引入echarts import * as echarts from "echarts";

使用:

<!-- 1.在绘图前我们需要为 ECharts 准备一个定义了高宽的 DOM 容器。 -->
<div id="main" style="width: 600px; height: 400px"></div>// dom节点被渲染完毕后执行
 mounted() {
   // 2. 基于准备好的dom,初始化echarts实例
   var myChart = echarts.init(document.getElementById("main"));

   // 3 .指定图表的配置项和数据
   let option = {
     title: {
       text: "ECharts 入门示例",
     },
     tooltip: {},
     legend: {
       data: ["销量"],
     },
     xAxis: {
       data: ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"],
     },
     yAxis: {},
     series: [
       {
         name: "销量",
         type: "bar",
         data: [5, 20, 36, 10, 10, 20],
       },
     ],
   };

   // 4.使用刚指定的配置项和数据显示图表。
   myChart.setOption(option);
 },
  1. 进度条插件


下载:

npm install --save nprogressimport NProgress from 'nprogress' // 进度条 import 'nprogress/nprogress.css' // 这个样式必须引入

可以在请求前 NProgress.start()

响应后 NProgress.done()

  1. 优化代码:
    去掉console.log();语句
    可以在babel.config.js中加入,在开发模式中会忽略
const prodPlugins = []
if (process.env.NODE_ENV === 'production') {
  prodPlugins.push('transform-remove-console')
}
  plugins: [
    ["component",
      {
        "libraryName": "element-ui",
        "styleLibraryName": "theme-chalk"
      }
    ],
    ...prodPlugins

  ]

vue.config.js配置

module.exports = {

    chainWebpack: config => {
        //发布模式
        config.when(process.env.NODE_ENV === 'production', config => {
            //entry找到默认的打包入口,调用clear则是删除默认的打包入口
            //add添加新的打包入口
            config.entry('app').clear().add('./src/main-prod.js')

            //使用externals设置排除项
            config.set('externals', {
                vue: 'Vue',
                'vue-router': 'VueRouter',
                axios: 'axios',
                lodash: '_',
                echarts: 'echarts',
                nprogress: 'NProgress',
                'vue-quill-editor': 'VueQuillEditor',
            });
            //使用插件
            config.plugin('html').tap(args => {
                //添加参数isProd
                args[0].isProd = true
                return args
            });
        });

        //开发模式
        config.when(process.env.NODE_ENV === 'development', config => {
            config.entry('app').clear().add('./src/main-dev.js');

            //使用插件
            config.plugin('html').tap(args => {
                //添加参数isProd
                args[0].isProd = false
                return args
            });
        });
    }
}

cdn引入以依赖在mian.js做出响应的修改,要注意版本号

<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width,initial-scale=1.0">
  <link rel="icon" href="<%= BASE_URL %>favicon.ico">
  <title>
        <!-- 区别开发依赖和生产依赖,开发依赖自己使用已经导入的插件 -->
    <%= htmlWebpackPlugin.options.isProd ? '' : 'dev - ' %>电商后台管理系统
  </title>
  <% if(htmlWebpackPlugin.options.isProd){ %>
    <!-- nprogress 的样式表文件 -->
    <link rel="stylesheet" href="https://cdn.staticfile.org/nprogress/0.2.0/nprogress.min.css" />


    <!-- 富文本编辑器 的样式表文件 -->
    <link rel="stylesheet" href="https://cdn.staticfile.org/quill/1.3.4/quill.core.min.css" />
    <link rel="stylesheet" href="https://cdn.staticfile.org/quill/1.3.4/quill.snow.min.css" />
    <link rel="stylesheet" href="https://cdn.staticfile.org/quill/1.3.4/quill.bubble.min.css" />

    <!-- element-ui 的样式表文件 -->
    <link rel="stylesheet" href="https://cdn.staticfile.org/element-ui/2.15.6/theme-chalk/index.css" />

    <script src="https://cdn.staticfile.org/vue/2.6.11/vue.min.js"></script>
    <script src="https://cdn.staticfile.org/vue-router/3.5.2/vue-router.min.js"></script>
    <script src="https://cdn.staticfile.org/axios/0.21.4/axios.min.js"></script>
    <script src="https://cdn.staticfile.org/lodash.js/4.17.21/lodash.min.js"></script>
    <script src="https://cdn.staticfile.org/echarts/5.2.0/echarts.min.js"></script>
    <script src="https://cdn.staticfile.org/nprogress/0.2.0/nprogress.min.js"></script>

    <!-- 富文本编辑器的 js 文件 -->
    <script src="https://cdn.staticfile.org/quill/1.3.4/quill.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vue-quill-editor@3.0.4/dist/vue-quill-editor.js"></script>

    <!-- element-ui 的 js 文件 -->
    <script src="https://cdn.staticfile.org/element-ui/2.15.6/index.js"></script>
    <% } %>
</head>
  1. 项目上线 搭建本地服务器运行开发项目通过node创建服务器,配置https服务
  1. 在vue_shop同级创建一个文件夹vue_shop_server存放node服务器
  2. 使用终端打开vue_shop_server文件夹,输入命令 npm init -y
  3. 初始化包之后,输入命令 npm i express -S
  4. 打开vue_shop目录,复制dist文件夹,粘贴到vue_shop_server中
  5. 在vue_shop_server文件夹中创建app.js文件,编写代码如下:
const express = require('express')
// const compression = require('compression')
// const https = require('https')
// const fs = require('fs')

//编写代码导入证书
const app = express()
//创建配置对象设置公钥和私钥
// const options = {
//     cert:fs.readFileSync('./full_chain.pem'),
//     key:fs.readFileSync('./private.key')
// }

// app.use(compression())
app.use(express.static('./dist'))

app.listen(8080,()=>{
    console.log("server running at http://127.0.0.1:8080")
})

//启动https服务
// https.createServer(options,app).listen(443)

  1. 然后再次在终端中输入 node app.js

注意:

首先,需要申请SSL证书,进入https://freessl.cn官网,在后台导入证书,打开在官网下载的证书文件夹,复制文件夹中的两个文件到vue_shop_server中

然后把 https 的把注释打开即可

  1. 使用pm2管理应用
    因为关闭终端项目就停止运行,我们可以使用 pm2来管理我的项目运行

打开vue_shop_server文件夹的终端,输入命令:npm i pm2 -g
使用pm2启动项目

在终端中输入命令:pm2 start app.js --name 自定义名称
查看项目列表命令:pm2 ls
重启项目:pm2 restart 自定义名称
停止项目:pm2 stop 自定义名称
删除项目:pm2 delete 自定义名称

最后效果展示

  1. 效果展示:
  1. 登录页面

vue element 部门 vue+element-ui项目_node.js

主页

vue element 部门 vue+element-ui项目_vue element 部门_02

用户列表

vue element 部门 vue+element-ui项目_javascript_03

权限管理--->用户角色

vue element 部门 vue+element-ui项目_vue.js_04

权限管理--->权限列表

vue element 部门 vue+element-ui项目_vue element 部门_05

商品管理--->商品列表

vue element 部门 vue+element-ui项目_vue element 部门_06

商品管理--->商品列表添加

vue element 部门 vue+element-ui项目_node.js_07

vue element 部门 vue+element-ui项目_node.js_08

商品管理--->商品列表添加富文本

vue element 部门 vue+element-ui项目_html_09

商品管理--->分类参数

vue element 部门 vue+element-ui项目_javascript_10

商品管理--->商品分裂

vue element 部门 vue+element-ui项目_html_11

订单管理--->订单列表

vue element 部门 vue+element-ui项目_javascript_12

数据统计--->数据列表

vue element 部门 vue+element-ui项目_vue.js_13

项目需调取的 api 分享链接:

vue_api_server文件名–>api接口

vue_shop_server文件名–>本地服务项目