日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
Vue項(xiàng)目實(shí)戰(zhàn)精粹匯總,你知道幾個(gè)?

前言

筆者曾經(jīng)有兩年的vue項(xiàng)目經(jīng)驗(yàn),基于vue做過移動(dòng)端項(xiàng)目和PC端的ERP系統(tǒng),雖然平時(shí)工作中采用的是react技術(shù)棧,但平時(shí)還是會(huì)積累很多vue相關(guān)的最佳實(shí)踐和做一些基于vue的開源項(xiàng)目,所以說總結(jié)vue的項(xiàng)目經(jīng)驗(yàn)我覺得是最好的成長,也希望給今年想接觸vue框架或者想從事vue工作的朋友帶來一些經(jīng)驗(yàn)和思考。

你將收獲

  • vue框架使用注意事項(xiàng)和最佳經(jīng)驗(yàn)
  • vue項(xiàng)目配置經(jīng)驗(yàn)總結(jié)
  • vue組件設(shè)計(jì)經(jīng)驗(yàn)總結(jié)
  • vue項(xiàng)目架構(gòu)與服務(wù)化探索

正文

本文不僅僅是總結(jié)一些vue使用踩過的一些坑和項(xiàng)目經(jīng)驗(yàn),更多的是使用框架(vue/react)過程中的方法論和組件的設(shè)計(jì)思路,最后還會(huì)有一些個(gè)人對(duì)工程化的一些總結(jié),希望有更多經(jīng)驗(yàn)的朋友們可以一起交流,探索vue的奧妙。

在開始文章之前,筆者建議大家對(duì)javascript, css, html基礎(chǔ)有一定的了解,因?yàn)闀?huì)用框架不一定能很好的實(shí)現(xiàn)業(yè)務(wù)需求和功能,要想實(shí)現(xiàn)不同場(chǎng)景下不同復(fù)雜度的需求,一定要對(duì)web基礎(chǔ)有充足的了解,所以希望大家熟悉如下基礎(chǔ)知識(shí),如果不太熟悉可以花時(shí)間研究了解一下。

javascript:

  • 數(shù)組常用方法的使用,比如遍歷有forEach,map,filter,every, some,reduce,操作方法有splice,slice, join,push,shift, pop,sort等
  • 基本數(shù)據(jù)結(jié)構(gòu),引用類型(對(duì)象,數(shù)組)
  • 基本邏輯運(yùn)算if else, switch,三目運(yùn)算:?,for/while循環(huán)等
  • 字符串常見api(如replace,slice, substr,indexOf)
  • 基本正則使用
  • 變量作用域,作用域鏈,變量提升,函數(shù)聲明提升
  • 對(duì)象基本用法,面向?qū)ο缶幊?/li>

css:

  • 基本盒模型(border/content/padding等)
  • 4種常用定位(static/absolute/relative/fixed)
  • 常用布局方式(浮動(dòng)布局/彈性布局flex/自適應(yīng)布局/網(wǎng)格布局grid)
  • css3基本樣式與動(dòng)畫(transition,animation)

html:

  • 新標(biāo)簽基本用法和使用
  • head標(biāo)簽作用與用法(主要是meta屬性的用法)

所以希望大家掌握好以上基礎(chǔ)知識(shí),也是前端開發(fā)的基礎(chǔ),接下來我們直接進(jìn)入正文。

1. vue框架使用注意事項(xiàng)和最佳經(jīng)驗(yàn)

vue學(xué)習(xí)最快的方式就是實(shí)踐,根據(jù)官網(wǎng)多寫幾個(gè)例子是掌握vue最快的方式。 接下來筆者就來總結(jié)一下在開發(fā)vue項(xiàng)目中的一些實(shí)踐經(jīng)驗(yàn)。

1.1 vue生命周期以及不同生命周期下的應(yīng)用

