vue 學習總結

# 傳智播客vue 學習## 1. 什么是 Vue.js* Vue 開發手機 APP 需要借助于 Weex* Vue.js 是一套構建用戶界面的框架, **只關注視圖層**, 它不僅易于上手,還便于與第三方庫或既有項目的整合。* 前端主要工作主要負責MVC 中的 V 這一層;主要工作是和界面打交道,來制作前端頁面效果。### 為什么要學習流行框架* 提高開發效率* 提高效率 原生 JS -> jQuery 之類的類庫 -> 前端模板引擎 -> angular.js / vue.js (能夠減少我們不必要的 DOM 操作,提高渲染效率;雙向數據綁定的概念【通過框架提供的指令,我們前端程序員只需要關心數據的業務邏輯,不再關心 DOM 是如何渲染的】)* 在 Vue 中,一個核心的概念就是讓用戶不再操作 DOM 元素,解放用戶的雙手,讓程序員更多的時間去關注業務邏輯。(去關注 MVC 的C層)## 2. 框架和庫的區別* 框架:提供了一整套解決方案;對項目的侵入性較大,如果想要更換框架,則需要重新架構整個項目。* node 中的 express* 庫(插件): 提供某個小功能,對項目的入侵性較小,如果某個庫無法完成某些需求,可以很容易切換到其他庫實現需求。## 3. 后端 MVC 與 前端中的 MVVM 之間的區別* MVC 是后端的分層開發概念。(M 主要是CRUD,數據)(v就是視圖層)(c 就是業務邏輯層,路由,登錄 啊、注銷)* MVVM 是== 前端視圖層 ==的概念,主要關注于 視圖層分離,也就是說:MVVM 把前端的視圖層,分為三個部分:Model, View, VM ViewModel* MVVM 主要把每個頁面分成了 M、V和VM。其中,VM 是 MVVM 思想的核心;因為VM 是 M 和 V 之間的調度者。* MVC 是后臺對整個項目結構歸類,MVVM 只是前端的視圖層。* MVVM 中的 M 保存著每個頁面中單獨的數據,(后臺返回的數據)。V就是每個頁面中的HTML 結構。 VM 它是一個調度者,分割了M和V,每當V層想要獲取或者保存數據的時候,都要由VM做中間件的處理。* 前端頁面中的使用,MVVM 的思想,主要是為了讓我們方便開發,因為 MVVM 提供了數據的雙向綁定;注意:數據的雙向綁定是由MV 提供 的。* 三大框架都適合做單頁面應用### 配置webpack babel* 安裝 npm i babel-loader babel-core babel-preset-es2015 babel-plugin-transform-runtime -D* rules: [ // 第三方匹配規則? { test: /\.js|jsx$/,use: 'babel-loader', exclude: /node_modules/ }//千萬別忘記添加 exclude 排除項? ],# Vue 語法## 1. vue 的基本代碼* 本次學習 vue 版本為 2.4.0* 在頁面導入 vue 包 ```html```* 創建一個 Vue 的實例 當我們導入 vue 之后,在瀏覽器的內存中,就會多了一個 Vue 構造函數。 ```javascript

{{ msg }}

? ? ? ? ? // 2. 創建一個Vue 實例

? ? ? ? ? //? 當我們導入包之后,在瀏覽器的內存中,就多了一個 Vue 構造函數

? ? ? ? ? // 注意: 我們 new 出來的 vm 對象,就是我們的 MVVM 中的 VM 調度者

? ? ? ? ? var vm = new Vue({

? ? ? ? ? ? ? el: "#app",? // 表示我們 new 的這個 Vue 實例,要控制在頁面上的哪個區域

? ? ? ? ? ? ? // 這里的 data 就是 MVVM 中的 M,專門用來保存每個頁面的數據

? ? ? ? ? ? ? data: {? ? //data 屬性中,存放著是 el 中要用到的數據,不用再操作DOM 根據提供的指令直接操作

? ? ? ? ? ? ? ? ? msg: 'hello Vue' // Vue 不提倡我們手動去操作 DOM 元素

? ? ? ? ? ? ? }

? ? ? ? ? })

? ? ? ```## 2. 單文件方式啟動* 單文件就是以`*.vue` 結尾的文件,最終通過 webpack 也會編譯成為 `*.js` 在瀏覽器中運行。* 內容:++1. template 中只能有一個根節點 2.x(例如下面只能寫一個 div)2. script 中 按照 export default {配置} 來寫3. style 中可以設置scoped 屬性,讓其只在 template 中生效### 以單文件的方式啟動配置好 webpack 之后安裝 vue 相關的。* webpack 找人來理解你的單文件代碼? * vue-loader ,vue-template-compiler, 代碼中依賴 vue,? ? 依賴關系(和安裝順序沒關系),先加載,再解析,再依賴vue? * 安裝 npm i vue -S? * npm i vue-loader vue-template-compiler -D#### 使用1. 引入 vue? ? import Vue from 'vue';2. 創建一個 Vue 實例,一般一個項目,大多數就是一個 vue 實例來完成顯示。? ```javascript? import Vue from 'vue'? import App from './app.vue'? ? ? // 創建一個Vue的實例,一般一個項目只有一個Vue實例來完成顯示? new Vue({? ? ? el: "#app",? // 目的地? ? ? render(creater) {? // 渲染的內容? ? ? ? ? return create(App)? ? ? }? })? ```? Vue 模塊化開發? 創建一個 app.vue 文件? ```javascript? export default {

? ? ? // 配置

? ? ? // 類似于 $scope.xxx = 'aaa'

? ? ? data() {

? ? ? ? ? return {

? ? ? ? ? ? ? txt: 'hello world',

? ? ? ? ? ? ? list: [{name: 'aaa'},{name: 'bbb'}]

? ? ? ? ? }

? ? ? }

? }


