-
vue一个域名部署多个项目 前端配置
2021-02-27 16:30:09在项目开发时,我们可能会遇到这样的需求,只有一个域名,但是需要配置多个不同的模块项目进去,那么遇到这样的情况我们前端需要怎么配置呢?下面我给大家说下我的配置: 第一步 首先,找到vue项目中的config文件下...在项目开发时,我们可能会遇到这样的需求,只有一个域名,但是需要配置多个不同的模块项目进去,那么遇到这样的情况我们前端需要怎么配置呢?下面我给大家说下我的配置:
第一步
首先,找到vue项目中的config文件下的index.js,
修改assetsPublicPath
,具体配置如下:build: { index: path.resolve(__dirname, '../dist/index.html'), // Paths assetsRoot: path.resolve(__dirname, '../dist'), assetsSubDirectory: 'static', assetsPublicPath: '/test/' }
第二步
router文件下的index.js
,配置如下:export default new Router({ base: '/test', routes, mode: 'history' })
第三步
根文件index.html添加<mate base="/test/" >
以上配置结束打包就可以了!
-
vue项目nginx部署子目录_Docker+nginx部署Springboot+vue前后端分离项目
2021-02-03 00:14:59上线前准备这里我们同步演示怎么部署到win环境和linux(centos7)系统中,前端服务器采用nginx部署,并使用docker统一管理前后端服务器。所以我们会用到:nginxdocker compose希望你看视频前有点基础哈,当然了,这次...上线前准备
这里我们同步演示怎么部署到win环境和linux(centos7)系统中,前端服务器采用nginx部署,并使用docker统一管理前后端服务器。
所以我们会用到:
nginx
docker compose
希望你看视频前有点基础哈,当然了,这次部署比较简单,不需要很精通,一般看了我的视频应该都能部署成功的哈。
话不多说,直接上手!别忘了给我一个一键三联哈,顺便关注我B站,感谢!
1、win环境
win环境我就用本机来演示了,我们需要分别打包前后端,前后端打包都是一条命令即可,只不过我们打包之前注意需要配置好线上的环境参数等。
1.1、前端
先来配置一下后端的调用路径,因为现在部署在本地localhost,所以在axios.js中,我们配置好链接,因为等下后端部署也是本机,所以我这里直接这样配置就好了,如下:
src\axios.js
axios.defaults.baseURL = "http://localhost:8081"
上面配置的就是前端访问后端接口的服务。然后前端部署还需要考虑一个问题:打包之后项目资源引用路径,比如我们打包后链接是否需要带项目名称等。按照Vue官方的部署说明,我们添加一个vue.config.js文件,
vueblog-vue/vue.config.js
module.exports = {
publicPath: '/'
}当然了,publicPath默认其实是空的,也就是publicPath: '',两个效果貌似其实是一样的,哈哈哈,我只是提醒一下有这回事而已,嘿嘿。设置完毕之后,我们执行打包命令:
# 打包命令
npm run build命令执行之后,我们在项目根目录下就可以找到一个dist的目录,这个就是打包之后的文件夹,里面有个index.html,但是我们点击直接打开是看不到任何内容的,这时候,我们需要部署到nginx中。
首先我们下载一个nginx,下载地址:http://nginx.org/en/download.html,这里我们下载nginx/Windows-1.18.0版本,下载之后解压zip。根据我们对nginx的熟悉,静态文件我们放在html文件夹下面,所以先把html文件夹中的index.html和50x.html删掉,然后把打包出来的dist文件夹内的所有文件都复制到nginx的html中,如图:
双击nginx.exe启动nginx,然后浏览器输入http://localhost,出现了我们熟悉的界面,虽然没有博客数据,链接也自动跳转到了http://localhost/blogs,
我们点击任意一个链接或者按钮或者刷新界面,这时候出现了404:
刷新之后nginx就找不到路由了,这是为啥,得和你们科普一下,vue项目的入口是index.html文件,nginx路由的时候都必须要先经过这个文件,所以我们得给nginx定义一下规则,让它匹配不到资源路径的时候,先去读取index.html,然后再路由。所以我们配置一下nginx.conf文件。具体操作就是找到location /,添加上一行代码try_files $uri $uri/ /index.html last;如下:
nginx-1.18.0/conf/nginx.conf
location / {
root html;
try_files $uri $uri/ /index.html last;
index index.html index.htm;
}这一行代码是什么意思呢?try_files的语法规则:格式1:try_files file ... uri,表示按指定的file顺序查找存在的文件,并使用第一个找到的文件进行请求处理,last表示匹配不到就内部直接匹配最后一个。
重启nginx之后,链接再刷新都正常啦。但是没有数据,所以我们去部署一下后端。windows环境nginx的重启我一般都是打开任务管理器直接干掉nginx进程,然后再重新双击的~~
1.2、后端
后端的打包就简单多了,应该大家都挺熟悉的,注意配置redis、mysql的链接密码啥的,然后执行命令,本机测试,redis和mysql我都已经提前安装好的了,sql文件也在vueblog-java的resources目录下。
对了,pom.xml文件里面,spring-boot-maven-plugin之前注释掉了,现在一定要打开。不然执行jar会找不到主类。
pom.xml
执行打包命令:
# 跳过测试打包
mvn clean package -Dmaven.test.skip=true得到target下的vueblog-0.0.1-SNAPSHOT.jar,然后再执行命令
java -jar vueblog-0.0.1-SNAPSHOT.jar --spring.profiles.active=default
后端上线之后,我们再访问下前端,发现已经可以正常浏览网页啦!spring.profiles.active表示指定环境配置文件。
2、linux环境
linux环境部署相对复杂一点,因为我们还要部署redis、mysql等。之前我发布过一个视频,是部署传统的博客项目eblog,采用的是docker容器,但是我们没有docker compose进行编排,这次我们使用docker compose来编排我们的服务,一起性搞定部署。
二话不说,我们先来安装一下docker和docker compose,对于docker知识还不是特别懂的同学,建议自行去补习补习哈。
2.1、安装docker
#安装
yum install docker
#检验安装是否成功
[root@localhost opt]# docker --version
Docker version 1.13.1, build 7f2769b/1.13.1
#启动
systemctl start docker2.2、安装docker compose
可以参考:https://docs.docker.com/compose/install/
sudo curl -L "https://github.com/docker/compose/releases/download/1.27.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
#
sudo chmod +x /usr/local/bin/docker-compose
# 检查是否安装成功
docker-compose --version2.3、编写Dockerfile文件
因为我们的项目需要成为docker的镜像,所以我们必须先编写Dockerfile文件构建我们的项目镜像然后进行编排,Dockerfile文件可以帮我们进行构建。
Dockerfile
FROM java:8
EXPOSE 8080
ADD vueblog-0.0.1-SNAPSHOT.jar app.jar
RUN bash -c 'touch /app.jar'
ENTRYPOINT ["java", "-jar", "/app.jar", "--spring.profiles.active=pro"]上面几行命令其实很简单,首先依赖jdk8环境,对外暴露8080,然后就是复制vueblog-0.0.1-SNAPSHOT.jar到docker容器中并命名为app.jar,最后是执行命令java -jar /app.jar --spring.profiles.active=pro,使用的是我们另外编写的一个线上环境配置。
application-pro.yml
# DataSource Config
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/vueblog?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=Asia/Shanghai
username: root
password: admin
shiro-redis:
enabled: true
redis-manager:
host: 127.0.0.1:6379等会儿我们需要修改application-pro.yml的redis和mysql链接等信息的一些配置,需要注意。
2.4、编写docker-compose.yml文件
我们需要用到的软件与服务分别有nginx、mysql、redis、还有我们的springboot项目,所以编写如下:
docker-compose.yml
version: "3"
services:
nginx: # 服务名称,用户自定义
image: nginx:latest # 镜像版本
ports:
- 80:80 # 暴露端口
volumes: # 挂载
- /root/nginx/html:/usr/share/nginx/html
- /root/nginx/nginx.conf:/etc/nginx/nginx.conf
privileged: true # 这个必须要,解决nginx的文件调用的权限问题
mysql:
image: mysql:5.7.27
ports:
- 3306:3306
environment: # 指定用户root的密码
- MYSQL_ROOT_PASSWORD=admin
redis:
image: redis:latest
vueblog:
image: vueblog:latest
build: . # 表示以当前目录下的Dockerfile开始构建镜像
ports:
- 8081:8081
depends_on: # 依赖与mysql、redis,其实可以不填,默认已经表示可以
- mysql
- redis上面的意思,我都用注释解释一遍了,希望可以讲清楚!需要注意的是,nginx中我们对nginx的放置静态资源的html文件夹和配置文件nginx.conf进行了一个挂载,所以我们打包后的文件放置到宿主机**/root/nginx/html**文件目录就行了哈
2.5、修改application-pro.yml
然后我们再回头看看application-pro.yml文件,mysql和redis的链接之前还是localhost,现在我们需要修改成容器之间的调用,如何知道mysql和redis的链接地址呢?docker compose就帮我们解决了这个问题,我们可以使用镜像容器的服务名称来表示链接。比如docker-compose.yml中mysql的服务名称就叫mysql、redis就叫redis。
所以我们最终得到的配置文件如下:
2.6、准备好nginx的挂载目录和配置
docker-compose.yml中已经提到,
宿主机的挂载目录:/root/nginx/html
挂载配置:/root/nginx/nginx.conf
所以我们在root目录下新建nginx目录,并进入nginx目录下新建html目录和一个nginx.conf配置文件。
然后对nginx.conf进行编写,具体配置如下:
nginx.conf
#user root;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
try_files $uri $uri/ /index.html last; # 别忘了这个哈
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}2.7、上传前端
前端打包之后先修改前端调用后端的接口,因为我是虚拟机,所以配置如下:
axios.js
axios.defaults.baseURL = "http://192.168.0.117:8081"
然后npm run build打包得到dist文件夹,并把dist压缩成dist.zip上传到linux之后解压到**/root/nginx/html**目录下。如下图:
2.8、部署后端
一切准备就绪之后,我们就开始编排部署了哈。
首先本地打包vueblog项目,vueblog-0.0.1-SNAPSHOT.jar,并上传到linux中,同时docker-compose.yml、Dockerfile也上传到同一目录下。如图所示:
然后我们执行一下编排命令:
# 开始编排
cd ~
docker-compose up -d其中-d表示后台服务形式启动
然后我们稍等片刻,特别是开始Building vueblog的时候可能时间有点长,耐心等待即可!
最后提示如下:
说明我们已经成功编排啦。
nginx是80端口,所以我们直接输入ip地址,如下可以看到一个界面然后有弹窗:
这个简单,是因为我们的数据库还没创建哈。接下来我们去手动创建一下数据库并导入sql文件。
vueblog-java/src/main/resources/vueblog.sql
然后再刷新一下浏览器链接,数据就出来啦,搞定,轻松
-
vue部署到eggjs下,并且实现多页面vue项目部署,eggjs前端渲染项目(附个人github示例地址)
2019-07-26 15:20:08怎么说呢,nodejs也是js,并且像阿里等大公司,别人虽然也用nginx之类,但是前端项目已经不是放在nginx上面跑了,所以,前端开发需要熟悉在nodejs环境下运行和开发。 项目已经上传 git地址:...项目背景
这个是我个人博客下一步开发的流程,上一篇博客讲过,我会研究eggjs后端框架,给我的博客建立后端系统。
这里有人会说前端不需要学后端。
怎么说呢,nodejs也是js,并且像阿里等大公司,别人虽然也用nginx之类,但是前端项目已经不是放在nginx上面跑了,所以,前端开发需要熟悉在nodejs环境下运行和开发。
项目已经上传
git地址:https://github.com/ht-sauce/dream-backend
调研
仔细看了下eggjs官方的关于和vue项目的结合
这里先奉上地址:https://www.yuque.com/easy-team/egg-vue/case
egg官方分为三种渲染模式
服务端渲染(ssr)
说白了就是把vue当成视图模板去开发,和传统不同的在于是完全由前端控制,核心的路由是nodejs控制。这是和Nuxt.js通过vuerouter进行控制不一样。eggjs更多是变成了传统的mvc框架模式。前端变成了之前的view部分。
前端渲染
这个和nginx没啥太大差别,但是主要是eggjs官方自己将vue的开发环境和eggjs结合在一起了,不存在启动两个项目的情况
assets前端渲染
这里我直接抄官方说法,说实在下面两点我没太理解。
在 前端渲染模式 章节讲到了基于 Vue 的一体化的前端渲染模式,好处是不需要借助第三方模板引擎且无效关注静态资源注入问题,但有两个小的功能限制:
-
layout 模板数据绑定能力较弱
-
资源注入不能自己定义,比如 async, crossorigin 等配置
个人选择
1、我个人而言项目之前是用的vuecli开发的,让我再把项目重构放在eggjs中,不乐意。
2、如果从前端渲染角度去考虑,我觉得完全没必要把项目进行合并,也降低了项目复杂度,缺点就是项目变多。
3、服务端渲染肯定是后期要做的。只不过先尝试。下次我会单独说一下服务端渲染。
实战
废话太多,最终我选择了前端渲染。选择和之前nginx类似的操作模式,不同在于我这次的vue项目是多页面项目。
vue的多页面项目从实际角度来看,其实和以前的静态文件模式差不多,但是多页面的优点在于资源共享。
1、打包
注意一点,你到时候项目放在哪里,也就是你的资源文件访问是否存在前缀。
我这里eggjs静态资源都在public下面所以,
vue.config.js是这样的:
//获取命令行参数 const projectName = process.argv[3]; console.log("当前打包项目名称:" + projectName); //页面配置参数,注意项目名称保持一致,页面结构保持一致 const multiPageConfig = { //index是特殊的项目,不做多余操作,仅仅用于项目分发 //举例,如判断电脑端和移动端,做首页项目入口 index: { name: "海天酱油" }, dht_blog: { name: "海天酱油博客" }, dht_platform: { name: "海天酱油后台系统" } }; //生成统一的页面配置结构 const multiPage = function() { let page = {}; for (let item in multiPageConfig) { page[item] = { entry: `src/${item}/main.js`, template: `src/${item}/index.html`, filename: `${item}.html`, title: multiPageConfig[item].name, favicon: `src/${item}/assets/${item}.ico` }; } return page; }; const page = multiPage(); //vue下配置文件参数 const vueConfig = { //注意,这里的public就是对于eggjs下的静态资源 publicPath: process.env.NODE_ENV === "production" ? "/public" : "/", //部署应用包时的基本 URL outputDir: "dist", //打包目录 pages: projectName ? page[projectName] : page }; console.log(page); module.exports = vueConfig;
打包之后直接放在eggjs下的app/public下
然后关键的路由配置就像nginx一样
这里注意,我开发的时候自己本身项目是区分了前缀的,但是eggjs的路由需要注意是在public下的,所以你需要增加public前缀,但是vue的router.js是不需要的
vue:router.js
eggjs:router.js
注意访问下面两个路由的代码是没错的,但是在访问的时候
应该分别是:/public/dht_blog/index
/public/dht_platform/home
原因在于我的项目在多页面的时候进行的首页重定向
'use strict'; /** * @param {Egg.Application} app - egg application */ module.exports = app => { const { router, controller } = app; router.get('/', controller.home.index); router.get('/public/dht_blog/*', controller.home.dhtBlog); router.get('/public/dht_platform/*', controller.home.dhtPlatform); };
接下来是eggjs的控制部分也就是mvc中的C(controller) ,直接读取静态文件发送给前端
'use strict'; const path = require('path'); const fs = require('fs'); const Controller = require('egg').Controller; class HomeController extends Controller { async index() { // 纯静态资源方式和eggjs结合,eggjs提供静态资源功能并且提供代理转发 // 注意当多页面项目情况下需要配置多个前缀路由 const { ctx } = this; ctx.response.type = 'html'; ctx.body = fs.readFileSync(path.resolve(__dirname, '../public/index.html')); } async dhtBlog() { const { ctx } = this; ctx.response.type = 'html'; ctx.body = fs.readFileSync(path.resolve(__dirname, '../public/dht_blog.html')); } async dhtPlatform() { const { ctx } = this; ctx.response.type = 'html'; ctx.body = fs.readFileSync(path.resolve(__dirname, '../public/dht_platform.html')); } } module.exports = HomeController;
接下来就是页面访问了
-
-
vue 一个页面多个router-view如何配置子路由_vue-cli3 项目从搭建优化到docker部署
2020-12-04 04:01:33项目地址 vue-cli3-project 欢迎 star 原文地址 https://www.ccode.live/lentoo/list/9?from=art1. 创建一个vue项目 相信大部分人都已经知道怎么创建项目的,可以跳过这一节,看下一节。1.1 安装@vue/cli# 全局安装 ...项目地址 vue-cli3-project 欢迎 star
原文地址 https://www.ccode.live/lentoo/list/9?from=art1. 创建一个vue项目
相信大部分人都已经知道怎么创建项目的,可以跳过这一节,看下一节。
1.1 安装@vue/cli
# 全局安装 vue-cli脚手架 npm install -g @vue/cli
等待安装完成后开始下一步
1.2 初始化项目
vue create vue-cli3-project
- 选择一个预设
可以选择默认预设,默认预设包含了
babel
,eslint
我们选择更多功能
Manually select features
回车后来到选择插件
- 插件选择
这边选择了(Babel、Router、Vuex、Css预处理器、Linter / Formatter 格式检查、Unit测试框架)
- 路由模式选择
是否使用
history
模式的路由 (Yes)- 选择一个css预处理器 (Sass/SCSS)
- 选择一个eslint配置
这边选择
ESLint + Standard config
,个人比较喜欢这个代码规范- 选择什么时候进行
eslint
校验
选择(Lint on save)保存是检查
如果你正在使用的vscode编辑器的话,可以配置eslint插件进行代码自动格式化
7. 选择测试框架 (Mocha + Chai)
8. 选择将这些配置文件写入到什么地方 (In dedicated config files)
- 是否保存这份预设配置?(y)
选是的话,下次创建一个vue项目,可以直接使用这个预设文件,而无需再进行配置。
等待依赖完成
2. 全局组件自动注册
在
components
目录下创建一个global
目录,里面放置一些需要全局注册的组件。index.js
作用只要是引入main.vue
,导出组件对象在
components
中创建一个index.js
,用来扫描全局对象并自动注册。// components/index.js import Vue from 'vue' // 自动加载 global 目录下的 .js 结尾的文件 const componentsContext = require.context('./global', true, /.js$/) componentsContext.keys().forEach(component => { const componentConfig = componentsContext(component) /** * 兼容 import export 和 require module.export 两种规范 */ const ctrl = componentConfig.default || componentConfig Vue.component(ctrl.name, ctrl) })
最后在入口文件
main.js
中导入这个index.js
中就可以了3.路由自动引入
在
Vue
项目中使用路由,相信想熟的人已经很熟悉怎么使用了,要新增一个页面的话,需要到路由配置中配置该页面的信息。如果页面越来越多的话,那么如何让我们的路由更简洁呢?
3.1 拆分路由
根据不同的业务模块进行拆分路由
在每个子模块中导出一个路由配置数组
在根
index.js
中导入所有子模块3.2 自动扫描子模块路由并导入
当我们的业务越来越庞大,每次新增业务模块的时候,我们都要在路由下面新增一个子路由模块,然后在
index.js
中导入。那么如何简化这种操作呢?
通过上面的自动扫描全局组件注册,我们也可以实现自动扫描子模块路由并导入
4. 通过node来生成组件
作为前端开发者,放着
node
这么好用的东西如果不能运用起来,岂不是很浪费?虽然我们通过上面已经实现了组件的自动注册,不过每次新建组件的时候,都要创建一个目录,然后新增一个
.vue
文件,然后写template
、script
、style
这些东西,然后新建一个index.js
、导出vue组件、虽然有插件能实现自动补全,但还是很麻烦有木有。那么我们能不能通过
node
来帮助我们干这些事情呢?只要告诉node
帮我生成的组件名称就行了。其它的事情让node
来干4.1 通过node来生成组件
- 安装一下
chalk
,这个插件能让我们的控制台输出语句有各种颜色区分
npm install chalk --save-dev
在根目录中创建一个
scripts
文件夹,新增一个
generateComponent.js
文件,放置生成组件的代码、新增一个
template.js
文件,放置组件模板的代码 * template.js// template.js module.exports = { vueTemplate: compoenntName => { return `<template> <div class="${compoenntName}"> ${compoenntName}组件 </div> </template> <script> export default { name: '${compoenntName}' } </script> <style lang="scss" scoped> .${compoenntName} { } </style> ` }, entryTemplate: `import Main from './main.vue' export default Main` }
- generateComponent.js`
// generateComponent.js` const chalk = require('chalk') const path = require('path') const fs = require('fs') const resolve = (...file) => path.resolve(__dirname, ...file) const log = message => console.log(chalk.green(`${message}`)) const successLog = message => console.log(chalk.blue(`${message}`)) const errorLog = error => console.log(chalk.red(`${error}`)) const { vueTemplate, entryTemplate } = require('./template') const generateFile = (path, data) => { if (fs.existsSync(path)) { errorLog(`${path}文件已存在`) return } return new Promise((resolve, reject) => { fs.writeFile(path, data, 'utf8', err => { if (err) { errorLog(err.message) reject(err) } else { resolve(true) } }) }) } log('请输入要生成的组件名称、如需生成全局组件,请加 global/ 前缀') let componentName = '' process.stdin.on('data', async chunk => { const inputName = String(chunk).trim().toString() /** * 组件目录路径 */ const componentDirectory = resolve('../src/components', inputName) /** * vue组件路径 */ const componentVueName = resolve(componentDirectory, 'main.vue') /** * 入口文件路径 */ const entryComponentName = resolve(componentDirectory, 'index.js') const hasComponentDirectory = fs.existsSync(componentDirectory) if (hasComponentDirectory) { errorLog(`${inputName}组件目录已存在,请重新输入`) return } else { log(`正在生成 component 目录 ${componentDirectory}`) await dotExistDirectoryCreate(componentDirectory) // fs.mkdirSync(componentDirectory); } try { if (inputName.includes('/')) { const inputArr = inputName.split('/') componentName = inputArr[inputArr.length - 1] } else { componentName = inputName } log(`正在生成 vue 文件 ${componentVueName}`) await generateFile(componentVueName, vueTemplate(componentName)) log(`正在生成 entry 文件 ${entryComponentName}`) await generateFile(entryComponentName, entryTemplate) successLog('生成成功') } catch (e) { errorLog(e.message) } process.stdin.emit('end') }) process.stdin.on('end', () => { log('exit') process.exit() }) function dotExistDirectoryCreate (directory) { return new Promise((resolve) => { mkdirs(directory, function () { resolve(true) }) }) } // 递归创建目录 function mkdirs (directory, callback) { var exists = fs.existsSync(directory) if (exists) { callback() } else { mkdirs(path.dirname(directory), function () { fs.mkdirSync(directory) callback() }) } }
- 配置package.json
"new:comp": "node ./scripts/generateComponent"
- 执行
如果使用
npm
的话 就是npm run new:comp
如果使用
yarn
的话 就是yarn new:comp
4.2 通过node来生成页面组件
通过上面的逻辑代码我们可以通过
node
来生成组件了,那么也可以举一反三来生成页面组件。只需稍微修改一下生成组件代码的逻辑。 在scripts
目录下新建一个generateView.js
文件// generateView.js const chalk = require('chalk') const path = require('path') const fs = require('fs') const resolve = (...file) => path.resolve(__dirname, ...file) const log = message => console.log(chalk.green(`${message}`)) const successLog = message => console.log(chalk.blue(`${message}`)) const errorLog = error => console.log(chalk.red(`${error}`)) const { vueTemplate } = require('./template') const generateFile = (path, data) => { if (fs.existsSync(path)) { errorLog(`${path}文件已存在`) return } return new Promise((resolve, reject) => { fs.writeFile(path, data, 'utf8', err => { if (err) { errorLog(err.message) reject(err) } else { resolve(true) } }) }) } log('请输入要生成的页面组件名称、会生成在 views/目录下') let componentName = '' process.stdin.on('data', async chunk => { const inputName = String(chunk).trim().toString() /** * Vue页面组件路径 */ let componentVueName = resolve('../src/views', inputName) // 如果不是以 .vue 结尾的话,自动加上 if (!componentVueName.endsWith('.vue')) { componentVueName += '.vue' } /** * vue组件目录路径 */ const componentDirectory = path.dirname(componentVueName) const hasComponentExists = fs.existsSync(componentVueName) if (hasComponentExists) { errorLog(`${inputName}页面组件已存在,请重新输入`) return } else { log(`正在生成 component 目录 ${componentDirectory}`) await dotExistDirectoryCreate(componentDirectory) } try { if (inputName.includes('/')) { const inputArr = inputName.split('/') componentName = inputArr[inputArr.length - 1] } else { componentName = inputName } log(`正在生成 vue 文件 ${componentVueName}`) await generateFile(componentVueName, vueTemplate(componentName)) successLog('生成成功') } catch (e) { errorLog(e.message) } process.stdin.emit('end') }) process.stdin.on('end', () => { log('exit') process.exit() }) function dotExistDirectoryCreate (directory) { return new Promise((resolve) => { mkdirs(directory, function () { resolve(true) }) }) } // 递归创建目录 function mkdirs (directory, callback) { var exists = fs.existsSync(directory) if (exists) { callback() } else { mkdirs(path.dirname(directory), function () { fs.mkdirSync(directory) callback() }) } }
- 配置package.json 新增一个
scripts
脚本
"new:view": "node ./scripts/generateView"
- 执行
如果使用
npm
的话 就是npm run new:view
如果使用
yarn
的话 就是yarn new:view
5. axios封装
- 安装 axios
npm install axios --save // or yarn add axios
5.1 配置不同的环境
在根目录新建三个环境变量文件
分别输入不同的地址, 比如
dev
就写dev
的api地址、test
就写test
的api地址# // .env NODE_ENV = "development" BASE_URL = "https://easy-mock.com/mock/5c4c50b9888ef15de01bec2c/api"
接着在根目录中新建一个
vue.config.js
// vue.config.js module.exports = { chainWebpack: config => { // 这里是对环境的配置,不同环境对应不同的BASE_URL,以便axios的请求地址不同 config.plugin('define').tap(args => { args[0]['process.env'].BASE_URL = JSON.stringify(process.env.BASE_URL) return args }) } }
然后在
src
目录下新建一个api
文件夹,创建一个index.js
用来配置axios
的配置信息// src/api/index.js import axios from 'axios' import router from '../router' import { Message } from 'element-ui' const service = axios.create({ // 设置超时时间 timeout: 60000, baseURL: process.env.BASE_URL }) // post请求的时候,我们需要加上一个请求头,所以可以在这里进行一个默认的设置 // 即设置post的请求头为application/x-www-form-urlencoded;charset=UTF-8 service.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'' export default service
5.2 请求响应封装
import axios from 'axios' import router from '../router' import { Message } from 'element-ui' const service = axios.create({ // 设置超时时间 timeout: 60000, baseURL: process.env.BASE_URL }) /** * 请求前拦截 * 用于处理需要在请求前的操作 */ service.interceptors.request.use(config => { const token = localStorage.getItem('token') if (token) { config.headers['Authorization'] = token } return config }, (error) => { return Promise.reject(error) }) /** * 请求响应拦截 * 用于处理需要在请求返回后的操作 */ service.interceptors.response.use(response => { const responseCode = response.status // 如果返回的状态码为200,说明接口请求成功,可以正常拿到数据 // 否则的话抛出错误 if (responseCode === 200) { return Promise.resolve(response) } else { return Promise.reject(response) } }, error => { // 服务器返回不是 2 开头的情况,会进入这个回调 // 可以根据后端返回的状态码进行不同的操作 const responseCode = error.response.status switch (responseCode) { // 401:未登录 case 401: // 跳转登录页 router.replace({ path: '/login', query: { redirect: router.currentRoute.fullPath } }) break // 403: token过期 case 403: // 弹出错误信息 Message({ type: 'error', message: '登录信息过期,请重新登录' }) // 清除token localStorage.removeItem('token') // 跳转登录页面,并将要浏览的页面fullPath传过去,登录成功后跳转需要访问的页面 setTimeout(() => { router.replace({ path: '/login', query: { redirect: router.currentRoute.fullPath } }) }, 1000) break // 404请求不存在 case 404: Message({ message: '网络请求不存在', type: 'error' }) break // 其他错误,直接抛出错误提示 default: Message({ message: error.response.data.message, type: 'error' }) } return Promise.reject(error) }) export default service
Message
方法是element-ui
提供的一个消息提示组件、大家可以根据自己的消息提示组件进行替换5.3 断网处理
在响应拦截中添加处理逻辑
service.interceptors.response.use(response => { const responseCode = response.status // 如果返回的状态码为200,说明接口请求成功,可以正常拿到数据 // 否则的话抛出错误 if (responseCode === 200) { return Promise.resolve(response.data) } else { return Promise.reject(response) } }, error => { // 断网 或者 请求超时 状态 if (!error.response) { // 请求超时状态 if (error.message.includes('timeout')) { console.log('超时了') Message.error('请求超时,请检查网络是否连接正常') } else { // 可以展示断网组件 console.log('断网了') Message.error('请求失败,请检查网络是否已连接') } return } // 省略其它代码 ······ return Promise.reject(error) })
5.4 封装图片上传
// src/api/index.js export const uploadFile = formData => { const res = service.request({ method: 'post', url: '/upload', data: formData, headers: { 'Content-Type': 'multipart/form-data' } }) return res }
调用
async uploadFile (e) { const file = document.getElementById('file').files[0] const formdata = new FormData() formdata.append('file', file) await uploadFile(formdata) }
5.5 请求 显示 Loading 效果
let loading = null service.interceptors.request.use(config => { // 在请求先展示加载框 loading = Loading.service({ text: '正在加载中......' }) // 省略其它代码 ······ return config }, (error) => { return Promise.reject(error) }) service.interceptors.response.use(response => { // 请求响应后关闭加载框 if (loading) { loading.close() } // 省略其它代码 ······ }, error => { // 请求响应后关闭加载框 if (loading) { loading.close() } // 省略其它代码 ······ return Promise.reject(error) })
6. 巧用 Mixins
6.1 封装 store 公用方法
假设有这样一个场景,我们通过
vuex
封装了获取新闻列表的function
import Vue from 'vue' import Vuex from 'vuex' import { getNewsList } from '../api/news' Vue.use(Vuex) const types = { NEWS_LIST: 'NEWS_LIST' } export default new Vuex.Store({ state: { [types.NEWS_LIST]: [] }, mutations: { [types.NEWS_LIST]: (state, res) => { state[types.NEWS_LIST] = res } }, actions: { [types.NEWS_LIST]: async ({ commit }, params) => { const res = await getNewsList(params) return commit(types.NEWS_LIST, res) } }, getters: { getNewsResponse (state) { return state[types.NEWS_LIST] } } })
然后在新闻列表页,我们通过
mapAction
、mapGetters
来调用Action
和getters
我们需要写上这些代码import { mapActions, mapGetters } from 'vuex' computed: { ...mapGetters(['getNewsResponse']) }, methods: { ...mapActions(['NEWS_LIST']) }
在假设,在另一个页面又需要重新调用获取新闻列表的接口,我们又要在写一遍上面的代码对吧?
复制粘贴就是干有木有?
如果接口突然加了一个参数,那岂不是每个要用到这个接口的代码都得加这个参数。
复制粘贴一时爽,需求一改你就爽
既然是重复的代码,我们肯定要复用,这时候
Vue
提供的Mixin
就起了大作用了 * 封装 news-mixin.js 在src
下创建一个mixins
目录,用来管理所有的mixins 新建一个news-mixin.js
import { mapActions, mapGetters } from 'vuex' export default { computed: { ...mapGetters(['getNewsResponse']) }, methods: { ...mapActions(['NEWS_LIST']) } }
然后在需要用到的组件中引入这个
mixin
,就能直接调用这个方法了。不管多少个页面,只要引入这个mixin
,直接就能使用。需求一改的话,也只需要修改这个
mixin
文件// news/index.vue import Vue from 'vue' import newsMixin from '@/mixins/news-mixin' export default { name: 'news', mixins: [newsMixin], data () { return {} }, async created () { await this.NEWS_LIST() console.log(this.getNewsResponse) } }
6.2 扩展
除了封装
vuex
的公用方法,其实还有很多的东西也能做封装。例如:分页对象
,表格数据
,公用方法
、等等就不一一举例了。可以看github在多个地方经常使用,就可以考虑封装成
mixin
,不过请写好注释哦。不然就会有人在背后骂你了!!你懂的~~7. 优化
7.1 gzip压缩
- 安装
compression-webpack-plugin
插件
npm install compression-webpack-plugin --save-dev // or yarn add compression-webpack-plugin --dev
- 在 vue.config.js 中添加配置
// vue.config.js const CompressionPlugin = require('compression-webpack-plugin') module.exports = { chainWebpack: config => { // 这里是对环境的配置,不同环境对应不同的BASE_URL,以便axios的请求地址不同 config.plugin('define').tap(args => { args[0]['process.env'].BASE_URL = JSON.stringify(process.env.BASE_URL) return args }) if (process.env.NODE_ENV === 'production') { // #region 启用GZip压缩 config .plugin('compression') .use(CompressionPlugin, { asset: '[path].gz[query]', algorithm: 'gzip', test: new RegExp('.(' + ['js', 'css'].join('|') + ')$'), threshold: 10240, minRatio: 0.8, cache: true }) .tap(args => { }) // #endregion } } }
npm run build
后能看到生成.gz
文件就OK了。如果你的服务器使用nginx的话,nginx也需要配置开启GZIP
、下面会讲到如何在nginx
中开启GZIP
7.2 第三方库引用cdn
对于
vue
、vue-router
、vuex
、axios
和element-ui
等等这些不经常改动的库、我们让webpack
不对他们进行打包,通过cdn
引入,可以减少代码的大小、也可以减少服务器的带宽,更能把这些文件缓存到客户端,客户端加载的会更快。 * 配置vue.config.js
const CompressionPlugin = require('compression-webpack-plugin') module.exports = { chainWebpack: config => { // 省略其它代码 ······ // #region 忽略生成环境打包的文件 var externals = { vue: 'Vue', axios: 'axios', 'element-ui': 'ELEMENT', 'vue-router': 'VueRouter', vuex: 'Vuex' } config.externals(externals) const cdn = { css: [ // element-ui css '//unpkg.com/element-ui/lib/theme-chalk/index.css' ], js: [ // vue '//cdn.staticfile.org/vue/2.5.22/vue.min.js', // vue-router '//cdn.staticfile.org/vue-router/3.0.2/vue-router.min.js', // vuex '//cdn.staticfile.org/vuex/3.1.0/vuex.min.js', // axios '//cdn.staticfile.org/axios/0.19.0-beta.1/axios.min.js', // element-ui js '//unpkg.com/element-ui/lib/index.js' ] } config.plugin('html') .tap(args => { args[0].cdn = cdn return args }) // #endregion } } }
- 修改
index.html
<!--public/index.html--> <!DOCTYPE html> <html lang="en"> <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"> <% if (process.env.NODE_ENV === 'production') { %> <% for(var css of htmlWebpackPlugin.options.cdn.css) { %> <link href="<%=css%>" rel="preload" as="style"> <link rel="stylesheet" href="<%=css%>" as="style"> <% } %> <% for(var js of htmlWebpackPlugin.options.cdn.js) { %> <link href="<%=js%>" rel="preload" as="script"> <script src="<%=js%>"></script> <% } %> <% } %> <title>vue-cli3-project</title> </head> <body> <noscript> <strong>We're sorry but vue-cli3-project doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> </noscript> <div id="app"></div> <!-- built files will be auto injected --> </body> </html>
7.3 全站cdn
我们已经把第三方库使用
cdn
替代了,那么我们build
后生成的js
,css
之类的文件能否也用cdn
呢?申请自己的cdn域名
要想把自己的资源上传到
cdn
上,前提是得有自己的cdn
域名,如果没有的话,可以到七牛云官网上注册申请一个 1. 注册七牛云账号 2. 到七牛云对象存储模块中新建存储空间 3. 输入存储空间信息4. 确定创建 5. 创建成功后会跳转到这个存储空间的控制台页面
6. 其中有个域名就是你的测试域名 7. 我们可以在内容管理那上传我们的
js
、css
之类的文件、不过我们的文件那么多,一个一个上传明显不合理。要你你也不干。这时候,这些批量又重复的操作应该由我们的
node
出马,让我们来通过node
来批量上传我们的资源文件将生成的js、css资源上传到七牛cdn
在七牛云官网的文档中心有介绍如何通过
node
上传文件、感兴趣的人可以自己去研究一下。- 查看
AccessKey
和SecretKey
,在你的个人面板 -> 秘钥管理 ,这两个秘钥待会会用到
- 安装需要的插件
npm install qiniu glob mime --save-dev
- 在
scripts
目录下创建一个upcdn.js
文件
// /scripts/upcdn.js const qiniu = require('qiniu') const glob = require('glob') const mime = require('mime') const path = require('path') const isWindow = /^win/.test(process.platform) let pre = path.resolve(__dirname, '../dist/') + (isWindow ? '' : '') const files = glob.sync( `${path.join( __dirname, '../dist/**/*.?(js|css|map|png|jpg|svg|woff|woff2|ttf|eot)' )}` ) pre = pre.replace(//g, '/') const options = { scope: 'source' // 空间对象名称 } var config = { qiniu: { accessKey: '', // 个人中心 秘钥管理里的 AccessKey secretKey: '', // 个人中心 秘钥管理里的 SecretKey bucket: options.scope, domain: 'http://ply4cszel.bkt.clouddn.com' } } var accessKey = config.qiniu.accessKey var secretKey = config.qiniu.secretKey var mac = new qiniu.auth.digest.Mac(accessKey, secretKey) var putPolicy = new qiniu.rs.PutPolicy(options) var uploadToken = putPolicy.uploadToken(mac) var cf = new qiniu.conf.Config({ zone: qiniu.zone.Zone_z2 }) var formUploader = new qiniu.form_up.FormUploader(cf) async function uploadFileCDN (files) { files.map(async file => { const key = getFileKey(pre, file) try { await uploadFIle(key, file) console.log(`上传成功 key: ${key}`) } catch (err) { console.log('error', err) } }) } async function uploadFIle (key, localFile) { const extname = path.extname(localFile) const mimeName = mime.getType(extname) const putExtra = new qiniu.form_up.PutExtra({ mimeType: mimeName }) return new Promise((resolve, reject) => { formUploader.putFile(uploadToken, key, localFile, putExtra, function ( respErr, respBody, respInfo ) { if (respErr) { reject(respErr) } resolve({ respBody, respInfo }) }) }) } function getFileKey (pre, file) { if (file.indexOf(pre) > -1) { const key = file.split(pre)[1] return key.startsWith('/') ? key.substring(1) : key } return file } (async () => { console.time('上传文件到cdn') await uploadFileCDN(files) console.timeEnd('上传文件到cdn') })()
修改 publicPath
修改
vue.config.js
的配置信息,让其publicPath
指向我们cdn
的域名const IS_PROD = process.env.NODE_ENV === 'production' const cdnDomian = 'http://ply4cszel.bkt.clouddn.com' module.exports = { publicPath: IS_PROD ? cdnDomian : '/', // 省略其它代码 ······· }
修改package.json配置
修改package.json配置,使我们
build
完成后自动上传资源文件到cdn服务器
"build": "vue-cli-service build --mode prod && node ./scripts/upcdn.js",
运行查看效果
npm run build
然后到你的
cdn
控制台的内容管理看看文件是否已经上传成功8. docker部署
这边使用的是
centOS7
环境,不过使用的是不同的系统,可以参考一下其它系统的安装方法8.1 安装docker
- 更新软件库
yum update -y
- 安装docker
yum install docker
- 启动docker服务
service docker start
- 安装docker-compose
// 安装epel源 yum install -y epel-release // 安装docker-compose yum install docker-compose
8.2 编写docker-compose.yaml
version: '2.1' services: nginx: restart: always image: nginx volumes: #~ /var/local/nginx/nginx.conf为本机目录, /etc/nginx为容器目录 - /var/local/nginx/nginx.conf:/etc/nginx/nginx.conf #~ /var/local/app/dist 为本机 build 后的dist目录, /usr/src/app为容器目录, - /var/local/app/dist:/usr/src/app ports: - 80:80 privileged: true
8.3 编写 nginx.conf 配置
#user nobody; worker_processes 2; #工作模式及连接数上线 events { worker_connections 1024; #单个工作进程 处理进程的最大并发数 } http { include mime.types; default_type application/octet-stream; #sendfile 指令指定 nginx 是否调用 sendfile 函数(zero copy 方式)来输出文件,对于普通应用, sendfile on; #tcp_nopush on; #keepalive_timeout 0; keepalive_timeout 65; # 开启GZIP gzip on; # # 监听 80 端口,转发请求到 3000 端口 server { #监听端口 listen 80; #编码格式 charset utf-8; # 前端静态文件资源 location / { root /usr/src/app; index index.html index.htm; try_files $uri $uri/ @rewrites; } # 配置如果匹配不到资源,将url指向 index.html, 在 vue-router 的 history 模式下使用,就不会显示404 location @rewrites { rewrite ^(.*)$ /index.html last; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } }
8.4 执行 docker-compose
docker-compose -d up
8.5 docker + jenkins 自动化部署
使用
docker
+jenkins
能实现代码提交到github后自动部署环境、这个要讲起来内容太多,有兴趣的可以看我这一篇文章从零搭建docker+jenkins+node.js自动化部署环境
6. 扩展
- 使用pm2自动化部署node项目
- 通过vue-cli3构建一个SSR应用程序
如果大家还有什么更好的实践方式,欢迎评论区指教!!
项目地址 vue-cli3-project 欢迎 star
原文地址 https://www.ccode.live/lentoo/list/9?from=art欢迎关注
欢迎关注公众号“码上开发”,每天分享最新技术资讯
-
【最新】小白通过nginx部署vue项目到CentOS
2020-07-09 12:33:51这两天想试一下怎么部署vue项目,可怜我这个小白一点经验都没,踩了很多坑,以此记录一下我配置的过程,希望能帮到其他人。对很多原理不了解,希望大佬们能够指出。 配置情况说明: 软件 说明 服务器:... -
vue2项目部署tomcat服务器
2017-08-24 15:17:00最近开发项目一直遇到一个问题就是vue2的项目打包之后的静态资源怎么部署在tomcat 经过一段时间的研究后,最后解决了这个问题,现在分享给打下 第一步 就是执行 npm run dev 第二步 执行 npm run build 这个不多... -
【全栈项目上线(vue+node+mongodb)】04. 怎么在一台主机上面部署多个网站,详细操作指南...
2017-10-31 09:34:15怎么在一台主机上面部署多个网站 使用Nginx的虚拟化配置 环境 使用一键安装lnmp环境请参考 https://segmentfault.com/a/11... 第一步:执行 lnmp vhost add lnmp vhost add 输入自己要绑定的域名,比如我现在需要... -
webpack打包vue项目之后生成的dist文件该怎么启动运行
2018-04-17 22:45:16进入该vue项目目录,打开git bash,执行:npm run build(在package.json的scripts配置)执行成功如下图所示:然后此时你会发现项目下多了一个 dist 文件夹,dist下文件便是项目打包之后生成的文件。此时我们直接在... -
详解webpack打包vue项目之后生成的dist文件该怎么启动运行
2020-12-12 19:49:21亲测,webpack打包vue项目之后生成的dist文件可以部署到 express 服务器上运行。 我的vue项目结构如下: 1. 进入该vue项目目录,打开git bash,执行:npm run build(在package.json的scripts配置) 执行成功如下... -
vue-cli3 项目从搭建优化到docker部署的方法
2020-12-08 20:20:351. 创建一个vue项目 相信大部分人都已经知道怎么创建项目的,可以跳过这一节,看下一节。 1.1 安装@vue/cli # 全局安装 vue-cli脚手架 npm install -g @vue/cli 等待安装完成后开始下一步 1.2 初始化项目 vue ... -
py文件怎么运行_前端面试:webpack打包vue项目之后生成的dist文件该怎么启动运行...
2020-12-04 21:10:09进入该vue项目目录,打开git bash,执行:npm run build(在package.json的scripts配置)执行成功如下图所示:然后此时你会发现项目下多了一个 dist 文件夹,dist下文件便是项目打包之后生成的文件。此时我们直接在... -
怎么把使用vuepress搭建的博客部署到Github Pages
2019-09-25 05:14:45推荐在这里阅读效果更佳 背景 网上搜了很多教程,包括官网的教程,但是...你的 vuepress 项目是否已经在github上的仓库下 如果是,请跳到第二步 如果不是,想在GitHub新建一个仓库,如图所示: ## 小坑 仓库名字要和... -
关于vue项目打包部署到nginx服务器,由于app.js文件过大导致首次加载速度过慢的解决办法
2019-10-22 17:16:17很多时候,一个vue项目打包下来,app.js 主文件都会有几兆,大点的项目都会有十几二十兆,还有app.css的打包文件可能也会很大。 对于一般的服务器来说,首次去打开部署好的平台页面,加载起来会很慢。 这样的速度... -
Linux+Nginx+Vue+uwsgi+Django前后端分离项目部署
2019-12-02 15:52:52手上有个项目是vue+django的模式,需求是vue部署到一台服务器上,django部署到另外一台服务器上 第一步:安装nginx.......怎么安装请谷歌,在此不做赘述(有很多类似的教程) 第二步:找到nginx的配置文件:/etc/... -
vue-cli怎么和express搭建项目!
2018-10-26 16:03:571.其实自动解除vue一来,就一直在想这个问题,问题是:express后台有一个服务是3000端口,然后vue-cli又开启了一个8080端口, 那么怎么把他们两个结合在一起呢? 要跨域吗? 部署到服务器的时候应该运行这个npm run dev的... -
使用 Nginx 部署前后端分离项目,解决跨域问题
2019-09-24 09:50:28前后端分离这个问题其实松哥和大家聊过很多了,上周松哥把自己的两个开源项目部署在服务器上以帮助大家可以快速在线预览(喜大普奔,两个开源的 Spring Boot + Vue 前后端分离项目可以在线体验了),然后群里就有小... -
Gin-vue-admin是一个基于vue和gin开发的全栈前后端分离的后台管理系统,集成jwt鉴权,动态路由,动态菜单,casbin鉴权,表单生成器,代码生成器等功能,提供多种示例文件,让您把更多时间专注在业务开发上。...
-
前后端分离项目部署_撸一个前后端分离的项目
2021-01-13 00:16:00如果让一个专业的前端工程师来写前端页面,其实也不难,Vue 算是三大前端框架中最容易上手的了。那怎么样就有难度了呢?让同一个人既写前端又写后端!我知道很多小伙伴在这里总是想不通,前后端是怎么通信的?跨域是... -
自己在写公司项目时封装了这个组件,它省去了初始化 UEditor、手动调用 getContent,setContent 等繁琐的操作,而是直接采用 v-model 来绑定数据,使得在 Vue 项目中的使用UEditor 可以像 Input 框一样简单。...
-
前后端分离项目如何部署_撸一个前后端分离的项目
2020-12-02 17:14:38如果让一个专业的前端工程师来写前端页面,其实也不难,Vue 算是三大前端框架中最容易上手的了。那怎么样就有难度了呢?让同一个人既写前端又写后端!我知道很多小伙伴在这里总是想不通,前后端是怎么通信的?跨域是... -
前后端分离的项目部署到tomcat_DncZeus前后端分离项目打包/发布/部署及注意事项...
2020-12-30 21:53:23DncZeus前后端分离项目打包/发布/部署及注意事项前言DncZeus这个基于ASP.NET Core + Vue.js前后端分离的通用后台管理框架从发布到现在已有大半年时间了,期间很多使用者问到DncZeus项目怎么打包,怎么发布,怎么部署... -
docker部署项目(一):环境安装
2020-06-09 10:36:11我们之前的文章,用springboot+vue+redis简单写了一个前后端分离的后台管理系统。 那么问题来了。如果要部署到阿里云服务器怎么弄呢。如果是传统的部署方式,肯定是要在服务器按照顺序安装数据库mysql,tocat,nginx... -
Docker容器化部署尝试——多容器通信(node+mongoDB+nginx)
2021-01-10 07:56:50想要部署一个mocker平台,就在朋友的推荐下选择了 api-mocker 这个现成的项目 该项目分为服务端node、客户端vue、以及数据库mongoDB 在尝试直接部署的时候发现需要装一大堆的环境,node、mongo、nginx啊,特别的麻烦... -
基于 Vue 技术栈的微前端方案实践
2020-12-09 02:35:13最终会将整个前端项目拆解成一个主项目和多个子项目,其中两者作用如下: <ul><li> 主项目:用于管理子项目的路由切换、注册子项目的路由和全局 Store 层、提供全局库和方法 </li><li> 子项目... -
使用vueAdmin开发后台管理系统(登录篇)
2020-07-06 10:07:13我自己的前端学的不怎么样,可以说是个半吊子,只能粗略的用一下,文章主要是针对那些对后端比较了解,但是前端了解的比较少,只需要会用就行的人,帮你们少走点弯路,都是自己踩了很多坑走过来的。 前面几段是根据... -
nginx + ubuntu 部署踩坑
2020-07-07 12:05:03最近在Ubuntu上部署springboot + vue.js 的项目的时候遇到了两个坑。 1 配置nginx配置文件的时候,默认的配置文件会引入sites-enabled 目录下的配置文件,这个文件里面指定的主页是 /usr/shar/nginx/...
-
Windows系统管理
-
怎样使用代理服务器上网?
-
WPF 多屏幕鼠标区域限制软件
-
MaxScale 实现 MySQL 读写分离与负载均衡
-
MySQL 开启数据库定时器
-
华为1+X认证——网络系统建设与运维(初级)
-
罗密欧与朱丽叶
-
Docker从入门到精通
-
在 Angular 项目中,如何为项目单独创建路由文件?
-
中央广播电视大学《软件工程》期末总复习资料(含答案).pdf
-
docker中宿主机与容器(container)互相拷贝传递文件的方法
-
工程制图 AutoCAD 2012 从二维到三维
-
llustrator CC2018软件安装
-
Galera 高可用 MySQL 集群(PXC v5.7+Hapro)
-
项目管理工具与方法
-
4---Mochi_Business商业计划书.pdf
-
rabbitMQ面试题(持续更新)
-
linux基础入门和项目实战部署系列课程
-
中央广播电视大学《网络实用技术基础(专科)》期末总复习资料(含答案).pdf
-
供配电系统外文翻译.doc