以上是vue官網(wǎng)上的生命周期的方法,大致劃分一下分為創(chuàng)建前/后,掛載前/后,更新前/后,銷毀前/后這四個(gè)階段。各個(gè)階段的狀態(tài)總結(jié)如下:

  • beforeCreate:在beforeCreate生命周期執(zhí)行時(shí),data和methods中的數(shù)據(jù)還未初始化,所以此時(shí)不能使用data中的數(shù)據(jù)和methods中的方法
  • create:data 和 methods初始化完畢,此時(shí)可以使用methods 中的方法和data 中的數(shù)據(jù)
  • beforeMount:template模版已經(jīng)編譯好,但還未掛載到頁面,此時(shí)頁面還是上一個(gè)狀態(tài)
  • mounted:此時(shí)Vue實(shí)例初始化完成了,DOM掛載完畢,可以直接操作dom或者使用第三方dom庫
  • beforeUpdate: 此時(shí)data已更新,但還未同步頁面
  • updated:data和頁面都已經(jīng)更新完成
  • beforeDestory:Vue實(shí)例進(jìn)入銷毀階段,但所有的 data 和 methods , 指令, 過濾器等都處于可用狀態(tài)
  • destroyed: 此時(shí)組件已經(jīng)被銷毀,data,methods等都不可用

根據(jù)以上介紹,頁面第一次加載時(shí)會(huì)執(zhí)行 beforeCreate, created, beforeMount, mounted這四個(gè)生命周期,所以我們一般在created階段處理http請(qǐng)求獲取數(shù)據(jù)或者對(duì)data做一定的處理, 我們會(huì)在mounted階段操作dom,比如使用jquery,或者其他第三方dom庫。其次,根據(jù)以上不同周期下數(shù)據(jù)和頁面狀態(tài)的不同,我們還可以做其他更多操作,所以說每個(gè)生命周期的發(fā)展?fàn)顟B(tài)非常重要,一定要理解,這樣才能對(duì)vue有更多的控制權(quán)。

1.2 vue常用的指令以及動(dòng)態(tài)指令的使用

指令 (Directives) 是帶有 v- 前綴的特殊屬性,vue常用的指令有:

  • v-bind 用于響應(yīng)式地更新 HTML屬性
  • v-if 根據(jù)表達(dá)式的值的真假來決定是否插入/移除元素
  • v-on 用于監(jiān)聽 DOM 事件
  • v-show 用于決定是否展示該元素,底層通過display:none實(shí)現(xiàn)
  • v-html 在dom內(nèi)插入html內(nèi)容
  • v-for 循環(huán)
  • v-text 渲染指定dom的內(nèi)容文本
  • v-cloak 和CSS規(guī)則如 [v-cloak] { display: none } 一起用,可以隱藏未編譯的 Mustache 標(biāo)簽直到實(shí)例準(zhǔn)備完畢

以上是比較常用的指令,具體用法就不一一舉例了,其中v-cloak主要是用來避免頁面加載時(shí)出現(xiàn)閃爍的問題,可以結(jié)合css的[v-cloak] { display: none }方式解決這一問題。關(guān)于指令的動(dòng)態(tài)參數(shù),使用也很簡(jiǎn)單,雖然是2.6.0 新增的,但是方法很靈活,具體使用如下:

 ... 





我們可以根據(jù)具體情況動(dòng)態(tài)切換事件名,從而綁定同一個(gè)函數(shù)。

1.3 vue常用修飾符及作用

事件修飾符
  • .stop 阻止事件冒泡
  • .prevent 阻止事件默認(rèn)行為
  • .self 事件綁定的元素本身觸發(fā)時(shí)才觸發(fā)回調(diào)
  • .once 事件只能觸發(fā)一次,第二次就不會(huì)觸發(fā)了
  • .native 將一個(gè)vue組件變成一個(gè)普通的html,使其可以監(jiān)聽click等原生事件 具體使用如下:
ok





