Vue项目开发学习经历(完结)

一、准备工作

前端项目初始化步骤

1.安装Vue脚手架
2.通过Vue脚手架创建项目
3.配置Vue路由
4.配置Element-UI组件
5.配置axios库
6.初始化git仓库
7.将本地项目托管到github

token

在学习的时候接触到了一个新的知识点:token

token登入原理:
客户端与服务器存在跨域问题 不推荐使用session cookie
登入页面输入用户名和密码进行登入,服务器验证通过之后生成该用户的token并返回
客户端存储该token,后续的请求都应该携带该token发生请求

⭐在使用axios向服务器端发请求的时候,如果是使用get方法,则需要在携带参数时,加上params属性

this.$axios.get("goods",{
    params:this.queryInfo
})

脚手架整理

1.App.vue根组件删除后效果

<template>
    <div id="app"></div>
</template>
<script>
export default {
    name:"app",
}
</script>
<style scoped>

</style>

2.router文件夹下的index.js删除后效果

import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = []
const router = new VueRouter({
    routes
})
export default router

二、知识点

1.开发使用less

在开发时推荐使用less进行页面美化,并且加上scoped保证该美化只对该组件生效。(当时学CSS不太了解scoped属性,现在在vue项目开发中遇到了它)

<style lang="less" scoped>

</style>

2.Vuetr插件设置

在开发的时候,上午使用vue写的好好的代码,下午打开却发现报了一堆错误(心里有点慌),后面想到应该是Vuetr插件的设置问题。
在这里插入图片描述
打开Vuetr插件设置,找到图中的三个选项,取消勾选即可在这里插入图片描述

3.less-loader依赖

必须要安装less-loader依赖才能在编译的时候不报错(因为我自己使用的是less语法)

4.导入组件

使用element-ui的时候,一开始报错:在这里插入图片描述
翻译一下是说没有找到这些标签,想了一下是自己在一开始创建项目的时候使用了按需导入。因此我来到了plugins文件夹下,修改element.js

import Vue from 'vue'
import { Button, Form, FormItem, Input, Message, 
Container, Header, Aside, Main, Menu,
 Submenu, MenuItem } from "element-ui"

