[TOC]
## 前言
本文主要總結了vue實際開發項目當中應該如何解決一些實際的開發問題,可能你認為很簡單,但短時間內也許你并沒解決思路的。
## 常見技術解答
### for循環中針對ui樣式的特征性樣式或者事件
- 針對ui有特定的數據字段進行判斷(也叫數據模型方法)
這種書數據的要求比較高,且要求你能夠找到比較好的對應關系,需要針對class進行特征性的組件渲染。當你需要改變時改變數據即可重新渲染達到改變樣式的目的。
~~~
<li v-for="item of list" :key="item.id" :class="item.status?'color':''" @click="changeColor(item.id)">{{item.name}}</li>
return {
list:[
{id:1,status:true,name:1111},
{id:2,status:true,name:222}]
}
methods:{
changeColor(id){
this.list.map((item)=>{
if(item.id==id){
item.status=!item.status;
}
return item;
})
}
}
~~~
- 傳入對應的參數以及事件源,可以進行相應的判斷改變class
特點更加靈活,也可以根據需要傳入你需要傳入的item屬性參數進行與class的匹配判斷,不用改變接口返回的數據結構。
~~~
<li v-for="item of list" :key="item.id" @click="changeColor($event)">{{item.name}}</li>
return {
list:[
{id:1,name:1111},
{id:2,name:222}]
}
changeColor(e){
let el=e.target;
if(el.classList.contains("color")){
el.classList.remove("color")
}else{
el.classList.add("color")
}
}
~~~
### 計算屬性方法的使用
問題描述:如果你的計算屬性依賴于data的部分,而你的data對應的字段在data里沒有申明,只是在請求接口時進行申明賦值,那么當接口請求時,雖然數據發生了變化,但是計算屬性的值不會發生更新。
解決方案 :需要你在data里申明你計算屬性依賴的字段,哪怕是空或者null
### 事件執行順序問題
問題描述 :定義了輸入框blur,再按鈕點擊事件問題,其中默認click的話,執行順序是先執行blur再執行click.如果你需要場景在點擊的時候不執行blur的事件
解決方案:
1 常規方案 :
需要吧點擊事件變成@mousedown.prevent ,前者會讓點擊優于blur執行,后者會阻止blur執行
2 el-input并不生效,可以用計時器延遲執行
將失去焦點的事件計時器延遲執行,然后點擊事件里清除定時器,也是可以只執行點擊事件邏輯的
### 路由參數變化組件不更新
問題描述 :路由參數變化,但是組件沒有對應的更新,主要是因為一般獲取參數寫在了created路由鉤子函數中,路由參數變化的時候,這個生命周期不會重新執行。
解決方案1:watch監聽router
~~~
watch: {
// 方法1
'$route' (to, from) { //監聽路由是否變化
if(this.$route.params.articleId){// 判斷條件1 判斷傳遞值的變化
//獲取文章數據
}
}
//方法2 判斷頁面路徑
'$route'(to, from) {
if (to.path == "/page") { /// 判斷條件2 監聽路由名 監聽你從什么路由跳轉過來的
this.message = this.$route.query.msg
}
}
//方法 3 設置路徑變化時的處理函數
'$route': {
handler: 'resetData',
immediate: true
}
}
~~~
解決方案2 :為了實現這樣的效果可以給router-view添加一個不同的key,這樣即使是公用組件,只要url變化了,就一定會重新創建這個組件。
```
<router-view :key="$route.fullpath"></router-view>
```
解決方案3 :如果組件被放在<keep-alive>中的話,可以把獲取新數據的方法放在activated鉤子,代替原來在created、mounted鉤子中獲取數據的任務
### 異步函數中使用this無法指向vue實例對象
問題描述 : 在定時器或者其他異步函數中使用傳統的func導致this指向不到vue實例,主要原因是因為this指向的問題,詳細的可以參考我的《神奇的this》這篇文章。
解決方案 :用箭頭函數或者指定變量賦值為this(其他一些不能用箭頭函數的地方自己也要注意)
### 定時器在組件銷毀后還在執行
問題描述 :一些耗費性能的計時器或者動畫在組件銷毀之后還是執行的,導致性能變低。
解決方案 :在銷毀組件的生命周期中銷毀定時器或者一些動畫的js
~~~
//組件銷毀前執行的鉤子函數,跟其他生命周期鉤子函數的用法相同。
beforeDestroy(){
//我通常是把setInterval()定時器賦值給this實例,然后就可以像下面這么停止。
clearInterval(this.intervalId);
},
~~~
這里也給出第二種方案,通過$once這個事件偵聽器器在定義完定時器之后的位置來清除定時器。以下是完整代碼:
~~~
const timer = setInterval(() =>{
// 某些定時器操作
}, 500);
// 通過$once來監聽定時器,在beforeDestroy鉤子可以被清除。
this.$once('hook:beforeDestroy', () => {
clearInterval(timer);
})
~~~
類似于其他需要在當前頁面使用,離開需要銷毀的組件(例如一些第三方庫的picker組件等等),都可以使用此方式來解決離開后以后在背后運行的問題。
如果不清楚$once、$on、$off的使用,這里送上官網的地址教程,在[程序化的事件偵聽器](https://cn.vuejs.org/v2/guide/components-edge-cases.html#%E7%A8%8B%E5%BA%8F%E5%8C%96%E7%9A%84%E4%BA%8B%E4%BB%B6%E4%BE%A6%E5%90%AC%E5%99%A8)那里。
### 組件名與引入時大小寫不一致導致報錯
問題描述:
~~~
This can lead to unexpected behavior when compiling on a filesystem with other case-semantic.
Use equal casing. Compare these module identifiers:
~~~
解決方案 :需要嚴格對應組件的大小寫,避免低級錯誤
### 動態添加的dom沒有樣式
問題描述:作為常識我們知道style中的樣式都會追加scoped,這樣針對模板dom中的樣式就可以生效,但其生效后的最終樣式并不是我們寫的樣式名,而是編碼后的,所以我們在js中拼接上的dom結構樣式并不會生效。
解決思路:
1 當添加的部分樣式不會太多,而且是動態加載的,可以將其設置為非scopred的
2 將添加dom部分用的樣式放到非scoped樣式標簽中
3 將添加的部分,如果有必要,可以另外寫一個頁面拆分的vue組件
拓展 :
項目中引入的其他ui框架的樣式,如果你想覆蓋修改,也是需要不加scoped的,如果你想整個項目覆蓋,就可以在src/styles下定義customer-element.scss 這樣的來重寫覆蓋樣式。
### vue中直接修改對象數據,頁面視圖不更新
問題描述 :你的數據對象類型,沒有在data中進行定義,就沒有增加對其的監聽綁定,當你直接去使用或者定義數據時,會導致這個數據的vm視圖層不會及時更新.
解決方案:這時候需要你將其定義到data中就會增加對其的監聽。
備注:與此同理,你需要增加監聽的數據或者變化的數據如果需要數據變化時馬上更新,都要定義到data一份。
### vue中直接修改數組數據,頁面視圖不更新
問題描述 :在常規理解中,視圖與數據是雙向綁定的,但是有時候修改data的數組或者對象值,視圖不會更新 。
~~~
data() { // data數據
return {
arr: [1,2,3],
obj:{
a: 1,
b: 2
}
};
},
// 數據更新 數組視圖不更新
this.arr[0] = 'OBKoro1';
this.arr.length = 1;
console.log(arr);// ['OBKoro1'];
// 數據更新 對象視圖不更新
this.obj.c = 'OBKoro1';
delete this.obj.a;
console.log(obj); // {b:2,c:'OBKoro1'}
~~~
解決方案 :由于js的限制,Vue 不能檢測以上數組的變動,以及對象的添加/刪除,很多人會因為像上面這樣操作,出現視圖沒有更新的問題。
1 this.$set(你要改變的數組/對象,你要改變的位置/key,你要改成什么value)
~~~
this.$set(this.arr, 0, "OBKoro1"); // 改變數組
this.$set(this.obj, "c", "OBKoro1"); // 改變對象
~~~
2 數組原生方法觸發視圖更新:
splice()、 push()、pop()、shift()、unshift()、sort()、reverse()
推薦使用splice方法會比較好自定義,因為slice可以在數組的任何位置進行刪除/添加操作
3 替換數組
比方說:你想遍歷這個數組/對象,對每個元素進行處理,然后觸發視圖更新。
~~~
// 文檔中的栗子: filter遍歷數組,返回一個新數組,用新數組替換舊數組
example1.items = example1.items.filter(function (item) {
return item.message.match(/Foo/)
})
~~~
- [codepen地址,可以進行問題重現](https://codepen.io/robinson90/pen/ZRWyYX)
### 需要無腦重復某內容
~~~
<div v-for="n in 5">
<span>這里會被渲染5次,渲染模板{{n}}</span>
</div>
~~~
### babel-plugin-transform-runtime使用
* 出現問題:這個插件可以兼容并轉化大部分的es6語法,但是部分語法也是不能轉化或者存在具體問題的。
1. 異步加載組件時,會產生 polyfill 代碼冗余
2. 不支持對全局函數與實例方法的 polyfill。不支持全局函數(如:Promise、Set、Map),Set 跟 Map 這兩種數據結構應該大家用的也不多,影響較小。但是 Promise 影響可能就比較大了。不支持實例方法(如:'abc'.include('b')、['1', '2', '3'].find((n) => n 等等),這個限制幾乎廢掉了大部分字符串和一半左右數組的新特性。
而兩個問題的原因均歸因于 babel-plugin-transform-runtime 采用了沙箱機制來編譯我們的代碼(即:不修改宿主環境的內置對象)。由于異步組件最終會被編譯為一個單獨的文件,所以即使多個組件中使用了同一個新特性(例如:Object.keys()),那么在每個編譯后的文件中都會有一份該新特性的 polyfill 拷貝。如果項目較小可以考慮不使用異步加載,但是首屏的壓力會比較大。
* 解決方案:一般情況下 babel-plugin-transform-runtime 能滿足大部分的需求,當不滿足需求時,推薦使用完整的 babel-polyfill。
* 首先,從項目中移除 babel-plugin-transform-runtime,卸載該依賴: `npm un babel-plugin-transform-runtime -D`,
* 接著修改 babel 配置文件
~~~
// .babelrc
{
//...
"plugins": [
// - "transform-runtime"
]
//...
}
~~~
* 然后,安裝 babel-polyfill 依賴:
`npm i babel-polyfill -D`
* 最后,在入口文件中導入
~~~
// src/main.js
import 'babel-polyfill'
~~~
### ES6 import 引用問題
在 ES6 中,模塊系統的導入與導出采用的是引用導出與導入(非簡單數據類型),也就是說,如果在一個模塊中定義了一個對象并導出,在其他模塊中導入使用時,導入的其實是一個變量引用(指針),如果修改了對象中的屬性,會影響到其他模塊的使用。
通常情況下,系統體量不大時,我們可以使用 JSON.parse(JSON.stringify(str)) 簡單粗暴地來生成一個全新的深度拷貝的 數據對象。不過當組件較多、數據對象復用程度較高時,很明顯會產生性能問題,這時我們可以考慮使用 Immutable.js。
鑒于這個原因,進行復雜數據類型的導出時,需要注意多個組件導入同一個數據對象時修改數據后可能產生的問題。
此外,模塊定義變量或函數時即便使用 let 而不是 const,在導入使用時都會變成只讀,不能重新賦值,效果等同于用 const 聲明。
### 動態懶加載組件
背景:在webpack的新特性中支持組件的懶加載,也就是說我們可以在加載到該路由的時候再把這部分腳本進行加載,同時這個在項目進行打包的時候,對應的文件也會被單獨打包,對于首屏優化以及其他頁面的資源加載優化都是非常好的。這也要求我們在每個頁面組件使用組件的時候盡量按需引入,提升體驗。
問題場景:那么我們需要解決的問題是:
0 webpack是靜態解析路徑的,直接傳入變量并不可行
1 每次都寫一串加載組件的代碼很不方便,是否可以支持寫成一個加載組件的方法
2 是否支持區分生產和開發環境,因為開發環境使用懶加載會導致熱更新,導致更新變慢,所以開發環境使用全量默認加載,生產環境使用懶加載
解決方案如下 :
1 webpack的路徑使用變量拼接,必須預先給出一個相對路徑,然后把具體的組件路徑在傳入
2 用一個箭頭函數,將需要傳入的組件名或者相對路徑傳入
3 用process.env.NODE_ENV確定使用哪種加載方式
代碼如下:
在原來的router/index.js中,定義一個加載組件的_import方法。
~~~
// router/index.js
const _import = require('./_import_' + process.env.NODE_ENV)
//使用時
{
path: '/',
name: 'HelloWorld',
component: _import('HelloWorld')
},
// router/_import_development.js
module.exports = file => require('@/views/' + file + '.vue').default // vue-loader at least v13.0.0+
// router/_import_production.js 如果你加載的vue不是這個路徑 請自定義哦
module.exports = file => () => import('@/views/' + file + '.vue')
~~~
**注意事項:**
1 如果配置完之后,可能會有部分樣式文件或者圖片引入的src路徑之外的,比如說static,報錯找不到對應的文件,這時候需要改為根路徑static的路徑就可以解決這個報錯?你需要裝的模塊:sass-loader,node-sass,stylus,stylus-loader,style-loader,css-loader,url-loader即可。具體的包需要進一步確定。
2 在具體的頁面中,如果你想懶加載組件,也是如此的寫法
```
import vOther from '@/components/other'
//修改后
const vOther = () => import('@/components/other')
```
### vue中的data必須為函數
**場景** :vue入門的人可能在頁面單獨引入vue的時候,直接使用data為對象類型的,并沒有問題,但是在spa應用中,如果組件中的data為對象類型就會報錯。
**解決方案** :data換為函數,返回對象類型的鍵值對。
拓展 :你可能知道要這樣做,這里稍微科普下原因,主要是因為根組件只會用一次,所以可以用對象,而子組件可能在一個應用中被多次使用,為了避免多個組件使用同一數據互相影響,所以講data約定為了返回函數類型,返回需要的對象,以此保證子組件在數據渲染的時候不會互相影響。
### 有父子標簽關系的自定義組件渲染失敗
**場景** :在自定義組件的時候,很多時候需要將ul下的li標簽,table下的tr\td標簽進行封裝為自定義組件,但直接使用自定義組件會導致其最終生成的位置不是我們想要的。截圖如下:
~~~
Vue.component("row",{
template:'<tr><td>{{content}}</td></tr>',
data(){
return {
content:'this is a row'
}
},
})
~~~


**解決方案** :原因是因為html會進行標簽解析,tbody下的標簽必須為tr,其他的同理。那么我們可以將其子標簽設置為原來的標簽類型,然后用is="selfComponent" 來解決這個問題。
`<tr is="row"></tr>`
- [vueComponents使用](https://codepen.io/robinson90/pen/GGjmyx)
拓展:
- 不要將渲染vue的容器元素定位到html或者body上,否則提示:` Do not mount Vue to <html> or <body> - mount to normal elements instead.`
- 確保有在vue新建實例的時候將el屬性綁定到一個html模板的標簽上
### ref使用
**場景** :雖然vue不建議直接操作dom,但是在復雜的場景中,我們需要進行dom的操作,這時候就可以借助ref實現。比如下面我們舉一個簡單的例子,通過ref獲取dom節點,拿到其內容。
**解決方案** :
~~~
<div @click="handleClick" ref="hello">hello world
</div>
handleClick(){
console.log(this.$refs.hello)
}
~~~
- 拓展案例 :實現計數器加和
場景 :假設我們有兩個計數器組件的實例,現在需要用ref的方案得到兩個計數器的加和。
代碼如下:
~~~
<counter ref="one" @change="handleChange"></counter>
<counter ref="two" @change="handleChange"></counter>
<span>{{total}}</span>
Vue.component("counter",{
template:"<div @click='change'>{{number}}</div>",
data(){
return {
number:0}
},
methods:{
change(){
this.number++;
this.$emit("change")
}
}
})
//app父組件方法
handleChange(){
this.total=this.$refs.one.number+this.$refs.two.number
},
~~~
- 拓展認知 :
this.$refs.name中如果是原生標簽,拿到的是原生標簽的節點,如果是組件,拿到的是組件的引用。
如果你用.name獲取不到,可以嘗試用【name】方式。
- [vueRefDemo使用](https://codepen.io/robinson90/pen/OERmra)
## 參考文檔
- [vue項目實踐中的一些問題](http://mp.weixin.qq.com/s/fgFOvWBC_P78hG154gyXYQ)
- 前端工程化
- 架構總綱
- 001
- 美團技術架構
- 前端工程化說明
- 歷史背景說明
- 架構說明
- 前端工程化技術棧
- 技術文檔說明
- 功能模塊說明
- 前端模塊管理器簡介
- 框架對比分析
- vue&react&ng對比分析(一)
- vue&react&ng對比分析(二)
- vue&react&ng對比分析(三)
- 工程化專題系列
- 需要解決的問題
- 001
- 002
- 003
- 常見代碼錯誤
- jslint中常見的錯誤
- css規范常見錯誤
- html規范常見錯誤
- 工程化目錄
- 工程化初始化
- 項目構建流程
- 項目打包優化
- 上線與迭代注意事項
- 前端部署發布
- jetkins部署
- 部署需求整理
- 前端監控
- 工程化實踐指南
- dock持續部署
- 系列文章
- 插拔式前端的設計
- 其他實踐
- 工程化的前端管理
- 宋小菜借鑒
- 大前端團隊介紹
- 人員組成
- 人員發展
- 研發流程
- 任務分類
- 前端基礎建設與架構
- 技術棧以及技術方案
- 業務目錄大綱
- 前端大綱
- api管理
- 后端api工具
- 前端easymock
- api攔截與代理
- api優化
- api請求時長策略設計
- 前端架構專題
- 架構專題一
- 產品原型對接
- 與ui對接
- 圖片專題
- 圖片工程化大綱
- 圖片優化
- 圖標字體
- 圖標字體vs雪碧圖
- 工程化的前端矩陣
- 螞蟻金服前端矩陣分享
- BFF架構
- 概念解析
- 前端腳手架
- 初始化項目
- 個性化配置
- 部署與發布
- 性能優化專題
- http專題
- https常識
- http優化1
- http優化2
- http優化3
- http緩存
- 常規web性能優化攻略
- 性能優化大綱
- 樣式優化
- js優化
- 第三方依賴優化
- 代碼分割優化
- 圖片優化
- 打包優化
- 服務器優化
- 緩存優化
- 交互優化
- pc事件優化
- 手機事件優化
- 推薦文章
- 01
- 前端安全專題
- 前端安全大綱
- 前端第三方庫
- seo優化
- web框架的對比
- 001
- 學習資源
- 珠峰前端架構
- npm教程
- npm入門
- cnpm入門
- cnpm搭建
- 你該知道的js模塊
- browserSync
- opn
- js-cookie
- npm-script進階
- 入門篇
- 進階篇
- 高階篇
- 實踐篇
- yarn入門
- nodejs教程
- axios&&fetch
- xhr
- axios
- fetch
- babel專題
- babel入門
- profill入門
- nodejs入門
- 快速入門
- 大綱介紹
- node基礎
- global obj
- assert斷言
- procss-進程
- child_process子進程
- cluster集群
- console控制臺
- crypto-加密
- dgram-數據報
- dns-域名服務器
- error-異常
- events-事件
- global-全局變量
- http-基本協議
- https-安全協議
- modules-模塊
- os-操作系統
- path-路徑
- querystring-查詢字符串
- readline-逐行讀取
- fs-文件系統
- net-網絡操作
- 命令行工具
- 內存泄露
- 代碼的組織與部署
- 異步編程
- orm模塊
- 異步編程解決方案
- node-lessons
- 環境準備
- nodejs實踐
- 項目搭建
- 異步優化
- 創建web和tcp服務器
- 終端問答程序
- 爬蟲系統
- mongleDb
- mongoDB簡介
- 基本使用
- 實用技巧
- 匯總001
- 餓了么后臺搭建
- nodejs干貨
- 滬江基于node的實踐
- 蘇寧基于nodejs優化
- 基于nodejs開發腳手架
- 書籍干貨
- 深入淺出nodejs
- 異步I/O(一)
- gulp教程
- gulp入門
- gulp常用插件(1)
- gulp常用插件(2)
- gulp創建目錄
- 經驗普及貼
- webpack教程
- webpack入門
- 簡單入門
- entry配置
- output配置
- 插件使用01
- 插件使用02
- loader使用
- dev-server介紹
- 構建css
- css模塊化
- 使用less和sass
- 構建圖片
- 引入字體
- babel配置攻略
- eslint
- 001
- webpack進階
- 分不同文件檢出
- 優化打包大小
- 優化打包速度
- 自定義配置
- 單頁以及多頁如何配置
- 優化實踐
- 文章導讀
- 001
- 優化指南
- 參考列表
- webpack4
- 多入口程序構建
- 參考教程
- 項目實踐
- 環境區分
- 常見問題
- 解讀webpack
- 從vuejs權威指南中解決
- 深入淺出webpack
- rollup
- 入門
- parcel
- 入門篇
- express教程
- nuxt教程
- 入門
- 基本入門
- koa教程
- koa基本入門
- koa開發注意事項
- koa實踐指南
- 關于路由
- koa優化指南
- 001
- Vuejs
- vuejs入門系列
- vue-cli入門
- vue2基本認識
- vuejs入門教程
- 樣式綁定
- vuex入門學習筆記
- vue組件生命周期
- 組件的使用
- vue-router入門
- vue-filter
- 計算屬性使用
- 開發注意事項
- mixins
- 組件通訊
- vuejs進階
- 進階資源
- router進階
- 官網介紹
- 前進與后退優化
- keep-alive基本使用
- keep-alive原理詳解
- 鉤子函數進階
- 計算屬性&監聽&方法
- vue服務端渲染技術
- 項目實踐之路
- 實踐大綱
- 插槽專題篇
- vue-cli升級
- 進階入門
- vuejs架構
- nuxt
- vuejs項目實踐
- vue實踐常見問題
- 001
- 002
- 003
- 004
- 005
- 改造api參數探索
- 007
- 008
- 009
- 010
- 項目技術棧
- vue性能問題以及優化方案
- vue-spa應用的理解
- vue-ssr的部署與使用
- 滴滴出行實踐案例
- 2.0重構
- vue-element-admin實踐
- 準備工作
- 菜單設計
- 權限設計
- 依賴模塊
- vue-betterScroll
- 性能優化懶加載
- 京東組件實踐
- vue2項目小結
- vue探索與實踐
- 去哪實踐
- 介紹
- 餓了么項目實踐
- 項目解析
- vue骨架屏實踐
- vue生態推薦
- ui框架
- elementUI
- 001
- 002
- VUE-material
- vant-ui
- 解讀入門
- iview
- 使用問題匯總
- vux
- mint-ui
- loadmore
- vue資源導航
- vueconf
- 源碼解讀
- vm
- 雙向綁定
- 基本原理
- 數組雙向綁定
- 報錯機制
- 封裝方法
- 運行環境
- 入門
- 指令
- vue-router解讀
- util
- vue-props
- 流程邏輯
- 推薦文章
- 源碼解讀
- 文章導讀
- 001
- vuejs實戰
- 基礎篇
- 進階篇
- 實踐篇
- 面試專題
- angularjs教程
- angularjs入門系列
- 基本入門
- ng2入門
- ng進階
- ng項目實踐
- 源碼解讀
- typescript
- reactjs教程
- reactjs入門系列
- react的基本入門
- react組件
- virtalDom認識
- react-cli入門
- react組件的生命周期
- 基本知識點
- react-router教程
- react進階
- 基本實踐
- react加載性能優化指南
- react屬性封裝
- 進階45講
- 01概述
- 02jsx
- 06高階組件&函數子組件
- contextApi
- react-router
- 入門章節
- 進階
- 高階組件
- react進階組件
- 基本介紹
- render props
- render props的封裝
- render props getter
- react-native入門
- 源碼解讀
- 001
- 002-reactDemo
- 參考教程
- 參考教程1
- 了解react-hooks
- ui框架
- pc端ui框架推薦
- 項目實踐
- weatherApp
- 001
- 002
- 不同生命周期使用場景
- react項目結構和組件的命名
- 常見問題解答
- 參考書籍
- react全棧
- 前言
- react與redux進階
- 常見誤解
- 反模式
- react設計模式與最佳實踐
- 7美化組件
- 7.2行內樣式
- 7.4css模塊
- 深入react技術棧
- react學習手冊
- 序
- mobx教程
- 入門
- 大佬推薦
- 001
- react面試
- 001
- linux教程
- linux入門
- 基本入門
- 文件管理
- 文件傳輸
- 文檔編輯
- 磁盤管理
- 磁盤維護
- 網絡通訊
- 系統管理
- 系統設置
- 備份壓縮
- 設備管理
- 查看系統信息
- linux其他
- webhook
- rsync入門教程
- ssh免登陸設置
- 安裝nodejs
- nginx教程
- 入門教程
- 安裝
- 基本配置
- 服務基本使用
- 高性能nginx
- 001
- pm2教程
- shell教程
- 入門大綱
- echo命令
- 參考文獻
- linux常用命令2
- linux常見問題
- 001
- python
- 入門教程
- 機器學習
- 準備工作
- 服務器常識
- tomcat
- 入門常識
- iis
- redis教程
- 入門第一篇
- redis進階
- 項目實踐
- redis使用問題
- mongleDB
- 入門
- 使用進階
- 項目實踐
- 常見問題
- electron
- 入門系列
- 前言
- 小程序
- 入門
- 準備工作
- 路由
- 參考文檔
- 001
- 小程序開發--雙路視頻調研
- 準備工作
- 參考資源
- 參考網址
- docker
- 入門
- 基本認識
- 安裝與使用
- docker安裝nginx
- docker安裝jetkins(1)
- docker部署jenkins(2)
- 進階
- 實踐總結
- docker群分享
- docker部署前端應用
- 文章導讀
- docker其他
- 網絡安全
- 入門
- 大綱
- 項目解析
- schoolpal.web
- 功能模塊大綱
- 目錄結構大綱
- 前端國際化
- 國際化方案
- 其他
- bower入門教程
- weex
- 入門
- memcached
- 入門
- sails
- 入門