? ```? * 注意: 每一個 第三方模塊都有一個 package.json 文件,其中 main 屬性后面對應的是入口文件。## 3. 項目結構* src 下存放著人可以看懂的代碼,具備一定的功能劃分,MVC* dist 存放著上線的代碼,(減少請求、混淆代碼),機器能看懂* 兩個命令? * webpack 立即讀取 配置文件,生成到 dist 目錄下? * Webpack-dev-server 運行 src 下的代碼,虛擬出 build.js 測試* 拿到項目 npm i,? npm i --production? 不會安裝開發環境的依賴## 4. vue 組件化* angular 模塊化, 雙向數據綁定(臟檢測: 一個數組($watch),更改之后檢測一大堆,效率較差)* vue 組件化? 組件: 組合起來的一個部件? * 頭部: 頁面、樣式、 動態效果? * 代碼: template? style? script? * 雙向數據流(基于ES5中的 defineProperty 來實現的,監聽),IE9才支持## 5. 雙向數據流1. js 內存屬性發生改變,影響頁面的變化2. 頁面的改變影響Js內存屬性的改變## 6. 常用指令* v-text 是元素的 inner-Text 只能在雙標簽中使用(單標簽一般用 value 屬性)* v-html 是元素的 innerHTML, 不能包含 {{xxx}} 表達式* v-if? 元素是否移除或者插入* v-show 元素是否顯示或隱藏* v-model 雙向數據綁定? 一般使用在 input 標簽中? 使用不需要再給 input 標簽再給 value 值,value 只能給字符串,不能給變量。? v-model 能給 select 標簽選中變量指定的 option? 注意: v-model 相當于綁定表單元素的 value 屬性* v-bind 給元素某屬性賦值? 例: v-bind:value='text' 這種綁定是單向的? 綁定之后可以傳遞變量來實現屬性的綁定。v-bind 會把后面綁定的屬性當做變量來執行,符合 js 語法的都可以直接寫。* V-cloak 這個指令保持在元素上直到關聯實例結束編譯。和 CSS 規則如?`[v-cloak] { display: none }`?一起用時,這個指令可以隱藏未編譯的 Mustache 標簽直到實例準備完畢。? v-cloak 當做一個class一樣的屬性來使用。 在樣式中使用像元素屬性一樣使用,直接用[]包圍。避免閃爍。* ```? [v-cloak] {? ? display: none;? }

? ? {{ message }}


```v-bind 是單向數據綁定(內存js 改變影響頁面),v-model 雙向數據綁定### class 結合 v-bind 使用* 需要根據可變表達式的結果來給 class 賦值,就需要用到 v-bind:class="xxx"? ```javascript? export default {

? ? ? data() {

? ? ? ? ? return {

? ? ? ? ? ? ? isRed: true

? ? ? ? ? }

? ? ? }

? }

? ? ? ? .red {

? ? ? ? ? background: red;

? ? ? }

? ? ? .green {

? ? ? ? ? background: green;

? ? ? }

? ```

aaaaaa

可以簡寫,并且傳遞對象? 變量是直接在字符串中使用,class 是在字符串中加 字符串? V-bind:? 可以簡寫為 :* v-bind:屬性名=“表達式”,最終表達式運算結束的結果賦值給該屬性名? * 引號里面可以放變量,也可以放字符串,字符串需要引號,把它當成一個 js? 區域即可。? ? 加引號表示一個字符串,不加引號表示一個變量? * 多個樣式:返回對象(樣式做key,true或false做為值)? ? 對象的 key 可以加引號,也可以不加引號* 使用數組傳值的形式? :class="['red', 'green']"注意: 傳遞多個class 的時候,不能夠像 HTML 中直接并排寫,需要使用數組或者對象的形式。單個class 即可以直接寫。### 內聯樣式1. 直接在元素上通過 :style 的形式,書寫樣式對象? ```html