Vue.use(Button)
Vue.use(Form)
Vue.use(FormItem)
Vue.use(Input)
Vue.use(Container)
Vue.use(Header)
Vue.use(Aside)
Vue.use(Main)
Vue.use(Menu)
Vue.use(Submenu)
Vue.use(MenuItem

导入Form、FormItem、Input,并在use方法中使用它们。之后发现不报错了。

5.表单验证规则

1.首先要定义一个规则 :rules=“loginRules”

<el-form  class="form" :model="form" :rules="loginRules">

2.在data中定义表单规则验证对象
3.给需要验证的表单加上验证规则 prop=" "

6.表单重置规则

1.首先我们要拿到表单引用对象 ref=“reset”

<el-form  ref="reset" class="form" :model="form" :rules="loginRules">

2.然后给重置按钮绑定一个单击响应函数
3.在单击响应函数中,调用this.$refs.reset.resetFields()即可

7.axios组件导入

如果表单验证通过,就发送请求,那么这里我选择通过axios发送请求。
在main.js中导入axios并全局配置

import axios from "axios"

Vue.config.productionTip = false
axios.defaults.baseURL = "http://127.0.0.1:8888/api/private/v1"
Vue.prototype.$http = axios

使用this.$http.post()发送请求
使用对象结构并重命名为res的方式获取服务器Promise对象中的data:

const {data:res}=  await this.$http.post("login",this.form)

8.全局挂载Message提示

import { Message } from "element-ui"
Vue.prototype.$message = Message

9.保存token

将登录成功之后的token保存在客户端的sessionStorage中
①项目中出了登录之外的其他API接口,必须在登录之后才能访问
②token只应该在当前网站打开期间生效,所以将token保存在sessionStorage中

window.sessionStorage.setItem("token",res.data.token);

10.Vue登录拦截

router.beforeEach((to, from, next) => {
    //to表示将要访问的路径
    //from代表从哪个路径跳转而来
    //next是一个函数表示放行
    if (to.path === "/login") {
        return next();
    } else {
        const tokenStr = window.sessionStorage.getItem("token")
        if (!tokenStr) {
            return next("/login")
        } else {
            next();
        }
    }
})

11.axios——request拦截器

11.通过axios——request拦截器添加token,保证拥有数据获取的权限。

//axios拦截器
axios.interceptors.request.use(config => {
    config.headers.Authorization = window.sessionStorage.getItem("token")
    return config
})

12.NavMenu踩雷

在使用NavMenu 导航菜单时,给index绑定一个item.id属性之后,发现报错:

<el-submenu :index="item.id" v-for="item in menuList" :key="item.id">

在这里插入图片描述
从报错信息反映出这个index接收字符串,而我更改index属性之后是一个数字,直接使用最简单的方法解决,在item.id之后加一个空字符串,拼串

<el-submenu :index="item.id+''" v-for="item in menuList" :key="item.id">

13.循环生成icon图标字体

在导出的默认数据内部的data中返回一个icons对象,分别保存对应item.id和想要的图标字体代码,在循环时给class属性绑定,使用中括号,根据item.id找到icons对象中对应的图标字体代码。

<el-submenu :index="item.id+''" v-for="item in menuList" :key="item.id">
	<i :class="icons[item.id]"></i>
</el-submenu>

<script>
export default {
  data() {
    return {
      icons:{
        "125":"el-icon-user",
        "103":"el-icon-lock",
        "101":"el-icon-star",
        "102":"el-icon-font",
        "145":"el-icon-flag",
      }
    }
  },
</script>

14.侧边栏装饰

在做项目的时候想到了一个侧边栏折叠效果,因此我加了一个可以点击的按钮,并且绑定了一个点击事件:

<div class="toggle-button" @click="toggleCollapse">|||</div>

给侧边栏加了一个属性绑定:使用动态开关来决定flag的值。

 <!-- 侧边栏菜单 -->
        <el-menu :collapse="flag" background-color="#114896" text-color="#fff" active-text-color="#ffd04b" 

在script中,data定义了一个flag开关;methods定义了toggleCollapse方法。

data() {
    return {
      //是否折叠
      flag:false
    }
  },
methods: {
    toggleCollapse(){
    //取反状态
      this.flag=!this.flag
    }
  }

在万事俱备以后,给侧边栏的宽度进行动态修改

<!-- 侧边栏 -->
      <el-aside :width="flag?'64px':'200px'">

15.侧边栏点击跳转路由

在element-ui中的Menu Attribute有一个router属性,启用该模式会在激活导航时以 index 作为 path 进行路由跳转。
因此我给侧边栏菜单开启了这个属性

<el-menu :router="true" background-color="#114896" text-color="#fff" active-text-color="#ffd04b"  unique-opened :collapse="flag"
:collapse-transition="false">

修改对应的index让它符合规则

:index="'/'+subItem.path+''"

16.侧边栏默认背景

(在methods中使用this.XXX就是在访问data里面的数据名称)
给点击到的侧边栏加一个默认背景,使用default-active属性
与14号知识点差不多的思路,但是这里使用到了sessionStorage,通过它来存储点击到的path路径,然后赋值给default-active属性

⭐这里就不演示代码了

17.表格索引号

Element-UI组件中给表格加上一个索引号,使用type=“index”

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

18.作用域插槽开关

作用域插槽渲染状态(mg_state)开关;slot-scope="scope"接收服务器的数据,提取其中的scope.row.mg_state,双向绑定在el-switch上

<el-table-column label="状态">
  <template slot-scope="scope">
      <!-- {{scope.row.mg_state}} -->
      <el-switch v-model="scope.row.mg_state" active-color="#13ce66"></el-switch>
   </template>
</el-table-column>

19.vue验证规则功能

添加用户的手机号和邮箱时,不能使用普通的验证(例如对用户名、密码),此时需要在script标签中定义验证规则函数,然后使用validator属性接收定义好的验证规则函数。(validator接收一个函数)

<script>
export default {
  data() {
//验证规则
    var checkemail=(rule,value,callback)=>{
      const reg=/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
      if(reg.test(value)){
        return callback();
      }
      callback(new Error("请输入合法的邮箱"))
    }
   
   return {
   	rules:{
   		email:[
          {required:true,message:"请输入邮箱",trigger:"blur"},
          //validator属性接收
          {validator:checkemail,trigger:"blur"}
        ],
      }
   	}
   }
</script>

20.分级别显示功能

先说明一下开发这个功能的想法:每一个用户都有不同的角色,而不同的角色对应着不同的权限,这个时候就需要区别对待。
但是逐一渲染非常麻烦,因此我想起了v-if属性,通过组件插槽这个功能拿到数据,使用v-if与拿到数据中的等级对比,从而在页面上渲染对应的等级

<el-table-column label="权限等级" prop="level">
   <template slot-scope="scope">
      <el-tag v-if="scope.row.level==='0'">一级</el-tag>
      <el-tag v-if="scope.row.level==='1'" type="success">二级</el-tag>
      <el-tag v-if="scope.row.level==='2'" type="warning">三级</el-tag>
    </template>
</el-table-column>

21.弹框删除组件

给弹框删除的元素绑定一个函数事件,使用element-ui提供的函数主体即可,函数源码如下:

async remove(){
    const confirm = await this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).catch(err=>err)
    }
    if(confirm!==confirm){
      return this.$message.info("取消删除")
    }

22.vue-table-with-tree-grid插件

main.js入口文件导入

import TreeTable from "vue-table-with-tree-grid"
Vue.component("tree-table", TreeTable)

官方文档:https://github.com/MisterTaki/vue-table-with-tree-grid

23.Cascader 级联选择器

分级别的选择功能运用场景还挺多,里面有几个需要注意的属性知识点:
I.options用来指定数据源
II.props用来指定配置对象
III.v-model用来保存选中数据的id

<el-cascader
v-model="selectvalue"
:options="parentCateList"
:props="{ expandTrigger:'hover',value:'cat_id',label:'cat_name',children:'children' }"
@change="handleChange"
clearable change-on-select
></el-cascader>

24.计算属性

在编写项目的时候,需要根据数组的长度来判断是否禁用按钮,于是我想到了利用计算属性computed

// 给按钮绑定disabled
<el-button :disabled="isBtndisabled" type="primary" size="mini">添加参数</el-button>
computed: {
      //计算属性 如果按钮需要被禁用则返回true
      isBtndisabled(){
          if(this.seleteCateList.length!==3){
              return true
          }
          return false
      }
  },

25.数组分割雷区

使用split()方法对数组进行分割时,如果对一个空数组进行空格分割,则结果是得到一个空格(而不是空数组),会导致渲染数据的时候,明明没有数据,浏览器却渲染出了一个空格!

使用三元表达式进行判断,如果这个数组为空,则直接返回空数组,不调用split方法。

res.data.forEach(item => {
    item.attr_vals = item.attr_vals?item.attr_vals.split(" "):[]; 
})

26.Element-ui文本框自动获取焦点

//$nextTick方法的作用,就是当页面上的元素被重新渲染之后,才指定回调函数中的代码
//第二行是获取页面上的Tag标签,调用focus()方法
      this.$nextTick(_ => {
          this.$refs.saveTagInput.$refs.input.focus();
        });

27.过滤器filter处理时间格式

在对日期进行处理的时候,需要使用filter
首先在全局中定义一个处理函数来处理日期格式
⭐padStart()方法: 用于头部补全补全字符串,第一个参数用来指定字符串的最小长度,第二个参数是用来补全的字符串。

Vue.filter("dateFormat", function(origin) {
    const dt = new Date(origin)
    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}`
})

接着在vue文件中使用作用域插槽来使用过滤器

<el-table-column width="180px" prop="add_time" label="创建时间">
    <template slot-scope="scope">
        {{scope.row.add_time | dateFormat}}
    </template>
</el-table-column>

28.MessageBox全局注册

在调用Element-ui之MessageBox组件时,忘记全局注册而导致报错在这里插入图片描述
提示我this.$confirm is not a function,我明明引用了组件为什么还报错,仔细一想我是在全局中进行使用,于是在element.js中全局注册了一下,完美的解决了这个问题

Vue.prototype.$confirm = MessageBox.confirm

29.Steps 步骤条与Tab 栏切换双向绑定

//active属性指定step的显示,在data中预先定义了一个activeIndex
<el-steps align-center :space="200" :active="activeIndex-0" finish-status="success">
        <el-step title="基本信息"></el-step>
        <el-step title="商品参数"></el-step>
        <el-step title="商品属性"></el-step>
        <el-step title="商品图片"></el-step>
        <el-step title="商品内容"></el-step>
        <el-step title="完成"></el-step>
</el-steps>

//v-model与activeIndex进行绑定,而name属性值存储在v-model中,点击不同的tab栏更改name,更改v-model,从而实现双向绑定
<el-tabs v-model="activeIndex" :tab-position="'left'" style="height: 200px;">
        <el-tab-pane name="0" label="基本信息">基本信息</el-tab-pane>
        <el-tab-pane name="1" label="商品参数">商品参数</el-tab-pane>
        <el-tab-pane name="2" label="商品属性">商品属性</el-tab-pane>
        <el-tab-pane name="3" label="商品图片">商品图片</el-tab-pane>
        <el-tab-pane name="4" label="商品内容">商品内容</el-tab-pane>
</el-tabs>

30.Tabs栏切换函数:before-leave

<el-tabs :before-leave="beforeTabLeave"></el-tabs>
 methods: {
	beforeTabLeave(activename,oldactivename){
      console.log("即将离开的标签页是"+oldactivename)
      console.log("即将进入的标签页是"+activename)
    }
}

31.图片上传组件Upload

这里记录一个bug:在上传的时候upload组件并没有使用项目设置的token,因此上传是失败的,使用headers设置上传的请求头部即可

<!-- action表示图片上传到的后台API地址 -->
<!-- list-type="picture" 指定缩略图 -->
<!-- :headers="headerObj" 指定请求头token -->
<el-upload
   :headers="headerObj"
   action="http://127.0.0.1:8888/api/private/v1/upload"
   :on-preview="handlePreview"
   :on-remove="handleRemove"
   list-type="picture"
>
data() {
    return{
		//图片请求头对象
      	headerObj:{
        	Authorization:window.sessionStorage.getItem("token")
      	}
	}
}

32.图片上传成功的事件

通过调用图片上传成功时触发的函数,得到图片信息对象
之后将图片信息对象的push到存储图片的数组中

const picInfo = { pic: response.data.tmp_path };
//将图片信息对象的push到pics数组中
this.addForm.pics.push(picInfo);

33.图片移除效果

通过调用图片移除时触发的函数,获取图片路径。
之后调用findIndex方法,在存储所有图片的数组中找到要移除的图片的索引号,使用一个参数接收。
之后调用splice方法移除该图片

const filePath = file.response.data.tmp_path;
const i = this.addForm.pics.findIndex((x) => {
        x.pic === filePath;
	});
this.addForm.pics.splice(i, 1);

34.图片预览效果

使用el-dialog组件弹出一个对话框,在对话框中放对应的图片:

<el-dialog title="图片预览" :visible.sync="dialogVisible" width="50%">
    <img :src="previewPath" class="previewimg">
</el-dialog>
data() {
    //定义图片的路径
	previewPath:""
}
method:{
	handlePreview(file){
	//拿到预览图片的路径并赋值
	  this.previewPath = file.response.data.url;
      this.dialogVisible=true
    }
}

35.富文本编辑器

启动vue ui,在运行依赖中输入Vue-Quill-Editor,安装

Mount with global:
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 } */)
Component:
<quill-editor v-model="addForm.goods_introduce"></quill-editor>

36.lodash深拷贝

启动vue ui,在运行依赖中输入lodash,安装

//导入
import _ from "lodash"
//cloneDeep()
//获得拷贝对象
const from =  _.cloneDeep(this.addForm)
from.goods_cat = from.goods_cat.join(",")

37.Echarts依赖

官方文档:https://echarts.apache.org/zh/index.html
运行vue ui ,在运行依赖中搜索Echarts,安装

//1.导入echarts
import echarts from "echarts";
//2.为ECharts准备一个具备大小(宽高)的Dom 
<div id="main" style="width: 750px;height:400px;"></div>
//3. 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById("main"));
//4. 指定图表的配置项和数据
const result = _.merge(res.data,this.options)
//5.展示数据
myChart.setOption(result);

在第4步的时候,使用了lodash的对象合并merge()方法,在36项知识点(使用_)已经导入。

三、项目优化

1.生成打包报告

在项目打包之后,可以看到打包报告。速度统计是在不同网络下打开所需时间。
体积过大的依赖项我们需要优化,来提升用户的浏览体验

在这里插入图片描述

2.路由懒加载

当打包构建项目时,JavaScript包会变得非常大,影响页面加载。我们需要把不同的路由对应的组件分割成不同的代码块,当路由被访问的时候在加载对应组件。
①安装@babel/plugin-syntax-dynamic-import包
②在babel.config.js文件下声明该插件

module.exports = {
    plugins: [
        "@babel/plugin-syntax-dynamic-import"
    ]
}

③将路由改为按需加载模式(示例一项)

//import Login from '../components/Login.vue'
const Login = () =>
    import ( /* webpackChunkName: "login_home_welcome" */ '../components/Login.vue')

3.首页内容定制

所谓的首页内容定制,就是动态的渲染title标签
根据环境不同(开发环境、发布环境),给title加上不同前缀

来到vue.config.js文件,在发布环境和开发环境新增一个回调函数,找到plugin下的html插件,通过调用tap加一个可控的属性args[0].isProd

module.exports = {
    lintOnSave:  false,
    chainWebpack: config => {
        //发布模式
        config.when(process.env.NODE_ENV === 'production', config => {
             config.plugin("html").tap(args => {
                 args[0].isProd = true
                 return args
             })
        })
        //开发模式
        config.when(process.env.NODE_ENV === 'development', config => {
            config.plugin("html").tap(args => {
                args[0].isProd = false
                return args
            })
        })
    }
}

创建了动态参数属性后,来到public文件夹下,找到index.html
使用art-template模板的原文输出给title加上之前定义的isProd进行改造:

<title>
	//这里使用了art-template模板的原文输出
	<%= htmlWebpackPlugin.options.isProd ? "":"dev-" %>电商后台管理系统
</title>

4.nprogress进度条

在Vue项目中,我们不需要使用npm install安装,在命令行窗口输入vue ui,在依赖栏的运行依赖中,搜索nprogress安装即可!
官方文档:https://github.com/rstacruz/nprogress
⭐最重要的两个函数

NProgress.start();
NProgress.done();
//在入口文件main.js导入nprogress的JS和CSS
import NProgress from "nprogress"
import "nprogress/nprogress.css"

//request拦截器中展示进度条
axios.interceptors.request.use(config => {
    NProgress.start()
    config.headers.Authorization = window.sessionStorage.getItem("token")
    return config
});
//response拦截器中隐藏进度条
axios.interceptors.response.use(config => {
    NProgress.done()
    return config
})

5.babel-plugin-transform-remove-console

去除打包环境下的console警告。
vue ui开发依赖中搜索babel-plugin-transform-remove-console,安装
之后再babel.config.js文件中编写下列代码

//这是项目发布阶段需要用到的babel插件
const prodPlugins=[]
if(process.env.NODE_ENV==="production"){
  prodPlugins.push("transform-remove-console")
}
module.exports = {
  presets: [
    '@vue/cli-plugin-babel/preset'
  ],
  plugins: [
    [
      'component',
      {
        libraryName: 'element-ui',
        styleLibraryName: 'theme-chalk'
      }
    ],
    //在项目开发的时候才运行这个插件
    ...prodPlugins
  ]
}

6.vue.config.js配置webpack打包

找到入口文件main.js,全选复制里面的代码,然后删除该文件,新建两个新的文件main-prod.js、main-dev.js,都粘贴原先main.js中的代码。 在这里插入图片描述 在这里插入图片描述
然后找到vue.config.js文件,编写下列代码

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

7.第三方库启用CDN(externals)

在6步骤的基础上新增externals设置排除项

module.exports = {
    lintOnSave:  false,
    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.when(process.env.NODE_ENV === 'development', config => {
            config.entry('app').clear().add('./src/main-dev.js')
        })
    }
}

之后找到public文件夹下的index.html文件,在head添加下列代码

<!-- 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" />
    
<script src="https://cdn.staticfile.org/vue/2.5.22/vue.min.js"></script>
<script src="https://cdn.staticfile.org/vue-router/3.0.1/vue-router.min.js"></script>
<script src="https://cdn.staticfile.org/axios/0.18.0/axios.min.js"></script>
<script src="https://cdn.staticfile.org/lodash.js/4.17.11/lodash.min.js"></script>
<script src="https://cdn.staticfile.org/echarts/4.1.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>

8.Element-UI组件按需加载

与第7步骤有一点不同,要在main-prod.js文件中注释(或删除)element-ui代码

// import './plugins/element.js'

之后找到public文件夹下的index.html文件,在head添加下列代码

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

7.8步骤均为优化依赖项体积的操作

四、打包上线

1.打包最终的dist

在终端中输入vue ui,找到任务栏的build点击运行,结束后生成一个dist文件。
新创建一个文件夹,用来存放打包上线的所有资源。
使用npm init -y初始化一个package.json文件
②使用npm install express -S安装Express,用于搭建网站服务器,要在电脑上先安装node
③新建一个文件app.js编写服务器代码

const express = require("express")
const app = express();
app.use(express.static("./dist"))
app.listen(80, () => { console.log("server running at http://127.0.0.1") })

④把dist文件夹移动到打包上线的文件夹,成效如图:
在这里插入图片描述

2.开启gzip配置

使用gzip减小文件的体积,更快速的打开网页
使用npm install compression -D安装
在1步骤的基础上,来到app.js文件编写代码

const express = require("express")
const compression = require("compression")
const app = express();
//一定要把compression写到静态资源托管之前
app.use(compression())
app.use(express.static("./dist"))
app.listen(80, () => { console.log("server running at http://127.0.0.1") })

3.pm2管理应用

使用pm2来解决打开网站必须运行在终端的问题。即可以通过配置达到不需要启动终端以打开网站的效果
①cmd命令行工具输入:npm i pm2 -g
②在打包上线的文件夹下命令行工具输入:pm2 start .\app.js --name web_vueshop
③查看运行项目:pm2 ls
④重启项目:pm2 restart id/项目名称
⑤停止项目:pm2 stop id/项目名称
⑥删除项目:pm2 delete id/项目名称

到此为止,所有的项目功能均已开发完毕!!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值