Vue-Element-UI-Vuex-Vue-router梳理前端知識點
Github來源: | 求星星 ? | 給個??關注,??點贊,??鼓勵一下作者
前端工程師的職業(yè)
初級工程師(對應薪資:5000-1w):初步掌握前端開發(fā),技術棧比較局限; 中級工程師(對應薪資:1w-2w):技術棧進一步豐富,對實現(xiàn)細節(jié)不清楚; 高級工程師(對應薪資:2w-3w):清楚實現(xiàn)細節(jié),不再局限某一技術棧; 專家工程師(對應薪資:3w-4w):靈活運用各種技術,解決復雜的技術問題。
on
<html>
<head>
<title>$emit 和 $on</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="root">
<button @click="boost">觸發(fā)事件</button>
</div>
<script>
new Vue({
el: '#root',
data() {
return {
message: 'hello vue'
}
},
created() {
this.$on('my_events', this.handleEvents)
},
methods: {
handleEvents(e) {
console.log(this.message, e)
},
boost() {
this.$emit('my_events', 'my params')
}
}
})
</script>
</body>
</html>
directive 用法
<html>
<head>
<title>directive 用法</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="root">
<div v-loading="isLoading">{{data}}</div>
<button @click="update">更新</button>
</div>
<script>
Vue.directive('loading', {
update(el, binding, vnode) {
if (binding.value) {
const div = document.createElement('div')
div.innerText = '加載中...'
div.setAttribute('id', 'loading')
div.style.position = 'absolute'
div.style.left = 0
div.style.top = 0
div.style.width = '100%'
div.style.height = '100%'
div.style.display = 'flex'
div.style.justifyContent = 'center'
div.style.alignItems = 'center'
div.style.color = 'white'
div.style.background = 'rgba(0, 0, 0, .7)'
document.body.append(div)
} else {
document.body.removeChild(document.getElementById('loading'))
}
}
})
new Vue({
el: '#root',
data() {
return {
isLoading: false,
data: ''
}
},
methods: {
update() {
this.isLoading = true
setTimeout(() => {
this.data = '用戶數(shù)據(jù)'
this.isLoading = false
}, 3000)
}
}
})
</script>
</body>
</html>
Vue.component 用法
<html>
<head>
<title>Vue.component 用法</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="root">
<Test :msg="message"></Test>
</div>
<script>
Vue.component('Test', {
template: '<div>{{msg}}</div>',
props: {
msg: {
type: String,
default: 'default message'
}
}
})
new Vue({
el: '#root',
data() {
return {
message: "Test Component"
}
}
})
</script>
</body>
</html>
Vue.extend 用法
<html>
<head>
<title>Vue.extend 用法</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="root">
<Test :msg="message"></Test>
</div>
<script>
const component = Vue.extend({
template: '<div>{{msg}}</div>',
props: {
msg: {
type: String,
default: 'default message'
}
},
name: 'Test'
})
Vue.component('Test')
new Vue({
el: '#root',
data() {
return {
message: "Test Extend Component"
}
}
})
</script>
</body>
</html>
<html>
<head>
<title>Vue.extend 用法2</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<style>
#loading-wrapper {
position: fixed;
top: 0;
left: 0;
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
background: rgba(0,0,0,.7);
color: #fff;
}
</style>
</head>
<body>
<div id="root">
<button @click="showLoading">顯示Loading</button>
</div>
<script>
function Loading(msg) {
const LoadingComponent = Vue.extend({
template: '<div id="loading-wrapper">{{msg}}</div>',
props: {
msg: {
type: String,
default: msg
}
},
name: 'LoadingComponent'
})
const div = document.createElement('div')
div.setAttribute('id', 'loading-wrapper')
document.body.append(div)
new LoadingComponent().$mount('#loading-wrapper')
return () => {
document.body.removeChild(document.getElementById('loading-wrapper'))
}
}
Vue.prototype.$loading = Loading
new Vue({
el: '#root',
methods: {
showLoading() {
const hide = this.$loading('正在加載,請稍等...')
setTimeout(() => {
hide()
}, 2000)
}
}
})
</script>
</body>
</html>
Vue.use 用法
<html>
<head>
<title>Vue.use 用法</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<style>
#loading-wrapper {
position: fixed;
top: 0;
left: 0;
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
background: rgba(0,0,0,.7);
color: #fff;
}
</style>
</head>
<body>
<div id="root">
<button @click="showLoading">顯示Loading</button>
</div>
<script>
const loadingPlugin = {
install: function(vm) {
const LoadingComponent = vm.extend({
template: '<div id="loading-wrapper">{{msg}}</div>',
props: {
msg: {
type: String,
default: 'loading...'
}
}
}, 'LoadingComponent')
function Loading(msg) {
const div = document.createElement('div')
div.setAttribute('id', 'loading-wrapper')
document.body.append(div)
new LoadingComponent({
props: {
msg: {
type: String,
default: msg
}
}
}).$mount('#loading-wrapper')
return () => {
document.body.removeChild(document.getElementById('loading-wrapper'))
}
}
vm.prototype.$loading = Loading
}
}
Vue.use(loadingPlugin)
new Vue({
el: '#root',
methods: {
showLoading() {
const hide = this.$loading('正在加載,請稍等...')
setTimeout(() => {
hide()
}, 2000)
}
}
})
</script>
</body>
</html>
組件通信 provide 和 inject
<html>
<head>
<title>組件通信 provide 和 inject</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="root">
<Test></Test>
</div>
<script>
function registerPlugin() {
Vue.component('Test', {
template: '<div>{{message}}<Test2 /></div>',
provide() {
return {
elTest: this
}
}, // function 的用途是為了獲取運行時環(huán)境,否則 this 將指向 window
data() {
return {
message: 'message from Test'
}
},
methods: {
change(component) {
this.message = 'message from ' + component
}
}
})
Vue.component('Test2', {
template: '<Test3 />'
})
Vue.component('Test3', {
template: '<button @click="changeMessage">change</button>',
inject: ['elTest'],
methods: {
changeMessage() {
this.elTest.change(this.$options._componentTag)
}
}
})
}
Vue.use(registerPlugin)
new Vue({
el: '#root'
})
</script>
</body>
</html>
過濾器 filter
<html>
<head>
<title>過濾器 filter</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="root">
{{message | lower}}
</div>
<script>
new Vue({
el: '#root',
filters: {
lower(value) {
return value.toLowerCase()
}
},
data() {
return {
message: 'Hello Vue'
}
}
})
</script>
</body>
</html>
監(jiān)聽器 watch
<html>
<head>
<title>監(jiān)聽器 watch</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="root">
<h3>Watch 用法1:常見用法</h3>
<input v-model="message">
<span>{{copyMessage}}</span>
</div>
<div id="root2">
<h3>Watch 用法2:綁定方法</h3>
<input v-model="message">
<span>{{copyMessage}}</span>
</div>
<div id="root3">
<h3>Watch 用法3:deep + handler</h3>
<input v-model="deepMessage.a.b">
<span>{{copyMessage}}</span>
</div>
<div id="root4">
<h3>Watch 用法4:immediate</h3>
<input v-model="message">
<span>{{copyMessage}}</span>
</div>
<div id="root5">
<h3>Watch 用法5:綁定多個 handler</h3>
<input v-model="message">
<span>{{copyMessage}}</span>
</div>
<div id="root6">
<h3>Watch 用法6:監(jiān)聽對象屬性</h3>
<input v-model="deepMessage.a.b">
<span>{{copyMessage}}</span>
</div>
<script>
new Vue({
el: '#root',
watch: {
message(value) {
this.copyMessage = value
}
},
data() {
return {
message: 'Hello Vue',
copyMessage: ''
}
}
})
new Vue({
el: '#root2',
watch: {
message: 'handleMessage'
},
data() {
return {
message: 'Hello Vue',
copyMessage: ''
}
},
methods: {
handleMessage(value) {
this.copyMessage = value
}
}
})
new Vue({
el: '#root3',
watch: {
deepMessage: {
handler: 'handleDeepMessage',
deep: true
}
},
data() {
return {
deepMessage: {
a: {
b: 'Deep Message'
}
},
copyMessage: ''
}
},
methods: {
handleDeepMessage(value) {
this.copyMessage = value.a.b
}
}
})
new Vue({
el: '#root4',
watch: {
message: {
handler: 'handleMessage',
immediate: true,
}
},
data() {
return {
message: 'Hello Vue',
copyMessage: ''
}
},
methods: {
handleMessage(value) {
this.copyMessage = value
}
}
}),
new Vue({
el: '#root5',
watch: {
message: [{
handler: 'handleMessage',
},
'handleMessage2',
function(value) {
this.copyMessage = this.copyMessage + '...'
}]
},
data() {
return {
message: 'Hello Vue',
copyMessage: ''
}
},
methods: {
handleMessage(value) {
this.copyMessage = value
},
handleMessage2(value) {
this.copyMessage = this.copyMessage + '*'
}
}
})
new Vue({
el: '#root6',
watch: {
'deepMessage.a.b': 'handleMessage'
},
data() {
return {
deepMessage: { a: { b: 'Hello Vue' } },
copyMessage: ''
}
},
methods: {
handleMessage(value) {
this.copyMessage = value
}
}
})
</script>
</body>
</html>
class 和 style 綁定的高級用法
<html>
<head>
<title>class 和 style 綁定的高級用法</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="root">
<div :class="['active', 'normal']">數(shù)組綁定多個class</div>
<div :class="[{active: isActive}, 'normal']">數(shù)組包含對象綁定class</div>
<div :class="[showWarning(), 'normal']">數(shù)組包含方法綁定class</div>
<div :style="[warning, bold]">數(shù)組綁定多個style</div>
<div :style="[warning, mix()]">數(shù)組包含方法綁定style</div>
<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }">style多重值</div>
</div>
<script>
new Vue({
el: '#root',
data() {
return {
isActive: true,
warning: {
color: 'orange'
},
bold: {
fontWeight: 'bold'
}
}
},
methods: {
showWarning() {
return 'warning'
},
mix() {
return {
...this.bold,
fontSize: 20
}
}
}
})
</script>
</body>
</html>
Vue.observable
<html>
<head>
<title>Vue.observable</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="root">
{{message}}
<button @click="change">Change</button>
</div>
<script>
const state = Vue.observable({ message: 'Vue 2.6' })
const mutation = {
setMessage(value) {
state.message = value
}
}
new Vue({
el: '#root',
computed: {
message() {
return state.message
}
},
methods: {
change() {
mutation.setMessage('Vue 3.0')
}
}
})
</script>
</body>
</html>
插槽 slot
<html>
<head>
<title>插槽 slot</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="root">
<div>案例1:slot的基本用法</div>
<Test>
<template v-slot:header="{user}">
<div>自定義header({{user.a}})</div>
</template>
<template v-slot="{user}">
<div>自定義body({{user.b}})</div>
</template>
</Test>
</div>
<div id="root2">
<div>案例2:Vue2.6新特性 - 動態(tài)slot</div>
<Test>
<template v-slot:[section]="{section}">
<div>this is {{section}}</div>
</template>
</Test>
<button @click="change">switch header and body</button>
</div>
<script>
Vue.component('Test', {
template:
'<div>' +
'<slot name="header" :user="obj" :section="'header'">' +
'<div>默認header</div>' +
'</slot>' +
'<slot :user="obj" :section="'body'">默認body</slot>' +
'</div>',
data() {
return {
obj: { a: 1, b: 2 }
}
}
})
new Vue({ el: '#root' })
new Vue({
el: '#root2',
data() {
return {
section: 'header'
}
},
methods: {
change() {
this.section === 'header' ?
this.section = 'default' :
this.section = 'header'
}
}
})
</script>
</body>
</html>
Element-UI
vue create element-test
vuex+router ([Vue 2] router, vuex, dart-sass, babel, eslint)
Default ([Vue 2] babel, eslint)
Default (Vue 3) ([Vue 3] babel, eslint)
Manually select features

