前言
前端技術(shù)近幾年發(fā)展十分迅速泉蝌,經(jīng)歷了jQuery嗅虏,angularjs,發(fā)展到現(xiàn)在的Angular蒜鸡,Vue和React三大前端框架。因Vue相比其他框架更容易上手(無需了解jsx牢裳、ts)逢防,且性能優(yōu)異,因而受到廣大開發(fā)者的青睞蒲讯。以下詳細介紹Vue框架忘朝。
vue 全家桶
- vue-cli 自動化構(gòu)建工具
- vue-router 路由控制
- vuex 狀態(tài)管理
- vue-Devtool 調(diào)試工具
- UI組件庫 (elementUI,vant)
- axios http請求
vue-cli 自動化構(gòu)建工具
搭建交互式的項目腳手架判帮,集成了前端生態(tài)中最好的工具
基礎(chǔ)配置
module.exports = {
// 項目部署的基礎(chǔ)路徑
publicPath: process.env.PUBLIC_PATH,
// 將構(gòu)建好的文件輸出到哪里
outputDir: process.env.PUBLIC_PATH,
// 該對象將會被 webpack-merge 合并入最終的 webpack 配置局嘁。
configureWebpack: config => {
if (process.env.NODE_ENV === 'production') {
// 為生產(chǎn)環(huán)境修改配置...
} else {
// 為開發(fā)環(huán)境修改配置...
config.devtool = 'source-map'
}
},
// 向 CSS 相關(guān)的 loader 傳遞選項
css: {
loaderOptions: {
scss: {
// 全局引入index.scss
prependData: `@import "~@/assets/styles/index.scss";`
}
}
},
// 鏈式操作,允許對內(nèi)部的 webpack 配置進行更細粒度的修改晦墙。
chainWebpack: config => {
const svgRule = config.module.rule('svg')
// 清除已有的所有 loader悦昵。
// 如果你不這樣做,接下來的 loader 會附加在該規(guī)則現(xiàn)有的 loader 之后晌畅。
svgRule.uses.clear()
// 添加要替換的 loader
svgRule
.use('vue-svg-loader')
.loader('vue-svg-loader')
},
// 前后的分離時但指,配置代理服務器
devServer: {
proxy: {
'/': {
target: process.env.PROXY_TARGET,
pathRewrite: {
'/test': ''
}
}
}
}
}
環(huán)境變量管理
通過cross-env來管理不同環(huán)境的變量
.env # loaded in all cases
.env.local # loaded in all cases, ignored by git
.env.[mode] # only loaded in specified mode
.env.[mode].local # only loaded in specified mode, ignored by git
優(yōu)先級:.local > .[mode] > .env
.env
文件可以簡單的以key=value
的方式定義變量:
NODE_ENV=production
VUE_APP_TITLE=My App (staging)
注意:變量必須以VUE_APP_*
命名才可以在程序中使用。(NODE_ENV
,BASE_URL
除外)
執(zhí)行命令:
vue-cli-service build --mode development // 會讀取.env .env.development .env.development.local
獲取參數(shù):
process.env.NODE_ENV
vue-router 路由控制
路由的基本配置
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'home',
component: Home // 會打包進app.js
},
{
path: '/about',
name: 'about',
// 會打包到about.js棋凳,在訪問路由about時拦坠,才加載about.js
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
}
]
const router = new VueRouter({
mode: 'hash',
base: process.env.BASE_URL,
routes
})
export default router
運行npm run build
打包
路由的兩種模式:
- hash
- history
hash模式不需要后端配置,可直接使用剩岳。缺點是無法使用錨點功能贪婉。
history模式需要后端配置,url不會出現(xiàn)#
卢肃,美觀疲迂。
vuex 狀態(tài)管理
- 為什么要使用vuex?
以下場景:
- 從根組件向子組件傳值莫湘,我們一般使用
props
尤蒿,倘若有多層嵌套時,得一級一級向下傳遞幅垮,比較繁瑣腰池,并 且中間層級可能并不需要該值。 - 兄弟組件需要使用同一狀態(tài)時忙芒,得通過父組件才能通信示弓。
- 來自不同視圖的行為需要變更同一狀態(tài)。
- 單向數(shù)據(jù)流
用 Vuex 的思維去實現(xiàn)v-model
的雙向綁定效果:給 <input> 中綁定 value呵萨,然后偵聽 input 或者 change 事件奏属,在事件回調(diào)中調(diào)用 action,通過action改變state潮峦,從而再更新視圖:
<input :value="message" @input="updateMessage">
// ...
computed: {
...mapState({
message: state => state.obj.message
})
},
methods: {
updateMessage (e) {
this.$store.commit('updateMessage', e.target.value)
}
}
// ...
mutations: {
updateMessage (state, message) {
state.obj.message = message
}
}
雙向綁定的計算屬性
<input v-model="message">
// ...
computed: {
message: {
get () {
return this.$store.state.obj.message
},
set (value) {
this.$store.commit('updateMessage', value)
}
}
}
父子組件通過
props
傳遞數(shù)據(jù)
子組件數(shù)據(jù)源通過父組件傳遞囱皿,雖然增加了耦合,但組件之間的層級關(guān)系更明顯忱嘹,代碼邏輯也更清晰明了嘱腥。Vue官網(wǎng)對Vuex的解釋:
Vuex 的狀態(tài)存儲是響應式的。當 Vue 組件從 store 中讀取狀態(tài)的時候拘悦,若 store 中的狀態(tài)發(fā)生變化齿兔,那么相應的組件也會相應地得到高效更新。
你不能直接改變 store 中的狀態(tài)础米。改變 store 中的狀態(tài)的唯一途徑就是顯式地提交 (commit) mutation分苇。這樣使得我們可以方便地跟蹤每一個狀態(tài)的變化,從而讓我們能夠?qū)崿F(xiàn)一些工具幫助我們更好地了解我們的應用椭盏。
vue-Devtool 調(diào)試工具
UI組件庫 (elementUI组砚,vant)
axios http請求
相關(guān)配置
import Axios from 'axios'
import store from '@/store'
const instance = Axios.create({
baseURL: '',
timeout: 60000
})
instance.interceptors.request.use(
config => {
const csrf = store.getters.csrf
config.headers = {
csrf,
'Content-Type': 'application/json'
}
return config
},
error => {
return Promise.reject(error)
}
)
instance.interceptors.response.use(
response => {
const res = response.data
// code here
return res
},
error => {
return Promise.reject(error)
}
)
export default instance
使用方法
import request from '@/utils/request'
export const getArticles = () => {
return request({
methods: 'get',
url: '',
params: {}
})
}
export const saveArticles = () => {
return request({
methods: 'post',
url: '',
data: {}
})
}