```? 采用了 : 就代表這是一個js 區域,因此 font-size 這樣的 - 的樣式需要加引號,也可以使用 fontSize 這樣的 JS 樣式書寫方式2. 直接使用 html 的內聯樣式? 直接使用3. 在 data 中寫一個對象,對象中防止它的樣式4. 放一個數組,數組中傳遞一個一個的樣式對象(data中定義好的),注意與 class 的區別。class 中的對象是在 style 標簽中定義的,行內樣式的對象是在 data 中定義的對象。### 6.1 事件* 綁定事件: v-on:事件? 例如: v-on:click? 事件后面加變量或者函數等任何表達式? 事件能夠實時監測頁面,頁面會根據綁定變量的變化而變化? 簡寫:@事件名=“表達式||函數名”? * 函數如果沒有參數,可以省略括號 @click="fn"? * 綁定函數? 事件后面可以直接綁定函數。 v-on:click="fn()"? 在方法中使用當前模塊的變量需要加 this 來調用* 函數寫在 methods 中? 聲明組件內函數,在 export default 這個對象的根屬性加上 methods 屬性,其是一個對象? * key 是函數名 值是函數體? 在 export default 這個對象的跟屬性加上 data 屬性,其是一個函數,返回一個對象? * 對象 的屬性使我們初始化的變量的名稱#### 6.1.1 事件修飾符* 在事件處理程序中調用?`event.preventDefault()`?或?`event.stopPropagation()`?是非常常見的需求事件修飾符:* .stop 阻止冒泡? 一定要明確 冒泡 行為是從里到外,阻止之后外層盒子綁定的事件將不再執行,不再有委托特性。* .prevent 阻止默認事件? 比如說 a 標簽的點擊觸發事件,,能夠阻止a 標簽的跳轉* .capture 添加事件偵聽器時使用事件捕獲模式? 與冒泡觸發事件相反。從外向里觸發事件。* .self 只當事件在該元素本身(比如不是子元素)觸發時觸發回調? 防止事件委托。.self 與 .stop 的區別就是 .self 是給最外層的盒子加的修飾符,.stop 是 給子元素添加的修飾符。.self 并不能阻止從它本身向外冒泡的性質。* .once 事件只觸發一次事件修飾符可以鏈式調用,例如 .prevent.once,once 是作用于 前面的事件的,阻止默認事件只執行一次。使用:?@click.stop * v-for 的使用? 可以使用操作數組 (item,index)? 可以使用 操作對象 (value, key, index)? 使用:? 數組: v-for="(value, index) in arr" :key="index"? 對象:? v-for="(value, key, index) in obj" :key="index"? 數字:迭代數字? v-for="i in 10" 也需要key? 需要綁定 key ,key 的值可以為 number 也可以為 string 不能為對象? :key="index"? 注意: key 的值最好用 value 中一項,防止出錯總結:1. v- 指令后面加字符串,字符串中加js變量或者語句* data 中的數據既可以使用v-text 類似有意義的綁定,也可以在 {{}} 中直接使用。2. 凡是在 template 中使用 當前模塊的變量,不需要加this? ? 在script中使用當前模塊的變量,需要加 this3. 沒有加 v- 的指令需要使用 v-bind: 來綁定4. 實例化的 Vue 對象會實時監聽自身 data 的變化,只要數據發生改變,就會自動把最新的數據,從 data 中同步到頁面上。好好處就是 只關心數據,不需要操作 DOM ,關心 DOM 的改變。5. v-if? 直接不會創建出該元素? v-show 只是會隱藏該元素? v-if 有較高的切換性能消耗? v-show 有較高的初始渲染消耗### 6.2 eval() 方法的再次登場* 計算字符串中的值,并返回(若果有的話)* 字符串中是表達式,不是語句### 6.3 array 又添加方法啦* arr.map 方法,能夠遍歷數組中的每個元素,做出相應的處理。參數為function(item,key)和forEach 相同* arr.some 方法,找到符合條件的元素就結束。參數相同,都是用 return 來結束* arr.forEach() 方法,只是遍歷數組,不會對本數組進行操作,可以用外面的數組來進行對比操作* arrfilter() 方法,過濾吊不符合的元素,并返回新數組## 7. SPA(單頁面應用)組件的使用* 使用組件的組件就是父組件* 被使用的組件就是子組件單頁面中使用組件:(在導出的對象中)```javascriptcomponents: {? ? // 組件名(在末班中使用的):組件對象}```組件對象需要在script 標簽中使用 import 引入* 單頁面樣式的使用? 如果希望該樣式只在當前組件有效,可以給 style 加一個 scoped 屬性* 父子組件的使用(父傳子)? * 父和子,使用的父,被使用的是子? * 父需要聲明子組件,引入子組件對象,聲明方式如下? ```javascript? components: {? ? ? // 組件名(在末班中使用的):組件對象? }? ```? 需要先引入一下。? 注意引入的組件名稱不能夠使用 - 來連接* 全局組件,使用更為方便,不需要聲明,直接使用,需要在 main.js (index.js) 中引入? 在 main.js (index.js) 中引入一次,使用 vue.component('組件名', 組件對象);? 注冊一個組件,第一個參數是名稱,在 template 中使用,第二個參數是實際的對象,顯示成什么內容,具備什么功能? ```javascript? import Vue from "vue"? import App from "./components/app.vue"? import Headervue from "./components/header.vue"? import Bodyvue from "./components/body.vue"? import Footervue from "./components/footer.vue"? ? Vue.component("Headervue", Headervue);? Vue.component("Bodyvue", Bodyvue);? Vue.component("Footervue", Footervue);? ? new Vue({? ? ? el:"#app",? ? ? render(creater) {? ? ? ? ? return creater(App)? ? ? }? })? ```? 直接就可以全局使用了。* 接受父組件值參數的設置? 例子:props: ['text1']? ?是一個數組,可以接受很多數據。== 接受組件在實例化過程中傳遞的參數。 ==? ?組件在作為標簽使用的時候要定義一個 text1 = 'aaa'? 的屬性。? 可以通過使用 v-bind:text="name" 的形式,來讓 text 能夠被賦值變量。? 在js 中獲取props 中的值,直接使用 this.text 來獲取,和獲取 data 中的數據是一樣的。 ### 7.1 父傳子* 父組件通過子組件的屬性將值進行傳遞? 方式有2:常量, 變量* 子組件需要聲明? 根屬性 props: ["prop1", 'prop2']? 在頁面中直接使用 {{prop1}}注意: 1. 組件 當標簽使用的時候,不能再給標簽中加東西了(加了也不頂用),而且都是雙閉合標簽2. 只有帶 v- 的屬性可以傳遞變量,其他自定義的只能傳遞字符串,當做傳入的值。可以使用 v-bind:text=""的形式來綁定,這樣之后就可以直接傳遞變量。3. 子組件的形式是一下傳遞一個子組件對象,全局組件的形式是一個一個傳入組件對象,因此一個加 s 一個不加 s## 8. 如何查看 vue 文檔* 全局 API 和 配置? 通過Vue. 能夠調用的* 實例方法/事件? 實例:組件內的 this 和 new Vue()? ![vueNode1](./vueNode1.png)? 只要能調用 this,就是一個實例* 選項/數據? options/類別 和實例相關,就是實例中的export 導出的那部分的key和new Vue 中傳遞的參數* 全局的 API 是在 index.js 文件中添加,然后所有的 組件 中都能使用的? 全局API 對應的局部選項,是在每個組件中,為當前組件添加的## 9. 子向父組件通信(vuebus)(擴展)* 父與子組件之間的通信可以通過? 實例.$on('自定義事件名稱', function(){})? 實例.$amit('事件名稱', '參數')? 使用$amit 能夠出發 $on 中自定義的事件? 使用一個中間的模塊,中間模塊 new 一個 Vue 對象,兩個組件分別引入這個 Vue 對象,調用這兩個方法,可以實現通信。************在 vue 中不會提及 DOM 元素的操作,只要涉及直接操作 DOM 元素,都應該用 vue 來實現## 10. 過濾器* vue 允許你自定義過濾器,可被用于一些常見的文本格式化。過濾器可以用在這兩個地方,mustachc插值{{}}和 v-bind 表達式。過濾器應該被添加在 js 表達式的尾部,有管道 符指示。? 例: {{ name | nameope }}* 定義一個過濾器? Vue.filter('過濾器名稱', function(data) {})? function 中第一個參數為管道符前面的值。? ```javascript? Vue.filter('msgFormat', function(msg) {? ? ? return msg.replace('aaa', 'bbb')? })? ```? ```javascript? Vue.filter('msgFormat', function(msg, arg1, arg2) {? ? ? return msg.replace('aaa', arg1+arg2)? })? ```? 也可以傳遞多個參數, {{ name | nameope(arg1, arg2) }}? 過濾器可以被多次調用? {{ name | nameope(arg1, arg2) } | test }* 過濾器調用規則? 先調用私有的過濾器,然后調用全局的過濾器(如果名稱相同)* es6 中的 自動填充 字符串方法? .padStart(2, '0')? 以 0 填充為長度為 2 的字符串? .padEnd(2, '0')## 11. 按鍵修飾符* vue 提供了觸發事件的按鍵修飾符,比如在能夠輸入鍵值的情況下? - `.enter`? - `.tab`? - `.delete` (捕獲“刪除”和“退格”鍵)? - `.esc`? - `.space`? - `.up`? - `.down`? - `.left`? - `.right`? 使用: @kendown.enter = 'fn'? 也可以 @keyup.13 = 'fn'? ,? 直接綁定按鍵的代碼。? 也可以通過全局對象來設置(只能全局啦),config 只能通過全局設置? ```javascript? Vue.config.keyCodes = {? ? v: 86,? ? f1: 112,? ? // camelCase 不可用? ? mediaPlayPause: 179,? ? // 取而代之的是 kebab-case 且用雙引號括起來? ? "media-play-pause": 179,? ? up: [38, 87]? }? ```## 12. 自定義指令* 全局定義? 使用 Vue.directive() 定義全局的指令? v-focus? 其中: 參數1:指令的名稱,注意,在定義的時候,指令的名稱前面,不需要加 v- 前綴,在調用的時候,必須在 指令名稱前 加上 v- 前綴來進行調用? 參數二: 是一個對象,這個對象身上,有一些指令相關的函數,這些函數可以在特定的階段,執行相關的操作? 常用到的鉤子函數:? ```javascript? Vue.directive('focus', {? ? bind: function(el) {? // 每當指令綁到這個元素上的時候,會立即執行這個 bind 函數,只執行一次? ? ? // 注意: 在每個函數中,第一個參數永遠是 el ,表示 被綁定了 指令的那個元素,這個 el 參數是一個 原生 的 js 對象,可以使用 js 原生 DOM 方法? ? ? // 在元素剛綁定了指定的時候,還沒有綁定到 DOM樹 中去,調用 focus 方法沒有作用? el.focus()? ? ? },? ? ? inserted: function(el) { // 當元素插入到 DOM 樹種的時候,會執行 inserted 函數[觸發一次]? ? ? el.focus()? },? ? ? updated: function (el) {? // 當VNnode 更新的時候,會執行 updated ,可能會觸發多次? ? ? ? ? ? ? ? }? })? ? ```? 頁面刷新獲取焦點,必須使用 inserted 來綁定自定義指令,只有綁定它之后,元素才會插入DOM 樹? 應用:? 直接添加屬性? v-focus? 后面不用加值。?修改樣式的自定義指令,可以使用 bind 來綁定方法。注意:1.? 一般行為的自定義指令,需要 js 操作DOM 需要使用 inserted 的方式自定義指令。不能再內存中操作。?需要在頁面中操作。要不然綁定不上方法。2. 樣式的操作會先加載完DOM 才會加載樣式,因此可以使用 bind 的形式來 自定義樣式,在內存中就會操作。? 樣式,只要通過指令綁定給了元素,不管這個元素有沒有被插入到頁面中去,這個元素肯定有一個內聯的樣式,將來元素肯定會渲染到頁面中去。* 鉤子函數的參數(看文檔,教程里面)? 自定義指令之后,指令需要執行的函數中的參數? 第一個參數為 el ,當前綁定的元素? 第二個參數為一個 對象 binding? 包含很多屬性:? ?常用的有 name (指令名稱)? ?value(計算之后的值)? ?expression(把指令中的表達式拿到,原封不動)? ?比如說一個 字符串 'blue',? v-color="'blue'"? ?value 拿到的值為 blue 類型為 字符串? ?expression 拿到的為 'blue'? 字符串中的字符串* 如果你可能只想在?`bind`?和?`update`?時觸發相同行為,可以簡寫,省去對象的書寫,直接寫函數? ```javascript? Vue.directive('color-swatch', function (el, binding) {? ? el.style.backgroundColor = binding.value? })? ```? 相當于把函數寫到 bind 和 update 中去了。注意: 唯一一個直接操作 DOM 的# Vue 生命周期* 生命周期: 從Vue 實例的創建、運行、到銷毀期間,總是伴隨著各種各樣的事件,這些事件,統稱為生命周期!(說白了就是各種事件)* 生命周期鉤子:就是生命周期事件的別名? 生命周期鉤子=生命周期函數=生命周期事件? ![lifecycle](./picture/lifecycle.png)1. var vm = new Vue({}) 2. init 表示初始化一個 Vue 空的實例對象,這時候這個對象身上,只有默認的一些生命周期函數和默認的事件,其他的東西都未被創建3. 在 beforeCreate 生命周期函數執行的時候,data 和 methods 中的 數據都還是沒有初始化? 在實例化對象中有一個 beforeCreate() 函數,在執行這個函數的時候,打印 data 或者是 methods 都顯示undefined,這個函數會自動的被調用4. 在 created() 方法中,data 和 methods 中的數據都已經加載好了,可以直接調用。? 如果要調用 methods 中的方法和操作data 中的數據,最早能在 created 方法中調用5. 是否存在 template 選項,編譯 template 模板? 判斷是否存在 el 選線的時候,表示 Vue 開始編譯模板,吧 Vue 代碼中的那些指令進行執行, 最終,在內存中生成一個編譯好的最終模板字符串,然后把這個模板字符串,渲染為 內存中的 DOM ,此時只是在內存中,渲染好了模板,并沒有把 模板掛在到真正的頁面當中去。 6. 第三個生命周期函數 beforeMount (在嵌入前),表示模板在內存中編輯完成了,但是尚未吧 模板 渲染到頁面中。? 執行 beforeMount ,打印頁面上元素的值,還無法打印出? 使用 document.getElementById()7. 第四個生命周期函數,mounted() 表示內存中的模板,已經真實的掛載到頁面中,用戶已經可以看到渲染好的頁面了。可以獲取到? mounted 是實例創建期間的最后一個生命周期函數,當執行完 mounted 就表示,實例已經被完全創建好了,此時,如果沒有其他的操作的話,這個實例就存放在內存中。? 如果要通過某些插件操作 DOM ,最好在 mounted 方法中進行。? 只要執行完了 mounted ,就表示整個 Vue 實例已經初始化完畢了,此時,組件已經脫離了創建階段;進入了運行階段8. 接下來的圈是組件運行階段的生命周期函數,只有兩個 beforeUpdate 和 updated 9. 當 data changes 時,beforeUpdate 會觸發,這倆事件,會根據 data 數據的改變,有選擇性的 觸發 0次 到 多次? 這時候表示我們的界面還沒有被更新,數據被更新啦。 MVVM 中 M 被更新啦,還沒有表現到 v 上面。? 當執行 beforeUpdate 的時候,頁面中的顯示的數據,還是舊的,此時 data 數據是最新的,頁面上的數據還沒有同步。編寫程序實現10. virtual DOM 虛擬的DOM? patch 打補丁? ? 這一步執行的是:先根據 data 中的最新的數據,在內存中,重新渲染出一份 最新的 內存 DOM 樹, 當最新的內存 DOM 樹被更新之后,會把最新的 內存DOM 樹,重新渲染到真實壓面中去,這時候,就完成了數據 從 data(Model)-> view(視圖層)的更新。? ? 生命周期函數 updated(),執行的時候頁面和data 數據已經保持同步更新了,都是最新的11. 當執行 beforeDestroy 鉤子函數的時候,Vue 實例就已經從 運行階段,進入到了銷毀階段,當執行 beforeDestroy() 函數的時候,實例身上多有的 data 和所有的 methods ,過濾器、指令等等,都處于可用狀態,此時還沒真正執行銷毀過程。12. 當執行 destroyed 函數的時候,組件已經被銷毀啦,此時組件所有的數據都不可用了。總結: 兩次使用到 鉤子函數的地方,自定義指令 和 生命周期鉤子函數。?鉤子函數只會執行一次!# 使用 vue-resource * 安裝 npm i vue-resource* import VueResource from 'vue-resource'* 安裝插件(所有帶 vue- 的第三方插件都可以這么用)? Vue.use(VueResource);? 能夠通過this.$http,插件都是掛載屬性,在原型上掛載? 原理: Vue.prototype.$http -> 實例(this)就可以 .$http* this.$http.get(url).then(data).catch(srr)? 基本使用* 請求方式 Request Method: OPTIONS? options 預檢請求,是當瀏覽器發現跨域+application/json 的請求,就會自動發起并且在發起的時候攜帶了一個 content-type 的頭(Request-Headers)? 因此需要設置 emulateJSON:boolean? content-type:application/x-www-form-urlencoded? ![WX20180828-140948](./picture/WX20180828-140948.png)# axios 基于Promise的http庫,適用于瀏覽器和node.js。* vue 不推薦操作 DOM ,不推薦使用 jQuery,因此發送ajax 請求需要第三方工具* axios 可以在三大框架中使用* 瀏覽器端發起XMLHttpRequests請求* node端發起http請求* 支持Promise API* 攔截請求和返回* 轉化請求和返回(數據)* 取消請求* 自動轉化json數據* 客戶端支持抵御[XSRF(跨站請求偽造)](http://baike.baidu.com/link?url=eFrTMGA9IsLxlOnyqKky-t6vTs3g6YoAfFc1sYmv2fVVS1FrfIoI3q3jxUV_o1AgIIoLdk9N0Ni_TxLItoRU3K)安裝:npm i axios引入:import Axios from 'axios'給 Vue 原型掛載一個屬性Vue.prototype.$axios = Axios;在 created 鉤子函數中調用this.$axios.get('url',{params: {ID: 12345}}, { headers: {'content-type': 'application/x-www-form-urlencoded’}}).then(data).catch(err)this.$axios.post('url', {key: 'value'}, {}).then().catch()post 請求的第三個參數為設置常用設置: headers: {?'content-type': 'application/x-www-form-urlencoded'?}form data 數據的格式應該為 key=value? 的形式如果不設置 headers 的話,請求數據的格式應該為 key=value 的形式(value 沒有自動的轉換)this.$axios.post('url', 'key=value', {}).then().catch() ,如果你寫這 json? 瀏覽器就會自動把請求頭設置成 json 的格式。請求的服務器數據不是同網頁的服務器,因此需要跨域,axios 已經實現了跨域。get 請求的設置在第二個參數,post 請求的設置在 第三個參數。配置: Axios.defaults.baseURL = 'http://127.0.0.1:8001/'? 可以配置默認的地址,get 和 post 請求中的地址會直接拼接在后面。(也可局部設置)局部設置:axios.defaults.baseURL = 'http://47.89.21.179:8080';設置完成直接寫后面需要補充的字符串。* 總結? 1. Post 請求的時候,如果數據是字符串,默認頭就是鍵值對,否則是對象就是 application/json? 2. this.$axios.get(url, options)? ? this.$axios.post(url, data, options)? ? 常用設置: options: {params:{id:1}, headers:{}}也可以 import Axios from 'axios'直接使用對象在局部使用* 手動發起的請求沒有表單格式,application/x-www-form-urlencoded,有的服務器處理不了* form data 表單數據# Vue 動畫![WX20180829-105402](./picture/WX20180829-105402.png)* Vue 動畫分為四個部分* 進入動畫(v-enter-active)? v-enter? v-enter-to* 離開動畫 (v-leave-active)? v-leave? v-leave-to* 時間段 加 一個 active* 四個時間點 和 兩個時間段使用:1. 使用 transition 元素,吧需要被動畫控制的元素,包裹起來.? transition 是 vue 官方提供的

? 2. 自定義兩組樣式,來控制 transition 內部元素實現動畫? ```html?

? .v-enter, .v-leave-to {


? /*設置出入時間點的樣式*/


? opacity:0;


? transform: translateX(80px)


? }


? .v-enter-active, .v-leave-active {


? transition: all 0.4 ease;


? // 設置 該時間段的過渡


? }


? ```? ? ? 不規定 .v-enter-to 的樣式,默認恢復默認樣式。? 如果一個元素想要實現上述的動畫,需要設置 v-if = 'flag',讓 transition 元素包括。會自動給它加這個類,由于元素的進出,需要 加 v-if 讓它實時進出,才能實現效果。定義私有的動畫:上述的動畫效果,只要被 transition 元素包括的都會執行一樣的效果。如果希望只執行自己的動畫效果,需要給 transition 元素的name 屬性定義一個私有的 標記,在樣式中直接使用私有的 標記-enter 的形式就可實現動畫的私有定制。例:```html .my-enter, .my-leave-to {

/*設置出入時間點的樣式*/

opacity:0;

transform: translateX(80px)

}

.my-enter-active, .my-leave-active {

transition: all 0.4 ease;

// 設置 該時間段的過渡

}```## 動畫使用第三方類實現`animate.css`?是一個集合酷的,有趣的和跨瀏覽器的動畫。引入 css 模塊直接在 transition 標簽元素上添加對應的類,vue動畫添加類采用 enter-active-class='' 和 leave-active-class='' 后面直接加類名例:```htmlh3 元素```注意:需要加基礎類,animated。或者加到動的元素身上也可以。```html

h3 元素

```* 定制一個顯性的過渡持續時間 (以毫秒計):? :duration='200'? 持續時間 200 毫秒* 分別定制過渡時間? :duration='{enter:200, leave: 300}'注意:enter-active-class 后面跟著的 js 變量## 使用鉤子函數實現動畫使用鉤子函數實現 動畫 可以只實現半程的動畫,不用實現全部過程的動畫。```html? ```如上:鉤子函數實現動畫的形式采用事件綁定的形式,因此綁定的事件需要在 methods 中實現。```javascriptbeforeEnter(el) {? ? // 動畫入場之前,此時,動畫尚未開始,可以在 beforeEnter 中,設置元素開始動畫之前的樣式? ? el.style.transform = 'translate(0, 0)'}enter(el) {? ? }```動畫鉤子函數的第一個參數el 表示要執行動畫的哪個元素,是個原生的 JS DOM 對象。在執行過程中的函數 enter 和 leave 函數中,第二個參數尾 done 表示 after-enter 的綁定函數,只要調用 done() 函數,在過渡完成或立即執行 afterEnter() 函數,不會存在等的問題。 注意: 在 enter() 函數中寫動畫的最終狀態,需要些 一行代碼 el.offsetWidth。這樣動畫才能正確執行到終點位置。```javascriptmethods: {? ? ? beforeEnter(el) {? ? ? ? ? el.style.transform = "translate(0, 0)"? ? ? ? ? el.style.opacity = 0? ? ? },? ? ? enter(el) {? ? ? ? //? el.offsetWidth? ? ? ? //? el.style.transform = "translate(100px, 800px)"? ? ? ? //? el.style.transition = "all 1s ease"? ? ? ? ? ? ? ? ? //? el.style.opacity = 1? ? ? ? //? done()? ? ? },? ? ? afterEnter(el) {? ? ? ? ? el.style.transform = "translate(100px, 800px)"? ? ? ? ? el.style.transition = "all 1s ease"? ? ? ? ? el.style.opacity = 1? ? ? ? ? this.flag = !this.flag? ? ? }? }```也可以在 afterEnter() 中實現動畫。## 給列表實現動畫 給 li 列表實現動畫效果,需要 使用 transition-group 取代 transition 來包裹加動畫的元素.列表的改變會影響位置的變化,如果需要給位置變化加動畫需要使用 .v-move 樣式類來實現(和 .v-enter 用法一樣)。如果加上 .v-leave-active{position: absolute} 可以使元素飄起來,實現效果。.v-move 要結合 .v-leave-active{position: absolute} 使用。注意: 所有的? .v- 的樣式,全部會加到 動畫的元素身上開始入場動畫:可以通過?`appear`?特性設置節點在初始渲染的過渡。* 注意:采用直接在 ul 下使用 transition-group 標簽包括的情況,容易出現ul 下面有一個 span 標簽的情況,最好采用 取消 ul 標簽,在 transition-group 標簽中加 tag="ul", 會自動的在最外層渲染為一個 ul 標簽,如果不指定,默認渲染為 span 標簽# 模塊化 和 組件化* 模塊化是代碼邏輯的角度來說的;方便分層開發,保證每一個功能模塊的職能單一。* 組件化:從 UI 界面的角度來進行劃分的,前端組件化,方便 UI 的重用組件創建的三種方式1. 使用 Vue.extend 來創建全局的 Vue 組件? ```javascript? var com1 = Vue.extend({? ? ? template: "

aaa

" // 通過 template 屬性,指定了組件要展示的 HTML 結構? })? ```? 使用 Vue.component('組件的名稱', '創建出來的模板對象')? Vue.component('myCom1', com1)? 注意: 使用組件的時候,要使用 - 連接 的形式,(不使用駝峰命名,直接使用)? ??style 樣式的書寫在 js 代碼中也要駝峰注意:組件的引用就是 使用組件標簽2. 第二種? Vue.component('myCom', {? ?template: "

111

"? })3. 第三種? Vue.component('myCom', {? ?template: "#temp1"? })? 將 template 寫到頁面上,直接使用 # id 選擇器引入,說明 Vue 接受對象,都可以接受 ID。自定義組件的命名最好為 "" 包括起來## 組件中的 data實例中的 data 為一個對象,組件中的data 必須為一個方法,并且返回一個對象。# 組件的切換* 在項目中點擊切換為登錄,切換為另一個 小界面v-if 和 v-else 的配合使用。它兩個必須使用同一個變量## Vue 提供的組件表達方式Vue 提供了 component 標簽來表示組件的使用,例: ```html```組件的名稱是一個字符串,在 component 中使用,需要加引號。可以使用 組件的名稱的切換,來達到頁面中 組件切換的效果。注意: 在html 標簽中寫 JS 代碼,所使用到的變量,必須在 data 中定義。動畫效果只能控制 v-if 消失和出現的動畫,使用 opacity 沒有作用# 組件之間的傳遞數據子組件中,不能直接 調用父組件中 data 上的數據和 methods 的方法。在開發過程中有時需要子組件獲取 父組件 的數據,展示出來。可以通過 v-bind:自定義屬性的 形式 給子組件傳值。例: 在父組件中,需要在 子組件中 定義一個 props 數組來接收,傳遞的數據。例: props: ['fathermsg']* 組件中的 所有 props 中的數據,都是通過父組件傳遞給子組件的。* 子組件的 data 數據是自身私有的。* data 中的數據都是可讀可寫的, props 中的數據都是可讀的傳遞方法:父組件給子組件傳遞方法,需要使用v-on: 來綁定,綁定事件后,在子組件的 可以使用 this.$emit('事件') 來實現事件的傳遞調用。需要執行 該語句 就需要使用一個函數來調用。this.$emit(function, arg1, args2...)利用傳參的特性,可以有父組件 給 子組件傳遞數據。使用 data 中的變量獲取。補充: 1. 組件上 綁定 v-model="msg" ,實際上相當于,v-bind:value="msg"2. 組件上還可以 @on 綁定事件,是為了傳遞方法(目前所知)## ref* ref 是 reference 的縮寫? Vue 提供了 ref 來實現對 DOM 元素的調用屬性? ```html

? ? ? 我是 div 中的元素


```? 在 js 部分就可以通過 this.$refs.mydiv.innerText 的形式來操作該節點。* ref 可以獲取組件,獲取組件之后也可以獲取組件內的變量和方法# 路由* 前端的路由:對于單頁面應用來說,主要通過 URL 中的hash (#號)來實現不同頁面之間的切換的,同事 hash 有一個特點;HTTP 請求中不會包含 hash 相關的內容,所以,單頁面程序中的頁面跳轉主要用 hash 實現。## vue-router* 安裝:? npm i vue-router? 使用:? import VueRouter from "vue-router"? Vue.use(VueRouter)* 當引入 vue-router 這個包之后,可以new 出一個路由對象,傳遞一個對象。注意: routes 不帶 r? ```javascript? var routerObj = new VueRouter({? ? ? // route? // 這個配置對象中的 route 表示 路由匹配規則 的意思? ? ? routes: [ // 路由匹配規則? ? ? ? ? // 每個路由規則,都是一個對象,這個規則對象,身上,有兩個必須的屬性? ? ? ? ? // 屬性1 是 path,表示監聽 哪個路由鏈接地址? ? ? ? ? // 屬性2 是 component,表示 如果路由是前面匹配的 path,則展示 component 屬性對應的那個組件,url 后面相當于一個hash? ? ? ? ? // 注意: component 必須為直接引入的組件名稱,不能為 父組件 注冊組件時起的名稱? ? ? ? ? { path: '/login', component: com1 },? // 不能加引號? ? ? ]? })? ? new Vue({? ? ? router: routerObj // 將匹配規則注冊 到 vue 實例上,用來監聽 URL 地址的變化,然后展示對應的組件? })? ```? ```html? // 需要在頁面上放顯示的容器? vue-router 提供了一個標簽元素 用來存放路由模塊 專門用來當做 占位符的,將來 路由規則匹配到的組件就會展示到這個 元素中去```? 切換模塊的時候,可以使用 a 標簽 中寫鏈接的形式實現,記住一定要加 # 要不然會出現地址的跳轉? ```html```? 因為每次都添加 # 所以不推薦使用上述的方式來實現路由,vue-router 還提供了一個 router-link 元素來實現路由,它實際渲染出來的還是一個 a? 標簽? ```html登錄```? 如果想讓它成為一個其他的標簽,則需要使用 tag="span" 的形式來實現。? 存在一個問題,剛進去頁面的時候,會出現在首頁 #/ 的頁面,需要默認出現在 登錄的頁面,可以使用 重定向。url 的地址和 頁面 都將變為重定向的地址。? ```js? {path: "/", redirect: "/login"}? ```? 當前頁面 按鈕 需要高亮的樣式修改,當前選中的按鈕 會有一個 router-link-active 類名,直接修改次 class? 也可實現。第二種方式,看文檔。還有定義動畫沒看????## 路由傳遞參數因為 該路由實在一個頁面上跳轉,因此不能夠使用HTTP 請求那樣的設置請求參數。* 如果在路由中 使用 查詢字符串 給路由 傳遞參數,則不需要修改路由規則的 path 屬性。? 直接在 path 中的地址后面使用 ? 拼接字符串? 使用 this.$route.query.id? 的形式就可以獲取到 queryString 請求值。? 注意:頁面上 js 區域,可以使用 所有在 this? 后面跟著的數據 都可以寫上去。? 例如: this.$route.query.id 可以使用 $route.query.id 在頁面上呈現。默認省略 this 。* 第二種傳遞參數的方法? 直接在 url 后面拼接要傳遞的數據。? 首先在 path 中設置,? {path: "/login/:id/:name", component: login}? 在 router-link 標簽中直接 to="/login/12/zs"? 在 this.$route.params. 中就能打印對應的 參數通過注入路由器,我們可以在任何組件內通過?`this.$router`?訪問路由器,也可以通過?`this.$route`訪問當前路由:注意: $route 表示的是當前目錄的路由。上述兩種傳遞參數的方式都可以,在開發中可以選擇## 子路由(路由的嵌套)在 VueRouter 實例中,能夠通過 children 屬性來設置子路由,通過子路由能夠訪問子組件。直接在父組件的路由設置中操作。```js{path: "/account", component: Acoount, children: [? ? {path: "login", component: Login},? ? {path: "register", component: Register}]}``` 注意:子路由的路徑不能加 '/',加上`/`會認為從根目錄開始 ```html

Account 組件

登錄注冊

```* 在子組件中嵌套,一定要記住,一定要有一個占位符來顯示要顯示的組件。## 一個路由放多個路由組件路由設置的時候,也能夠在路徑后面跟一個組件對象。在頁面上,使用 router-view 屬性的 name 來規定這個坑由誰來填。```jspath: "/", components: {? ? "default": header,? "left": leftBox,? ? "main": mainBox}// 使用```不寫的話,默認匹配 ”default“。次情況適合于頁面布局 的情況。# watch 監聽* Vue 實例對象中有一個屬性, watch 后面跟著一個屬性,可一監聽 data 中數據的變化,只要 data 中的數據發生變化,就會執行該監聽數據后面的函數。? ```js? data() {? ? ? msg: "aaa"? },? watch: {? ? ? msg: function(newVal, oldVal) {? ? ? ? ? this.fullname = newVal + oldVal? ? ? }? }? ```? 向 keyup 和 change 這種狀態變化事件,也需要注意與 watch 的對比* 監聽路由地址的變化? watch: $route.path? $route.path 返回當前的路由 /login,不加 ## computed * 在 computed 中,可以定義一些 屬性,這些屬性,叫做 【計算屬性】,計算屬性的本質,就是一個方法,只不過,我們在使用這些計算屬性的時候,是把 他們 的名稱直接當做屬性來使用的,并不會把計算屬性當做方法去調用```js"fullname": function(){? ? return this.firstname }```相當于在 data 中定義了一個 fullname 的變量,它的值 為后面的函數的處理結果。但是 data 中不需要再定義 fullname 變量了。注意:1. 計算屬性,在引用的時候,一定不要加 ()去調用,直接把它 當做 普通 屬性去使用就好了;?2.只要計算屬性 function 內部使用到的 data 中的數據,發生變化,就會觸發該函數去求值。實時的求值。?3.計算屬性的求值結果,會被緩存起來,方便下次直接調用;若計算屬性方法中使用到的 data 數據都沒發生過變化,則不會對計算屬性求值。(提升效率)為啥常用 "" 的形式 "fullname"* 上面兩種為 非 DOM 元素的改變時間綁定總結:1. 計算屬性 和 watch 都是一個后面加了一個 function2. watch 沒有 return 一個返回值3. methods中 是業務邏輯的處理* watch、computed、methods 之間的區別? 1. computed 屬性的結果會被緩存,除非依賴的響應式屬性變化才會重新計算,主要當做屬性來使用;? 2. methods 方法表示一個具體的操作,主要書寫業務邏輯? 3. watch 一個對象,鍵是需要觀察的表達式,值是對應回調函數。主要用來監聽某些特定數據的變化,從而進行某些具體的業務邏輯操作;可以看做是 computed 和 methods 的結合體。? 4. computed 中的數據相當于,先定義一個數據然后再監控它的計算值是否發生變化。watch 中的數據,直接就監聽的 該變量是否發生變化。

?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,401評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,011評論 3 413
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,263評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,543評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,323評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,874評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,968評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,095評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,605評論 1 331
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,551評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,720評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,242評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,961評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,358評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,612評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,330評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,690評論 2 370

推薦閱讀更多精彩內容

  • 十年磨一劍,三年茹盡苦。 投此一孤注,焉可不孤獨? 水流云依在,將至志窮處。 天天無可賴,時時意彳亍。 會有滿月弓...
    陳景行閱讀 627評論 0 0
  • 月色從黎明的露珠上跌落 摔成一片片霜花 落在故鄉的石碾上 猶如被軋碎的年華 邁出清晨混沌的門檻 尋找散落的石塊,竟...
    泰安左眼皮跳跳閱讀 229評論 0 9
  • 我是阿樹,謝謝你們陪我度過了這21天。 我已經很久沒有這么平靜過了,所以在寫這篇文章之前,我重新整理了一遍我的書架...
    是阿樹啊閱讀 649評論 0 2