初始化項目
vue create element-test
安裝
npm i element-ui -S
Vue 插件
import ElementUI from 'element-ui'
Vue.use(ElementUI)
引用樣式
import 'element-ui/lib/theme-chalk/index.css'
按需加載
Entrypoints:
app (1.03 MiB)
css/chunk-vendors.a16c4353.css
js/chunk-vendors.29976e71.js
css/app.601d2ada.css
js/app.29e7d705.js
For more info visit https://webpack.js.org/guides/code-splitting/
File Size Gzipped
dist\js\chunk-vendors.29976e71.js 845.63 KiB 225.63 KiB
dist\js\app.29e7d705.js 2.77 KiB 1.30 KiB
dist\css\chunk-vendors.a16c4353.css 209.55 KiB 33.63 KiB
dist\css\app.601d2ada.css 0.25 KiB 0.19 KiB
Images and other types of assets omitted.
按需加載的用法如下:
安裝 babel-plugin-component
npm install babel-plugin-component -D
修改 babel.config.js:
{
"presets": [["es2015", { "modules": false }]],
"plugins": [
[
"component",
{
"libraryName": "element-ui",
"styleLibraryName": "theme-chalk"
}
]
]
}
Vuex 原理解析
Vuex 的原理關鍵:使用 Vue 實例管理狀態(tài)
<html>
<head>
<title>vuex 原理解析</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="root">{{data}}</div>
<div id="root2">{{data2}}</div>
<div id="root3">
<button @click="change">change</button>
</div>
<script>
function registerPlugin(Vue) {
const vuex = {}
vuex._vm = new Vue({
data: {
message: 'hello vue.js'
}
})
vuex.state = vuex._vm
vuex.mutations = {
setMessage(value) {
vuex.state.message = value
}
}
function init() {
this.$store = vuex
}
Vue.mixin({
beforeCreate: init
})
}
Vue.use(registerPlugin)
new Vue({
el: '#root',
computed: {
data() {
return this.$store.state.message
}
}
})
new Vue({
el: '#root2',
computed: {
data2() {
return this.$store.state.message
}
}
})
new Vue({
el: '#root3',
methods: {
change() {
const newValue = this.$store.state.message + '.'
this.$store.mutations.setMessage(newValue)
}
}
})
</script>
</body>
</html>
vue-router 實現(xiàn)原理
vue-router 實例化時會初始化 this.history,不同 mode 對應不同的 history
constructor (options: RouterOptions = {}) {
this.mode = mode
switch (mode) {
case 'history':
this.history = new HTML5History(this, options.base)
break
case 'hash':
this.history = new HashHistory(this, options.base, this.fallback)
break
case 'abstract':
this.history = new AbstractHistory(this, options.base)
break
default:
if (process.env.NODE_ENV !== 'production') {
assert(false, `invalid mode: ${mode}`)
}
}
}
這里以 HashHistory 為例,vue-router 的 push 方法實現(xiàn)如下:
push (location: RawLocation, onComplete?: Function, onAbort?: Function) {
// $flow-disable-line
if (!onComplete && !onAbort && typeof Promise !== 'undefined') {
return new Promise((resolve, reject) => {
this.history.push(location, resolve, reject)
})
} else {
this.history.push(location, onComplete, onAbort)
}
}
HashHistory 具體實現(xiàn)了 push 方法:
function pushHash (path) {
if (supportsPushState) {
pushState(getUrl(path))
} else {
window.location.hash = path
}
}
對路由的監(jiān)聽通過 hash 相應的事件監(jiān)聽實現(xiàn):
window.addEventListener(
supportsPushState ? 'popstate' : 'hashchange',
() => {
const current = this.current
if (!ensureSlash()) {
return
}
this.transitionTo(getHash(), route => {
if (supportsScroll) {
handleScroll(this.router, route, current, true)
}
if (!supportsPushState) {
replaceHash(route.fullPath)
}
})
}
)
除此之外,vue-router 還提供了兩個組件:
Vue.component('RouterView', View)
Vue.component('RouterLink', Link)
vue-router 路由守衛(wèi)
創(chuàng)建 router.js:
import Vue from 'vue'
import Route from 'vue-router'
import HelloWorld from './components/HelloWorld'
Vue.use(Route)
const routes = [
{ path: '/hello-world', component: HelloWorld }
]
const router = new Route({
routes
})
export default router
在 main.js 中引用 router,并加入 vue 實例:
import router from './router'
new Vue({
render: h => h(App),
router
}).$mount('#app')
全局守衛(wèi)
router.beforeEach((to, from, next) => {
console.log('beforeEach', to, from)
next()
})
router.beforeResolve((to, from, next) => {
console.log('beforeResolve', to, from)
next()
})
router.afterEach((to, from) => {
console.log('afterEach', to, from)
})
局部守衛(wèi)
beforeRouteEnter (to, from, next) {
// 不能獲取組件實例 `this`
console.log('beforeRouteEnter', to, from)
next()
},
beforeRouteUpdate (to, from, next) {
console.log('beforeRouteUpdate', to, from)
next()
},
beforeRouteLeave (to, from, next) {
console.log('beforeRouteLeave', to, from)
next()
}
路由元信息
通過 meta 定義路由元信息
const routes = [
{ path: '/a', component: A, meta: { title: 'Custom Title A' } }
]
使用 meta 信息動態(tài)修改標題
router.beforeEach((to, from, next) => {
console.log('beforeEach', to, from)
if (to.meta && to.meta.title) {
document.title = to.meta.title
} else {
document.title = 'default title'
}
next()
})
路由 API
使用 router.addRoutes 動態(tài)添加路由
addRoute() {
this.$router.addRoutes([{
path: '/b', component: B, meta: { title: 'Custom Title B' },
}])
}
此時可以訪問到 B 組件
<router-link to='/b'>to B</router-link>
項目初始化
git clone https://github.com/PanJiaChen/vue-element-admin
cd vue-element-admin
npm i
npm run dev
項目精簡
刪除 src/views 下的源碼,保留:
dashboard:首頁 error-page:異常頁面 login:登錄 redirect:重定向 對 src/router/index 進行相應修改
刪除 src/router/modules 文件夾
刪除 src/vendor 文件夾
vue-element-admin 初始化項目
vue-element-admin 實現(xiàn)了登錄模塊,包括 token 校驗、網(wǎng)絡請求等
項目配置
通過 src/settings.js 進行全局配置:
title:站點標題,進入某個頁面后,格式為:
頁面標題 - 站點標題
showSettings:是否顯示右側懸浮配置按鈕 tagsView:是否顯示頁面標簽功能條 fixedHeader:是否將頭部布局固定 sidebarLogo:菜單欄中是否顯示LOGO errorLog:默認顯示錯誤日志的環(huán)境
源碼調(diào)試
如果需要進行源碼調(diào)試,需要修改 vue.config.js:
config
// https://webpack.js.org/configuration/devtool/#development
.when(process.env.NODE_ENV === 'development',
config => config.devtool('cheap-source-map')
)
將 cheap-source-map 改為 source-map,如果希望提升構建速度可以改為 eval
通常建議開發(fā)時保持 eval 配置,以增加構建速度,當出現(xiàn)需要源碼調(diào)試排查問題時改為 source-map
項目結構
api:接口請求
assets:靜態(tài)資源
components:通用組件
directive:自定義指令
filters:自定義過濾器
icons:圖標組件
layout:布局組件
router:路由配置
store:狀態(tài)管理
styles:自定義樣式
utils:通用工具方法
auth.js:token 存取 permission.js:權限檢查 request.js:axios 請求封裝 index.js:工具方法 views:頁面
permission.js:登錄認證和路由跳轉(zhuǎn)
settings.js:全局配置
main.js:全局入口文件
App.vue:全局入口組件
后端框架搭建
npm init -y
安裝依賴
npm i -S express
創(chuàng)建 app.js
const express = require('express')
// 創(chuàng)建 express 應用
const app = express()
// 監(jiān)聽 / 路徑的 get 請求
app.get('/', function(req, res) {
res.send('hello node')
})
// 使 express 監(jiān)聽 5000 端口號發(fā)起的 http 請求
const server = app.listen(5000, function() {
const { address, port } = server.address()
console.log('Http Server is running on http://%s:%s', address, port)
})
Express 三大基礎概念
中間件
中間件是一個函數(shù),在請求和響應周期中被順序調(diào)用
const myLogger = function(req, res, next) {
console.log('myLogger')
next()
}
app.use(myLogger)
提示:中間件需要在響應結束前被調(diào)用
路由
應用如何響應請求的一種規(guī)則
響應 / 路徑的 get 請求:
app.get('/', function(req, res) {
res.send('hello node')
})
響應 / 路徑的 post 請求:
app.post('/', function(req, res) {
res.send('hello node')
})
異常處理
通過自定義異常處理中間件處理請求中產(chǎn)生的異常
app.get('/', function(req, res) {
throw new Error('something has error...')
})
const errorHandler = function (err, req, res, next) {
console.log('errorHandler...')
res.status(500)
res.send('down...')
}
app.use(errorHandler)
使用時需要注意兩點:
第一,參數(shù)一個不能少,否則會視為普通的中間件 第二,中間件需要在請求之后引用
項目框架搭建
路由
安裝 boom 依賴:
npm i -S boom
創(chuàng)建 router 文件夾,創(chuàng)建 router/index.js:
const express = require('express')
const boom = require('boom')
const userRouter = require('./user')
const {
CODE_ERROR
} = require('../utils/constant')
// 注冊路由
const router = express.Router()
router.get('/', function(req, res) {
res.send('歡迎學習管理后臺')
})
// 通過 userRouter 來處理 /user 路由,對路由處理進行解耦
router.use('/user', userRouter)
/**
* 集中處理404請求的中間件
* 注意:該中間件必須放在正常處理流程之后
* 否則,會攔截正常請求
*/
router.use((req, res, next) => {
next(boom.notFound('接口不存在'))
})
/**
* 自定義路由異常處理中間件
* 注意兩點:
* 第一,方法的參數(shù)不能減少
* 第二,方法的必須放在路由最后
*/
router.use((err, req, res, next) => {
const msg = (err && err.message) || '系統(tǒng)錯誤'
const statusCode = (err.output && err.output.statusCode) || 500;
const errorMsg = (err.output && err.output.payload && err.output.payload.error) || err.message
res.status(statusCode).json({
code: CODE_ERROR,
msg,
error: statusCode,
errorMsg
})
})
module.exports = router
創(chuàng)建 router/use.js:
const express = require('express')
const router = express.Router()
router.get('/info', function(req, res, next) {
res.json('user info...')
})
module.exports = router
創(chuàng)建 utils/constant:
module.exports = {
CODE_ERROR: -1
}
驗證 /user/info:
"user info..."
驗證 /user/login:
{"code":-1,"msg":"接口不存在","error":404,"errorMsg":"Not Found"}
登錄
用戶名密碼校驗 token 生成、校驗和路由過濾 前端 token 校驗和重定向
Nginx 服務器搭建
修改配置文件
打開配置文件 nginx.conf:
windows 位于安裝目錄下 macOS 位于: /usr/local/etc/nginx/nginx.conf
修改一:添加當前登錄用戶為da
user sam da;
修改二:在結尾大括號之前添加:
include /Users/sam/upload/upload.conf;
這里 /Users/sam/upload 是資源文件路徑,/Users/sam/upload/upload.conf 是額外的配置文件,當前把 /Users/sam/upload/upload.conf 配置文件的內(nèi)容加入 nginx.conf 也是可行的!
修改三:添加 /Users/sam/upload/upload.conf 文件,配置如下:
server
{
charset utf-8;
listen 8089;
server_name http_host;
root /Users/sam/upload/;
autoindex on;
add_header Cache-Control "no-cache, must-revalidate";
location / {
add_header Access-Control-Allow-Origin *;
}
}
如果需要加入 https 服務,可以再添加一個 server:
server
{
listen 443 default ssl;
server_name https_host;
root /Users/sam/upload/;
autoindex on;
add_header Cache-Control "no-cache, must-revalidate";
location / {
add_header Access-Control-Allow-Origin *;
}
ssl_certificate /Users/sam/Desktop/https/da.pem;
ssl_certificate_key /Users/sam/Desktop/https/da.key;
ssl_session_timeout 5m;
ssl_protocols SSLv3 TLSv1;
ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
ssl_prefer_server_ciphers on;
}
https證書:/Users/sam/Desktop/https/da.pem https:私鑰:/Users/sam/Desktop/https/da.key
啟動服務
啟動 nginx 服務:
sudo nginx
重啟 nginx 服務:
sudo nginx -s reload
停止 nginx 服務:
sudo nginx -s stop
檢查配置文件是否存在語法錯誤:
sudo nginx -t
訪問地址:
http: http://localhost:8089https: https://localhost
??掘金文章
前端日??偨Y 一份不可多得的TypeScript系統(tǒng)入門整理 JS葵花寶典秘籍筆記,為你保駕護航金三銀四 TypeScript趁早學習提高職場競爭力 前端模擬面試字數(shù)過23477萬內(nèi)容 JavaScript數(shù)據(jù)結構之鏈表 | 技術點評 JavaScript的數(shù)據(jù)結構-集合 |技術點評 這是我的第一次JavaScript初級技巧 一個合格的初級前端工程師需要掌握的模塊筆記 【初級】個人分享Vue前端開發(fā)教程筆記 localStorage和sessionStorage本地存儲 HTML5中的拖放功能 挑戰(zhàn)前端知識點HTTP/ECMAScript 前端170面試題+答案學習整理(良心制作)
??關注+點贊+收藏+評論+轉(zhuǎn)發(fā)??
點贊、收藏和評論
我是Jeskson(達達前端),感謝各位人才的:點贊、收藏和評論,我們下期見!(如本文內(nèi)容有地方講解有誤,歡迎指出?謝謝,一起學習了)
我們下期見!
文章持續(xù)更新,可以微信搜一搜「 程序員哆啦A夢 」第一時間閱讀,回復【資料】有我準備的一線大廠資料,本文 https://www.1024bibi.com 已經(jīng)收錄
github收錄,歡迎Star:https://github.com/webVueBlog/WebFamily