表單修飾符
  • .lazy 在輸入框輸入完內(nèi)容,光標(biāo)離開時(shí)才更新視圖
  • .trim 過濾首尾空格
  • .number 如果先輸入數(shù)字,那它就會(huì)限制你輸入的只能是數(shù)字;如果先輸入字符串,那就相當(dāng)于沒有加.number

用法如下:







還有很多修飾符比如鍵盤,鼠標(biāo)等修飾符,感興趣的大家可以自行學(xué)習(xí)研究。

1.4 組件之間,父子組件之間的通信方案

組件之間的通信方案:

  • 通過事件總線(bus),即通過發(fā)布訂閱的方式
  • vuex

父子組件:

  • 父組件通過prop向自組件傳遞數(shù)據(jù)
  • 子組件綁定自定義事件,通過this.$emit(event,params) 來調(diào)用自定義事件
  • 使用vue提供的 children & $refs方法來通信

1.5 vue實(shí)現(xiàn)按需加載組件

組件的按需加載是項(xiàng)目性能優(yōu)化的一個(gè)環(huán)節(jié),也可以降低首屏渲染時(shí)間,筆者在項(xiàng)目中用到的組件按需加載的方式如下:

使用() => import(), 具體代碼如下:

  






使用resolve => require(['./ComponentA'], resolve),使用方法如下:

  






「1.6 vuex的幾種屬性和作用,以及使用vuex的基本模式」

Vuex 是一個(gè)專為 Vue.js 應(yīng)用程序開發(fā)的狀態(tài)管理模式。它采用集中式存儲(chǔ)管理應(yīng)用的所有組件的狀態(tài),并以相應(yīng)的規(guī)則保證狀態(tài)以一種可預(yù)測(cè)的方式發(fā)生變化。

vuex的基本工作模式如下圖所示:

state的改變完全由mutations控制, 我們也沒必要任何項(xiàng)目都使用vuex,對(duì)于中大型復(fù)雜項(xiàng)目而言,需要共享的狀態(tài)很多時(shí),使用vuex才是最佳的選擇。接下來我將詳細(xì)介紹各api的概念和作用。

  • state 單一狀態(tài)樹,用一個(gè)對(duì)象就包含了全部的應(yīng)用層級(jí)狀態(tài),并且作為一個(gè)唯一數(shù)據(jù)源而存在
  • getters 就像計(jì)算屬性一樣,getter 的返回值會(huì)根據(jù)它的依賴被緩存起來,且只有當(dāng)它的依賴值發(fā)生了改變才會(huì)被重新計(jì)算 比如如下案例:
const store = new Vuex.Store({  
state: {
todos: [
{ id: 1, text: '...', done: true },
{ id: 2, text: '...', done: false }
]
},
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
}
}
})
// 訪問getters里的屬性
this.$store.getters.doneTodos





Mutation 更改 Vuex 的 store 中的狀態(tài)的唯一方法,使用案例如下:

const store = new Vuex.Store({  
state: {
num: 1
},
mutations: {
add (state) {
// 變更狀態(tài)
state.num++
}
}
})

// 在項(xiàng)目中使用mutation
store.commit('add')
// 添加額外參數(shù)
store.commit('add', 10)





Action Action提交的是mutation,而不是直接變更狀態(tài),可以包含任意異步操作,具體用法如下:

const store = new Vuex.Store({  
state: {
num: 0
},
mutations: {
add (state) {
state.num++
}
},
actions: {
add (context) {
context.commit('add')
},
asyncAdd ({ commit }) {
setTimeout(() => {
commit('add')
}
}
})
// 分發(fā)action
store.dispatch('add')
// 異步action
store.dispatch('asyncAdd')
// 異步傳參
store.dispatch('asyncAdd', { num: 10 })





Module 將store分割成模塊(module)。每個(gè)模塊擁有自己的 state、mutation、action、getter、甚至是嵌套子模塊

筆者更具實(shí)際經(jīng)驗(yàn)總結(jié)了一套標(biāo)準(zhǔn)使用模式,就拿筆者之前的開源XPXMS舉例,如下:

store目錄是用來組織vuex代碼用的,我將action,mutation,state分文件管理,這樣項(xiàng)目大了之后也很容易管理和查詢。接下來看看是如何組織的:

// type.ts  
// 用來定義state等的類型文件
export interface State {
name: string;
isLogin: boolean;
config: Config;
[propName: string]: any; // 用來定義可選的額外屬性
}

export interface Config {
header: HeaderType,
banner: Banner,
bannerSider: BannerSider,
supportPay: SupportPay
}

export interface Response {
[propName: string]: any;
}

// state.ts
// 定義全局狀態(tài)
import { State } from './type'
export const state: State = {
name: '',
isLogin: false,
curScreen: '0', // 0為pc, 1為移動(dòng)
config: {
header: {
columns: ['首頁', '產(chǎn)品', '技術(shù)', '運(yùn)營', '商業(yè)'],
height: '50',
backgroundColor: '#000000',
logo: ''
}
},
// ...
articleDetail: null
};

// mutation.ts
import {
State,
Config,
HeaderType,
Banner,
BannerSider,
SupportPay
} from './type'

export default {
// 預(yù)覽模式
setScreen(state: State, payload: string) {
state.curScreen = payload;
},

// 刪除banner圖
delBanner(state: State, payload: number) {
state.config.banner.bannerList.splice(payload, 1);
},

// 添加banner圖
addBanner(state: State, payload: object) {
state.config.banner.bannerList.push(payload);
},

// ...
};

// action.ts
import {
HeaderType,
Response
} from './type'
import http from '../utils/http'
import { uuid, formatTime } from '../utils/common'
import { message } from 'ant-design-vue'

export default {
/**配置 */
setConfig(context: any, paylod: HeaderType) {
http.get('/config/all').then((res:Response) => {
context.commit('setConfig', res.data)
}).catch((err:any) => {
message.error(err.data)
})
},
/**header */
saveHeader(context: any, paylod: HeaderType) {
http.post('/config/setHeader', paylod).then((res:Response) => {
message.success(res.data)
context.commit('saveHeader', paylod)
}).catch((err:any) => {
message.error(err.data)
})
},
// ...
};

// index.ts
import Vue from 'vue';
import Vuex from 'vuex';
import { state } from './state';
import mutations from './mutation';
import actions from './action';

Vue.use(Vuex);

export default new Vuex.Store({
state,
mutations,
actions
});

// main.ts
// 最后掛載到入口文件的vue實(shí)例上
import Vue from 'vue';
import App from './App.vue';
import router from './router';
import store from './store/';
import './component-class-hooks';
import './registerServiceWorker';

Vue.config.productionTip = false;

new Vue({
router,
store,
render: (h) => h(App),
}).$mount('#app');





我們?cè)趯?shí)際項(xiàng)目中都可以使用這種方式組織管理vuex相關(guān)的代碼。

「1.7 vue-router基本使用模式和導(dǎo)航鉤子的用法及作用」

vue-router使用大家想必不是很陌生,這里直接寫一個(gè)案例:

// router.ts  
import Vue from 'vue';
import Router from 'vue-router';
import Home from './views/admin/Home.vue';

Vue.use(Router);

const router = new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{
path: '/',
component: Home,
beforeEnter: (to, from, next) => {
next();
},
children: [
{
// 當(dāng) /user/:id/profile 匹配成功,
// UserProfile 會(huì)被渲染在 User 的
path: '',
name: 'header',
component: () => import(/* webpackChunkName: "header" */ './views/admin/subpage/Header.vue'),
},

{
path: '/banner',
name: 'banner',
component: () => import(/* webpackChunkName: "banner" */ './views/admin/subpage/Banner.vue'),
},
{
path: '/admin',
name: 'admin',
component: () => import(/* webpackChunkName: "admin" */ './views/admin/Admin.vue'),
},
],
},
{
path: '/login',
name: 'login',
component: () => import(/* webpackChunkName: "login" */ './views/Login.vue'),
meta:{
keepAlive:false //不需要被緩存的組件
}
},
{
path: '*',
name: '404',
component: () => import(/* webpackChunkName: "404" */ './views/404.vue'),
},
],
});

