本博文记录作者学习Vue的一个过程,长期更新!希望能帮助大家
最近作者的朋友准备学习前端,学完html、css、js后就不知道改如何下手。于是我建议他学习Vue。前后端分离时代要学的知识非常的多,不仅要求基本知识扎实,也强迫每一个学者持之以恒的学习。加油!
Vue-Cli脚手架3.0版本与2.0版本没有什么太大的区别,脚手架的结构做了调整
npm,它是随node.js安装的,装了node.js也就有了它
node.js安装下载地址
# 检查node.js是否安装,若有则显示版本号
$ node -v
# 检查npm的版本号
$ npm -v
安装淘宝镜像cnpm,因为在墙内,有时候使用npm安装会很慢
# 安装cnpm,并指定镜像地址
$ npm install -g cnpm --registry=https://registry.npm.taobao.org
# 最新稳定版
$ npm install vue
# 同时安装它的命令行工具
$ npm install --global vue-cli
安装好之后我们接下来就使用它的命令行工具vue-cli构建项目
在桌面创建一个文件夹,cmd命令进入到文件夹内初始化项目
# 去到放项目的文件夹地址
C:> cd /Users/Vue-Demo
# 创建基于webpack模版的项目,名称为vue-demo
C:\Users\Vue-Demo> vue init webpack vue-demo
# 提示我有新版本
A newer version of vue-cli is available.
latest: 2.8.2
installed: 2.8.1
This will install Vue 2.x version of the template.
# 提示我如果需要使用webpack#1.0的话,创建时用这个命令
For Vue 1.x use: vue init webpack#1.0 vue-demo
# 填写了一些基础信息,根据你的需要选择
# 这里我用了ESLint,标准选择了默认的Standard,不熟悉ESLint的话建议不启用或标准选择none,我是给自己挖坑的,玩玩,我不熟。
# 这里我不启动unit测试和e2e测试
? Project name vue-demo
//项目简介
? Project description This is a demo
//项目作者
? Author XXX
? Vue build standalone
//是否安装Vue路由模块,建议安装
? Install vue-router? Yes
//是否安装ESLint模块,建议安装
? Use ESLint to lint your code? Yes
? Pick an ESLint preset Standard
? Setup unit tests with Karma + Mocha? No
? Setup e2e tests with Nightwatch? No
vue-cli · Generated "vue-demo".
To get started:
cd vue-demo
npm install
npm run dev
Documentation can be found at https://vuejs-templates.github.io/webpack
在个性化定制的过程中,router和Eslint都可以在项目初始化的时候就依赖进来,其余可以更具自己的需求
首先运行 npm install安装所需依赖,然后运行npm run dev 命令运行vue项目
C:> cd /Users/Vue-Demo/vue-demo
C:\Users\Vue-Demo\vue-demo>npm run dev
Starting dev server…
Listening at http://localhost:8080
打开浏览器,输入http://localhost:8080查看效果
vue-cli2.0 在config文件夹下的index.js里面修改,vue-cli3.0在根目录下的vue.config.js里面修改
vue-cli2.0
module.exports = {
dev: {
// Paths
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {
},
// Various Dev Server settings
host: 'localhost', // can be overwritten by process.env.HOST
port: 8080, //此处修改为8081端口,vue项目将会在8081端口运行
autoOpenBrowser: false,
errorOverlay: true,
notifyOnErrors: true,
},
接触过vue的同学应该都知道,用vue-cli开发vue的项目十分方便,它可以帮你快速构建一个具有强大构建能力的Vue.js项目
.
|-- build // 项目构建(webpack)相关代码
| |-- build.js // 生产环境构建代码
| |-- check-version.js // 检查node、npm等版本
| |-- utils.js // 构建工具相关
| |-- webpack.base.conf.js // webpack基础配置
| |-- webpack.dev.conf.js // webpack开发环境配置
| |-- webpack.prod.conf.js // webpack生产环境配置
|-- config // 项目开发环境配置
| |-- dev.env.js // 开发环境变量
| |-- index.js // 项目一些配置变量
| |-- prod.env.js // 生产环境变量
|-- src // 源码目录
| |-- assets // vue静态资源图片Logo
| |-- mixin // vue混入的配置(可以先不看)
| |-- router // vue路由
| |-- store // vuex的配置(可以先不看)
| |-- components // vue公共组件
|-- views // 可以存放页面
| |-- App.vue // 页面入口文件
| |-- main.js // 程序入口文件,加载各种公共组件
|-- static // 静态文件,比如一些图片,json数据等
| |-- data // 群聊分析得到的数据用于数据可视化
|-- .babelrc // ES6语法编译配置
|-- .editorconfig // 定义代码格式
|-- .gitignore // git上传需要忽略的文件格式
|-- README.md // 项目说明
|-- favicon.ico
|-- index.html // 入口页面
|-- package.json // 项目基本信息
.
一般一个初步的Vue项目创建好之后都会有这三个文件:index.html 、main.js 、App.js
index.html
Vue是单页面形式开发,而这个index.html文件在其中起着特别重要的作用。所有组件(后缀名为.vue都被视为组件)都会通过此文件进行渲染加载,很少会在这里面进行大量的代码二次编写
相当于一个C/Java中的入口函数。控制着初次启动Vue项目要加载的组件
(1)import A from ‘B’ 这类语句相当于引入B(这一般是路径)然后给它起个名字叫做A
(2)Vue.user() 全局方法定义 。也就是说,定义以后,你可以在这个Vue项目的任意地方使用该组件
(3)el: ‘#app’ 这个和index.html的(id=“app”)挂钩
开发模式:npm run dev是前端自己开发用的
生产模式:npm run build 打包之后给后端放在服务端上用的
如果没有这行代码,或者设置为true,控制台就会多出这么一段代码
You are running Vue in development mode.
Make sure to turn on production mode when deploying for production.
运行的Vue是开发模式。为生产部署时,请确保启用生产模式!!
vue每个组件都是独立的,每个组件都有一个属于它的生命周期,从一个组件创建、数据初始化、挂载、更新、销毁,这就是一个组件所谓的生命周期。
1.beforeCreate
在实例初始化之后,数据观测(data observer) 和 event/watcher 事件配置之前被调用
2.created
实例已经创建完成之后被调用。在这一步,实例已完成以下的配置:数据观测(data observer),属性和方法的运算, watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。
3.beforeMount
在挂载开始之前被调用:相关的 render 函数(模板)首次被调用。 例如通过v-for生成的html还没有被挂载到页面上
4.mounted
el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。 有初始值的DOM渲染,例如我们的初始数据list,渲染出来的li,只有这里才能获取
5.beforeUpdate
数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前。 你可以在这个钩子中进一步地更改状态,这不会触发附加的重渲染过程。 当我们更改Vue的任何数据,都会触发该函数
6.updated
由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。 当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态,因为这可能会导致更新无限循环。 该钩子在服务器端渲染期间不被调用。
7.beforeDestroy
实例销毁之前调用。在这一步,实例仍然完全可用。
8.destroyed
Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。 该钩子在服务器端渲染期间不被调用。
路由,其实就是指向的意思,当我点击页面上的login按钮时,页面中就要显示login的内容,如果点击页面上的home按钮,页面中就要显示home的内容。login按钮 => login内容, home按钮 => home内容,也可以说是一种映射. 所以在页面上有两个部分,一个是点击部分,一个是点击之后,显示内容的部分。
首先要定义route, 一条路由的实现。它是一个对象,由两个部分组成: path和component. path 指路径,component 指的是组件。
const routes = [
{
path: '/',
component: Login,
beforeEnter: (to, from, next) => {
console.log("input")
next()
},
beforeLeave: (to, from, next) => {
console.log("output")
next()
}
},
{
path: '/main',
component: MainPage
}
]
创建router 对路由进行管理,它是由构造函数 new vueRouter() 创建,接受routes 参数
export default new Router({
mode: 'history',
routes: routes
})
配置完成后,把router 实例注入到 vue 根实例中,就可以使用路由了 ==>main.js
new Vue({
el: '#app',
*router:router,*
store,
components: {
App },
template: ' '
})
当用户点击 router-link 标签时,会去寻找它的 to 属性, 它的 to 属性和 js 中配置的路径{ path: ‘/main’, component: main} path 对应,从而找到了匹配的组件, 最后把组件渲染到 router-view 标签所在的地方。所有的这些实现才是基于hash 实现的。
当我们去访问网站并登录成功后,它会显示 欢迎你 + 你的名字。不同的用户登录, 只是显示“你的名字” 部分不同,其它部分是一样的
<template>
<div id="app">
<header>
<!-- 增加两个到user组件的导航,可以看到这里使用了不同的to属性 -->
<router-link to="/main/123">main123</router-link>
<router-link to="/main/456">main456</router-link>
</header>
<router-view></router-view>
</div>
</template>
router.js 配置user动态路由
const routes = [
{
path: '/',
component: Login,
beforeEnter: (to, from, next) => {
console.log("input")
next()
},
beforeLeave: (to, from, next) => {
console.log("output")
next()
}
},
{
path: '/main/:id',
component: MainPage
}
]
获取传递参数
<template>
<div>
<div>动态部分是{
{
getId}}</div>
</div>
</template>
<script>
export default {
computed: {
getId() {
return this.$route.params.id
}
}
}
</script>
嵌套路由,主要是由我们的页面结构所决定的。当我们进入到main页面的时候,它下面还有分类的话
const routes = [
{
path: '/',
component: Login,
beforeEnter: (to, from, next) => {
console.log("input")
next()
},
beforeLeave: (to, from, next) => {
console.log("output")
next()
}
},
{
path: '/main/:id',
component: MainPage,
// 子路由
children: [
{
path: "phone",
component: phone
},
{
path: "tablet",
component: tablet
},
{
path: "computer",
component: computer
}
]
}
]
嵌套路由的组件和之前一样,必选全部引入进来,访问main下的tablet页面:/main/tablet
this.$router.push("/main")
vue中路由守卫一共有三种,一个全局路由守卫,一个是组件内路由守卫,一个是router独享守卫
想要进入一个路由,都会经过全局路由守卫
全局路由守卫有个两个:一个是全局前置守卫,一个是全局后置守卫
router.beforeEach((to, from, next) => {
console.log(to) => // 到哪个页面去?
console.log(from) => // 从哪个页面来?
next() => // 一个回调函数
}
router.afterEach(to,from) = {
}
next():回调函数参数配置
next(false): 中断当前的导航。如果浏览器的 URL 改变了 URL 地址会重置到 from 路由对应的地址
next('/') or next({
path: '/' }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航
组件路由守卫是写在每个单独的vue文件里面的路由守卫
// 跟methods: {}等同级
beforeRouteEnter (to, from, next) {
// 注意,在路由进入之前,组件实例还未渲染,所以无法获取this实例,只能通过vm来访问组件实例
next(vm => {
})
}
beforeRouteUpdate (to, from, next) {
// 同一页面,刷新不同数据时调用,
}
beforeRouteLeave (to, from, next) {
// 离开当前路由页面时调用
}
路由独享守卫是在路由配置页面单独给路由配置的一个守卫
const routes = [
{
path: '/',
component: Login,
beforeEnter: (to, from, next) => {
console.log("input")
next()
},
beforeLeave: (to, from, next) => {
console.log("output")
next()
}
},
{
path: '/main/:id',
component: MainPage,
beforeEnter: (to, from, next) => {
// ...
}
}
]
利用 npm 安装 npm install axios --save
在项目初始化的时候如果选了axios依赖,则不需要安装
axios所需要的url是后端写的接口的地址。开发时需要和后端人员确定
//通过给定的ID来发送请求
axios.get('/main?ID=12345')
.then(function(response){
console.log(response);
})
.catch(function(err){
console.log(err);
});
//以上请求也可以通过这种方式来发送
axios.get('/user',{
params:{
ID:12345
}
})
.then(function(response){
console.log(response);
})
.catch(function(err){
console.log(err);
});
axios.post('/user',{
firstName:'Fred',
lastName:'Flintstone'
})
.then(function(res){
console.log(res);
})
.catch(function(err){
console.log(err);
});
在请求、响应在到达then/catch之前拦截
//添加一个请求拦截器
axios.interceptors.request.use(function(config){
//在请求发出之前进行一些操作
return config;
},function(err){
//Do something with request error
return Promise.reject(error);
});
//添加一个响应拦截器
axios.interceptors.response.use(function(res){
//在这里对返回的数据进行处理
return res;
},function(err){
//Do something with response error
return Promise.reject(error);
})
添加拦截器
var TEST = axios.create();
TEST .interceptors.request.use(function(){
})
在vue-cli项目中新建util文件夹,存放开发工具代码
新建request.js,复制
import axios from 'axios'
import router from '@/router'
const http = axios.create({
baseURL: http://XXXX/,
timeout: 1000 * 180,
})
/**
* 请求拦截
*/
http.interceptors.request.use(config => {
//逻辑代码....
return config
}, error => {
return Promise.reject(error)
})
/**
* 响应拦截
*/
http.interceptors.response.use(response => {
if (response.data.code === 401 || response.data.code === 10001) {
clearLoginInfo()
router.replace({
name: 'login'})
return Promise.reject(response.data.msg)
}
return response
}, error => {
console.error(error)
return Promise.reject(error)
})
export default http
整合Element使用,因为我的项目是搭配element-ui使用的,所以先写这里,不了解的可以先看看,后面有教程
<template>
<div class="jarClass">
<!--新增驱动-->
<el-form label-width="100px" :rules="rules" :model="dataSouseInfo" ref="add" class="demo-form-inline">
<el-row>
<el-col :span="24">
<el-form-item label="jdbcUrl:" prop="jdbcUrl">
<el-input
type="textarea"
:autosize="{ minRows: 4, maxRows: 8}"
placeholder="请输入内容"
v-model="dataSouseInfo.jdbcUrl">
</el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="8" :offset="16">
<el-button class="buttonClass" type="primary" @click="add()" size="small">新增</el-button>
<el-button class="buttonClass" @click="remove()" size="small">取消</el-button>
</el-col>
</el-row>
</el-form>
</div>
</template>
<script>
export default {
name: "jarcomponts",
props: ['parent'],
data() {
return {
dataSouseInfo: {
databaseName: '',
fileName: '',
className: '',
desc: '',
jdbcUrl: '',
},
};
},
methods: {
url(){
return window.SITE_CONFIG['apiURL'] + "/jar/upload"
},
add() {
let url = '/jar/save'
this.$refs["add"].validate((valid) => {
if (valid) {
console.log(this.dataSouseInfo)
this.$http.post(url, this.dataSouseInfo).then((res) => {
console.log(res)
if (res.data.statu == '200') {
this.$message({
message: '成功',
type: 'success'
});
this.remove()
} else {
this.$message({
message: '失败',
type: 'danger'
});
this.remove()
}
})
}
})
},
}
}
</script>
<style scoped>
.buttonClass {
width: 80px;
}
</style>
vuex官网的解释是:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
npm install vuex --save
项目目录src下新建store目录和store.js文件
通常store对象都包含4个属性:state,getters,actions,mutations
state (类似存储全局变量的数据)
getters (提供用来获取state数据的方法)
actions (提供跟后台接口打交道的方法,并调用mutations提供的方法)
mutations (提供存储设置state数据的方法)
store.js
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export default new Vuex.Store({
//state (类似存储全局变量的数据)
state: {
cityname: 'jingjiang'
},
//getters (提供用来获取state数据的方法)
getters: {
// 参数列表state指的是state数据
getCityName(state) {
return state.cityname
}
},
//mutations (提供存储设置state数据的方法)
mutations: {
// name传递过来的数据
setCityName(state,name) {
state.cityname = name
}
},
// actions (提供跟后台接口打交道的方法,并调用mutations提供的方法)
actions: {
// state指的是state数据
// commit调用mutations的方法
// name就是调用此方法时要传的参数
setCity({
commit, state}, name) {
commit('setCityName',name)
}
}
})
在main.js中引用vuex
import store from './store/index.js';
new Vue({
el: '#app',
router:router,
store,
components: {
App },
template: ' '
})
在任意组件中使用
通过调用this.$store.getters.getCityName可以获取到state里面定义的城市名
通过调用this.$store.dispatch("setCity",'shanghai')可以修改state里面定义的城市名
<template>
<div class="divClass">
<h1>Vuex实例演示</h1>
</div>
</template>
<script>
import {
mixin} from "../mixin/mixin";
export default {
name: "login",
mixins:[mixin],
data() {
return {
cityname: '',
}
},
methods: {
show() {
this.$store.dispatch("setCity",'shanghai')
//alert(this.$store.getters.getCityName)
},
mounted() {
alert(this.$store.getters.getCityName)
}
}
</script>
Mixins是一种分发Vue组件中可复用功能的非常灵活的一种方式。当页面的风格不用,但是执行的方法和需要的数据类似,即可使用mixins
在项目的src目录下新建mixin文件夹,定义一个全局需要混入的对象mixin.js
export const mixin = {
data(){
return{
testName:'hello mixin',
}
},
methods:{
getName(){
console.log(this.testName)
}
}
}
把混入对象混入到当前的组件中
import {
mixin} from "../mixin/mixin";
<template>
<div class="divClass">
<el-button type="primary" @click="get()">Mixin</el-button>
</div>
</template>
<script>
import {
mixin} from "../mixin/mixin";
export default {
name: "login",
mixins:[mixin],
data() {
return {
}
},
methods: {
get(){
this.getName()
},
}
</script>
引入mixin之后,这个vue组件便拥有了mixin.js里面写的方法
当组件和混入对象含有同名选项时,这些选项将以恰当的方式混合
数据对象
mixin的数据对象和组件的数据发生冲突时以组件数据优先
var mixin = {
data: function () {
return {
mes: 'hello',
foo: 'abc'
}
}
}
new Vue({
mixins: [mixin],
data: function () {
return {
mes: 'goodbye',
bar: 'def'
}
},
created: function () {
console.log(this.$data)
// => { mes: "goodbye", foo: "abc", bar: "def" }
}
})
钩子函数
同名钩子函数将会混合为一个数组,都将被调用到,但是混入对象的钩子将在组件自身钩子之前调用
var mixin = {
created: function () {
console.log('混入对象')
}
}
new Vue({
mixins: [mixin],
created: function () {
console.log('组件钩子')
}
})
// => "混入对象"
// => "组件钩子"
值为对象的选项
值为对象的选项,例如 methods, components 和 directives,将被混合为同一个对象。两个对象键名冲突时,取组件对象的键值对。
var mixin = {
methods: {
test: function () {
console.log('test')
},
}
}
var vm = new Vue({
mixins: [mixin],
methods: {
test: function () {
console.log('test2')
},
}
})
vm.test() // => "test2"
之前在做项目的过程中遇到了跨域的问题,于是乎要修改vue-cli的配置文件,vue-cli 3.0的配置文件是vue.config.js,本博文演示的是vue-cli 2.0解决跨域问题
后台接口地址是:http://localhost:8888/vueApi/getData
打开config文件夹下的index.js,修改为如下配置:
module.exports = {
var BaseApi='http://localhost:8888/vueApi',
dev: {
// Paths
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {
'/proxy': {
target: BaseApi, // 要访问的接口域名
changeOrigin: true, //开启代理:本地会创建一个虚拟服务端,然后发送请求的数据,并同时接收请求的数据,服务端和服务端进行数据的交互就不会有跨域问题
pathRewrite: {
'^/proxy': '' //这里理解成用'/proxy'代替target里面的地址,比如我要调用'http://localhost:8888/vueApi/getData',直接写'/proxy/getData'即可
}
}
},
}
}
在组件中使用
<template>
<el-button @click="getData()">getData</el-button>
</template>
<script>
export default {
name: "LoginDemo",
data(){
return{
}
},
methods:{
getData(){
const url = '/vueApi/getData'
this.$axios.get(url).then((res) => {
console.log(res.data)
})
}
}
}
</script>
前后端分离的开发方式已被广泛采用,后端提供数据接口,前端调用接口获取数据渲染页面。实际开发中,后端开发由于逻辑相对复杂接口迟迟提供不到位,前端正着急着调用接口来测试页面是否能够正常渲染,造成开发进度阻塞。幸好,我们有mockjs这个插件可以完美的解决这个问题!
npm install mockjs --save-dev
在项目的src目录下新建mock.js文件,并引入mockjs
import Mock from 'mockjs'
function getData(){
let datalist= [];
for (let i = 0; i < 100; i++) {
datalist.push(i)
}
}
return {
data: datalist
}
}
const data = Mock.mock('/testApi',getData)
export default {
data};
Mock.mock()函数的第一个参数是被请求的url,第二个参数是后端要返回给前端的数据
模拟好假数据接口之后,我们还要在main.js中将接口导入
import mockdata from './mock'
<button @click="fasong">fasong</button>
methods:{
fasong(){
this.$http.get('/testApi').then(function (res) {
console.log(res)
})
}
}
Element-Ul是饿了么前端团队推出的一款基于Vue.js 2.0 的桌面端UI框架
Element-ui 官网地址
npm i element-ui -S
需求:后台编写代码,提供给前端接口地址。前端有个登录页面用(vue+elementUi)发起登录请求给后端,后端收到后返回是否登陆成功!
这个功能是不是超级简单,这部分知识想把之前的Vue知识和后端串起来,巩固一下学习的成功!将从初始化Vue项目到后台这个顺序写,侧重于前端框架的整合使用。
这个模块的篇幅较长,我会在另一个博客中详细讲解Element-Ui的使用与登录功能的实现!
Vue+Springboot+Element-ui实现简单的登录
vue项目打包命令
npm run build
生成一个dist文件,dist文件名在Vue的配置文件里面指定
打开tomcat的webapps目录,将打包后的文件复制到webapps文件夹下
启动之后一般tomcat的默认的路径是localhost:8080 我们可以直接通过这个地址打开tomcat
如果端口被占用,需要修改tomcat端口号或者vue项目端口号
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
浏览器输入http://localhost:8080/dist即可
使用 vue init webpack创建Vue项目,需要找到config/index.js文件将build中的assetsPublicPath: '/',修改成assetsPublicPath: './',
nginx是一个高性能的HTTP和反向代理服务器。因此常用来做静态资源服务器和后端的反向代理服务器。
1、下载Nginx
Nginx下载地址:http://nginx.org/en/download.html
将Nginx下载到本地后,解压到桌面文件夹,查看压缩包内部
2.启动nginx
Nginx的配置文件是conf目录下的nginx.conf,默认配置的nginx监听的端口为80,如果80端口被占用可以修改为未被占用的端口即可
检查80端口是否被占用的命令是: netstat -ano | findstr 0.0.0.0:80 或 netstat -ano | findstr “80”
当我们修改了nginx的配置文件nginx.conf 时,只需要执行命令 nginx -s reload 即可让改动生效
修改nginx的配置文件nginx.conf 的proxy_pass 配置请求转发地址,即当我们依然输入http://localhost:80 时,请求会跳转到我们配置的服务器
将Nginx服务器停止
修改nginx.conf配置文件
再次打开nginx出现如下效果表示成功
修改nginx配置文件,配置文件为conf下的nginx.conf,修改nginx.conf中的server配置片段
server {
listen 8080;#默认端口是80,如果端口没被占用可以不用修改
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
root C:/vue/my_project/dist;#vue项目的打包后的dist路径
location / {
try_files $uri $uri/ @router;#需要指向下面的@router否则会出现vue的路由在nginx中刷新出现404
index index.html index.htm;
}
#对应上面的@router,主要原因是路由的路径资源并不是一个真实的路径,所以无法找到具体的文件
#因此需要rewrite到index.html中,然后交给路由在处理请求资源
location @router {
rewrite ^.*$ /index.html last;
}
#.......其他部分省略
}
完成nginx配置后重新加载配置文件,命令如下(ps:需要在安装的根路径下执行):
nginx -s reload
部署成功后访问:localhost:8080即可进入项目