// 路由導(dǎo)航鉤子的用法
router.beforeEach((to, from, next) => {
if(from.path.indexOf('/preview') < 0) {
sessionStorage.setItem('prevToPreviewPath', from.path);
}
next();
})

export default router





以上案例是很典型的靜態(tài)路由配置和導(dǎo)航鉤子的用法(如何加載路由組件,動(dòng)態(tài)加載路由組件,404頁面路由配置,路由導(dǎo)航鉤子使用)。如果在做后臺(tái)系統(tǒng),往往會(huì)涉及到權(quán)限系統(tǒng),所以一般會(huì)采用動(dòng)態(tài)配置路由,通過前后端約定的路由方式,路由配置文件更具不同用戶的權(quán)限由后端處理后返。由于設(shè)計(jì)細(xì)節(jié)比較繁瑣,涉及到前后端協(xié)定,所以這里只講思路就好了。

1.8 vue中檢測(cè)變化的注意事項(xiàng)

受現(xiàn)代 JavaScript 的限制,Vue 無法檢測(cè)到對(duì)象屬性的添加或刪除。由于 Vue 會(huì)在初始化實(shí)例時(shí)對(duì)屬性執(zhí)行 getter/setter 轉(zhuǎn)化,所以屬性必須在 data 對(duì)象上存在才能讓 Vue 將它轉(zhuǎn)換為響應(yīng)式的。還有一種情況是,vue無法檢測(cè)到data屬性值為數(shù)組或?qū)ο蟮男薷?,所以我們需要用原?duì)象與要混合進(jìn)去的對(duì)象的屬性一起創(chuàng)建一個(gè)新的對(duì)象。可以使用this.$set或者對(duì)象的深拷貝,如果是數(shù)組則可以使用splice,擴(kuò)展運(yùn)算符等方法來更新。

1.9 對(duì)指定頁面使用keep-alive路由緩存

keep-alive是Vue的內(nèi)置組件,能在組件切換過程中將狀態(tài)保留在內(nèi)存中,防止重復(fù)渲染DOM。我們可以使用以下方式設(shè)置某些頁面是否被緩存:

通過路由配置文件和router-view設(shè)置:

// routes 配置  
export default [
{
path: '/A',
name: 'A',
component: A,
meta: {
keepAlive: true // 需要被緩存
}
}, {
path: '/B',
name: 'B',
component: B,
meta: {
keepAlive: false // 不需要被緩存
}
}
]





路由視圖配置:

// 路由設(shè)置  














通過router-view的key屬性 具體方式如下:

  







1.10 vue常用工具函數(shù)總結(jié)

總結(jié)一下筆者在vue項(xiàng)目中的常用的工具函數(shù)。

識(shí)別ie瀏覽器

/**  
* 識(shí)別ie--淺識(shí)別
*/
export const isIe = () => {
let explorer = window.navigator.userAgent;
//判斷是否為IE瀏覽器
if (explorer.indexOf("MSIE") >= 0) {
return true;
}else {
return false
}
}





顏色16進(jìn)制轉(zhuǎn)rgba

/**  
* 顏色轉(zhuǎn)換16進(jìn)制轉(zhuǎn)rgba
文章名稱:Vue項(xiàng)目實(shí)戰(zhàn)精粹匯總,你知道幾個(gè)?
網(wǎng)頁網(wǎng)址:http://m.5511xx.com/article/djhcidd.html