整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          Vue真是太好了 壹萬多字的Vue知識點 超詳細!

          Vue真是太好了 壹萬多字的Vue知識點 超詳細!



          ??、Vue和其他兩大框架的區別

          • Angular 學習成本太高
          • React 代碼可讀性差
          • Vue 學習成本較低 很容易上手
            VUE官方: https://cn.vuejs.org/v2/guide/comparison.html

          ?2??、Vue是什么

          • Vue是一套用于構建用戶界面的漸進式框架 "前端框架"
          • 讓程序員脫離自己操作DOM 專注于寫邏輯和操作數據
          • Vue的核心庫只關注視圖層 易上手 便于與第三方庫或既有的項目整合
          • 當與現代化的工具鏈以及各種支持的庫結合使用時 Vue也完全能夠為復雜的單頁應用提供驅動

          ?3??、MVVM

          • M
            model 數據
          • V
            view 頁面
          • VM
            viewModel Vue實例
            DOM監聽(DOM Listeners)
            數據綁定(Date Bindings)

          ?4??、Vue指令

          ?4??.?1?? v-text

          說明: 文本數據渲染 用法: v-text="Vue實例中的數據"=> 簡寫 {{Vue實例中的數據}}

          相當于JavaScript中的innerText

          ?4??.?1??.?2?? v-text指令 和 {{ }}插值表達式 的區別

          • v-text 會直接替換元素中的所有內容
          • {{ }} 只會替換插值表達式中的占位符

          ?4??.?2?? v-html

          說明: HTML渲染數據 用法:v-html="Vue實例中的數據" 會解析html結構 渲染至頁面

          相當于JavaScript中的innerHTML

          ?4??.?2??.?1?? v-html指令 和 v-text指令的區別

          • v-html 會將數據解析成html 渲染至頁面
          • v-text 只會輸出成文本(字符串形式)

          注意: 在網站上動態渲染任意的 HTML 是非常危險的!!! 因為容易導致 XSS 攻擊 只在可信內容上使用 v-html 絕對不要用在用戶通過(提交)的內容上使用

          ?4??.?3?? v-on

          說明: 事件綁定(綁定事件監聽器) 用法: v-on:事件名="事件處理函數"=> 簡寫 @事件名="事件處理函數"

          ?4??.?3??.?1?? 詳細用法

          • @事件名.修飾符="事件處理函數"
          • 邏輯比較少的可以直接寫在行內
          • 邏輯較多的寫到 methods 中 注意: 操作Vue實例上的數據要跟上 this
          • 可以通過實參傳遞($event) 獲取事件參數e

          $event.target 獲取當前事件觸發的DOM元素 $event.path[0](el.path[0]) 也可以獲取當前事件觸發的DOM元素 path數組中有從觸發事件源的元素的所有上一級元素 直到window 實參不傳遞(沒有任何參數) 默認在形參中第一個就是事件參數
          實參傳遞 就必須傳遞$event 來獲取獲取事件參數

          ?4??.?3??.?2?? 事件修飾符

          • .stop
            阻止事件冒泡
          • .prevent
            阻止事件默認行為
          • .once
            只觸發一次回調
          • .native
            監聽組件根元素的原生事件
            很重要!有些第三方組件可能內部并沒有設置原生的事件 就可以通過.native來觸發事件

          面試問及

          之前在使用餓了么UI的時候給一個組件添加一個原生的事件 但是一直觸發不了 后面查閱文檔發現這個組件內部并沒有注冊我使用的原生事件 事件修飾符.native就可以直接監聽并觸發組件的原生事件

          • .capture
            添加事件偵聽器時使用 capture 模式
          • .{keyCode | keyAlias}
            只當事件是從特定鍵觸發時才觸發回調
          • .left
            (2.2.0版本) 只當點擊鼠標左鍵時才觸發
          • .right
            (2.2.0版本) 只當點擊鼠標右鍵時才觸發
          • .middle
            (2.2.0版本) 只當點擊鼠標中鍵時才觸發
          • .self
            只當事件使用偵聽器綁定的元素本身觸發時才觸發回調
          • .passive
            (2.3.0版本)以{ passive:true } 模式添加偵聽器

          ?4??.?4?? v-bind

          說明: 屬性綁定(行內屬性) 用法: v-bind:屬性名="Vue實例中的數據"=> 簡寫 :屬性名="Vue實例中的數據" 當Vue實例中的數據改變之后 頁面會同步更新

          ?4??.?4??.1?? 屬性綁定修飾符

          • .prop
            被用于綁定 DOM 屬性 (property)
          • .camel
            (2.1.0+) 將 kebab-case 特性名轉換為 camelCase. (從 2.1.0 開始支持)
          • .sync
            (2.3.0+) 語法糖,會擴展成一個更新父組件綁定值的 v-on 偵聽器

          ?4??.?4??.2?? 對象的方式綁定class

          • :class="{'red' : isRed}"

          isRed=true 就有red這個類 isRed=false 就沒有red這個類 isRed 在 Vue 實例data中聲明

          • 默認的class 和 :class(綁定的class) 一起使用不會沖突 后面的會作為追加或者移除來解析

          class="red" :class="{'yellow' : isYellow}"

          ?4??.?4??.3?? 對象的方式綁定style

          • :style="{fontSize : mySize + 'px'}"
          • 樣式名需要使用駝峰命名法
          • 后面的mySize需要在Vue實例data中定義

          ?4??.?5?? v-model

          說明: 雙向數據綁定 用法: v-model="Vue實例中的數據"

          ?4??.?5??.?1?? 雙向

          • 視圖層
          • 數據層
            數據能夠自動的從內存中顯示到頁面上去

          ?4??.?5??.?2?? 雙向綁定修飾符

          • .lazy
            懶載入 當表單屬性失去光標或按下回車鍵后 再將頁面中的數據和Vue實例中的數據雙向綁定
          • .trim
            輸入的數據首位空格過濾
          • .number
            輸入字符串轉為有效的數字

          注意: v-model 只能設置給from表單屬性

          ?4??.?6?? v-for

          說明: 循環渲染 用法: v-for="(item,index) in items" :key="index"

          items是源數據數組 item是被迭代的數組元素的別名 index是被迭代的數組元素的下標(索引)

          ?4??.?6??.?1?? :key

          • 數據唯一標識綁定
          • v-for默認行為試著不改變整體 而是替換元素 迫使其重新排序的元素需要提供一個key(用戶刪除數據后 數據需重新排列序號 就可以使用key來實現)
          • 數據實現重用和重新排序現有的元素
          • 值最好為字符串或數值類型(唯一的)

          ?4??.?6??.?2?? 遍歷數組注意點

          • Vue本身只是監視了Vue實例Data中數組的改變(監視內存地址) 沒有監視數組內部數據的改變
          • (變異方法)Vue重寫了數組中的一系列改變數組內部數據的方法(先調用原生的方法 再更新頁面) 所以實現了使用數組提供的方法 數組內部改變 界面自動改變

          push() pop() shift() unshift() splice() sort() reverse() ...

          • this.arr[index]=新值

          這種修改數組中的元素是無法實現數據改變后頁面會同步改變(只會修改data中的數據 但是頁面不會同步改變)

          • splice()的增刪改
            增 this.arr.splice(index,0,新值)
            刪 this.arr.splice(index,1)
            改 this.arr.splice(index,1,新值)

          ?4??.?7?? v-if,v-else,v-else-if

          說明: 條件(表達式或布爾值)判斷渲染 用法: v-if="表達式或布爾值" v-else-if="表達式或布爾值" v-else

          ?4??.?7??.?1?? 注意

          v-if 和 v-else-if 后面必須跟表達式或布爾值 v-else-if 和 v-else 不能獨立使用 必須跟在 v-if 后面

          ?4??.?8?? v-show

          說明: 條件渲染 用法: v-show="表達式或布爾值" 根據表達式或布爾值的真假切換元素的display屬性

          ?4??.?8??.?1?? 注意

          v-show 不支持 <template>元素 也不支持 v-else

          ?4??.?9?? v-if vs v-show

          都是用來判斷渲染數據的

          • v-if

          1.有較高的切換性能消耗 2.惰性渲染 第一次如果條件為false 則不會渲染到頁面 需要等后面條件切換后才會進行第一次渲染 3.條件切換是切換DOM數中這個元素的移除或添加 4.如果運行時條件很少改變則使用v-if

          • v-show

          1.有較高的初始渲染消耗 2.初始渲染 不管條件 第一次加載頁面的時候都會渲染到頁面 3.條件切換只是切換元素的display屬性 4.如果運行時條件會非常頻繁的切換則使用v-show

          ?4??.??1??0?? v-cloak

          說明: 這個指令保存在這個元素上 直到關聯實例結束編譯

          ?4??.??1??0??.?1?? 詳細說明

          插值表達式在網絡較滿的情況下可能會出現數據閃爍問題 可以通過給實例(#app)盒子添加一個 v-cloak 指令 通過這個指令的特性(如頁面中還有插值表達式就會存在這個指令 如果頁面的插值表達式都被替換成數據 就會自動移除這個標簽) 配合css [v-cloak]{display:none|opacity:0}來解決數據閃爍的問題

          ?4??.??1??1?? v-once

          說明: 這個指令添加的元素 內部的胡子語法只會在第一次渲染的時候執行解析一次 后面數據發生改變后也不會觸發更新

          ?4??.??1??1??.?1?? 用途

          某些元素只需要解析一次 后續不需要更新 就可以使用這個指令 提升性能


          ?5??、Vue實例

          ?5??.?1?? el

          • 與頁面中的元素綁定
          • 指定根element(選擇器)
          • 可以寫id、class、標簽選擇器
            建議使用id 因為id是唯一的 一個Vue實例綁定一個頁面元素
          • 注意: 不支持綁定body和html

          ?5??.?2?? data

          • 數據對象
          • 初始化數據(頁面可以訪問)
          • 可以在里面寫對象、字符串、數值、數組、...

          ?5??.?3?? methods

          • 方法對象
          • 可以在里面聲明一些方法
            可以通過this.xxx 獲取Vue實例上的數據或方法
          • 注意: 不要使用箭頭函數 會改變this指向

          ?5??.?4?? computed

          • 計算屬性
          • 可以在里面聲明一些函數
            必須要有 return 值
          • 計算屬性函數中如果使用到了data中的數據 這些數據發生改變后 就會重新執行這個計算屬性函數 將最新的計算結果返回出去
            執行時機:初始化顯示執行和函數中用到了data中的數據變化后會執行
          • 在頁面中直接用插值表達式使用計算屬性{{計算屬性函數名}} 計算屬性本質就是一個方法 但是使用的時候是將這些方法的方法名當作屬性使用 計算屬性的值就是return出來的值
          • getter 和 setter

          1.使用get和set函數 需要把計算屬性函數改成計算屬性對象 2.計算屬性默認執行get方法(根據相關的數據計算返回當前屬性的值) 3.當計算數學值自身改變后執行set方法 4.可以用來計算稅前和稅后的互推算

          • 計算屬性存在緩存 多次讀取只執行一次getter函數
            緩存=> {計算屬性名:"數據結果"} 鍵值對

          ?5??.?5?? watch

          • 偵聽屬性
          • 可以偵聽data中的屬性和一些非DOM元素的改變
          • 可以獲取數據改變前的值和改變后的值
            形參(newVal,oldVal)=> (改變后的值,改變前的值)
          • 深度偵聽
            watch默認無法偵聽復雜數據類型 需要偵聽復雜數據類型 得使用深度偵聽
          watch:{
              XXX:{   
                  deep:true,
                  handler(newVal,oldVal){
                      // 處理代碼
                  }
              }
          }
          
          • 偵聽路由 hash
          watch: {
            // watch里面的 $router 這些對象前面不要帶this
            "$route.path"(newVal, oldVal) {
              if (newVal.indexOf("/login") >=0) {
                this.welcom="歡迎登陸";
              }
              if (newVal.indexOf("/register") >=0) {
                this.welcom="歡迎注冊";
              }
            }
          }
          
          • 子組件偵聽路由的變化
            watch: {
              $route: function(newVal,oldVal) {
                console.log(this.$route.path);
              }
            }
          
          • 面試問及:
            使用或偵聽器嗎 在Vue中碰到過什么bug

          1.偵聽器用來檢測數據的改變 2.當偵聽的那個數據發生改變后就會觸發偵聽器中的對應函數 3.一般我更多的使用是用偵聽路由的變化=> 重新獲取數據(如搜索在對應的router-view中顯示對應的數據) 4.之前碰到過一個坑點 偵聽器默認無法偵聽復雜數據類型 5.后面使用深度偵聽 depp:true 來解決了這個問題 6.或者偵聽精確到對象中的那個值也可

          ?5??.?6?? computed和watch的區別

          • watch里面的方法只能對那個方法名的屬性名做偵聽
          • computed里面可以對那個方法中所有使用到了的data中的屬性名做偵聽
          • watch里面無須return
          • computed需要return

          ?5??.?7?? components

          • 私有組件
          • 后面會有全局組件 更詳細

          ?5??.?8?? filters

          • 過濾器
            聲明全局過濾器 一定要在實例化Vue之前聲明
          • 全局過濾器
          Vue.filter("formatData", (形參=管道符前面的數據,形參=想要傳入的數據...)=> {
              處理數據; `返回`處理之后的數據
          });
          
          • 局部過濾器
          filters:{ 
              formatTime(形參=管道符前面的數據,形參=想要傳入的數據...){
                  處理數據; `返回`處理之后的數據  }
           }
          
          • 在頁面中使用
            {{data | formatTime | formatTime1 | ...}}
          • 一個過濾器是一個函數 需要接收一個參數 參數就是處理的數據 (可以不傳 默認是 管道符前面的數據) 可以做一些邏輯處理后 再將處理好的數據返回出去
          • 不修改數據的情況下 修改數據的顯示效果 過濾器不會修改源數據

          ?6??、Vue實例中的this

          • this就是當前實例化出來的Vue對象(Vue實例)
          • Vue構造函數內部解析時 會把data、methods等中的值直接設置給這個實例化出來的Vue實例對象
          • 最終直接通過這個Vue實例對象即可訪問data中的數據以及methods中的方法等

          ?7??、Vue實例屬性

          ?7??.?1?? vm.$data

          獲取data中的所有數據

          ?7??.?2?? vm.$options

          用于當前Vue實例的初始化選項 可以獲取自定義選項

          new Vue({
            customOption: 'foo',
            created: function () {
              console.log(this.$options.customOption) //=> 'foo'
            }
          })
          

          ?7??.?3?? vm.$refs

          • 通過給元素設定ref屬性在Vue實例中獲取這個元素
          • 頁面元素 ref="jack"
          • Vue實例獲取 this.$refs.jack
            返回的是一個DOM對象
          • 如果ref重名后面的會把前面的覆蓋

          ?8??、Vue組件

          ?8??.?1?? 什么是組件

          組件的出現就是為了拆分Vue實例的代碼量 能夠讓我們以不同的組件來劃分不同的功能模塊 需要什么功能就去調用對應的模塊即可 局部功能界面

          ?8??.?2?? 組件化和模塊化的區別

          • 模塊化
            是從代碼的邏輯角度去劃分的 方便代碼分層開發 保證每個功能模塊的職能單一
          • 組件化
            是從UI界面的角度進行劃分的 前端的組件化方便UI組件的重用

          ?8??.?3?? 全局組件

          ?8??.?3??.?1?? 用法

          Vue.component('組件名',{參數})

          ?8??.?3??.?2?? 注意

          組件名請使用小寫 大寫需要駝峰命名法

          Vue.component('sayHiBaby',{參數})
          頁面中標簽使用 <say-hi-baby></say-hi-baby>
          

          ?8??.?3??.?3?? 組件參數

          • props:['xxx']

          父向子傳參 通過 props 向子組件傳遞數據 可以在組件實例中通過 this.xxx 拿到傳遞過來的值 高級寫法(props驗證)

          props:{
            xxx:{
              // 數據類型
              type:"String",
              // 必須傳遞
              required:"true",
              // 默認值
              default:"mystring"
              ....
            }
          }
          

          props可以傳遞任何數據類型 包括函數

          • data(){ return{ } }
            組件中的數據data是一個函數 將數據寫在返回出去的對象中即可

          為什么組件的data是一個函數 而Vue實例的data是一個對象?

          1.每一個Vue組件都是一個Vue實例 2.都是通過new Vue() 創建出來的 3.如果data是一個對象的話 那么這些組件的引用指向就會相同 4.一個的值修改后 其他的值也會修改(這是JavaScript語法的特性) 5.如果data是一個函數 函數中再返回一個對象 6.那么每個Vue組件都有了自己的作用域 互不干擾

          • template
            模版
            動態的HTML頁面 包括一些JavaScript語法代碼
            注意: 如果模版中包含多個標簽 需要在最外層加一個div 作為根標簽
          • 其他參數和Vue實例的一致

          ?9??、Vue生命周期鉤子

          Vue生命周期鉤子 || Vue生命周期函數 Vue提供給開發者一系列的回調函數 讓我們可以在Vue的各個階段添加自定義的邏輯處理

          ?9??.?1?? 三大階段

          ?9??.?1??.?1?? 初始化顯示

          創建期間的生命周期函數(1次)

          • beforeCreate()
            Vue實例被創建 但date和methods數據中的數據還沒有被設置上去(未初始化)
          • created()
            data和methods以及被初始化(已被設置在Vue實例上)但是還未開始模版編譯
            常用 如果要操作data中的數據和methods中的方法 最早只能在created中調用
          • beforeMount()
            開始解析模版編譯 把數據和結構(模版)關聯起來 但現在頁面上還不能看到數據
          • mounted()
            數據掛載完畢 頁面中可以看到數據 當這個鉤子函數執行完畢 創建期間的所有的生命鉤子全部執行完
            常用 發送ajax請求 啟動定時器等異步任務 操作DOM中的節點

          Vue渲染解析插值表達式 并不是在頁面中直接渲染解析 而是將整個掛載在Vue實例的模版 拿到內存中去解析 等全部解析完成后 再一次性的渲染到頁面(批量) (因為有可能頁面中有很多一樣的data中的值 如果是在頁面中直接渲染解析會很耗性能)

          ?9??.?1??.?2?? 更新顯示

          運行期間的生命周期函數(0次-多次)

          • beforeUpdate()
            頁面中的數據還是舊的 但Vue實例中的數據已經被更新 數據還未同步
          • updated()
            頁面和Vue實例中的數據已同步

          ?9??.?1??.?3?? 銷毀

          銷毀期間的生命周期函數(1次)

          • beforeDestory()
            開始進入銷毀階段 Vue實例中的方法和數據還能使用 還未真正銷毀
            常用 做收尾工作 如:清除定時器...
          • destoryed()
            已被完全銷毀 Vue實例中的數據和方法不能再使用

          想要銷毀Vue實例 調用 vm.$destroy() 即可 注意: 這個方法方法并不會銷毀Vue實例的一些如 定時器或計時器等方法 會造成 '內存泄漏' 所以在完全銷毀之前 需要在 beforeDestory 鉤子中清除定時器等...


          ??1??0??、父子組件傳參

          ??1??0??.?1?? 父傳子

          • 子組件中定義 props 屬性 props:['num','max','min']
          • 父組件中使用子組件時 <comSon num='xxx' max='xx' :min='x'></comSon>

          ??1??0??.?2?? 子傳父

          • 子組件中 特定的時候 觸發 this.$emit('事件名A','參數')
          • 父組件中 <com @事件名A="自己methods中的方法"></com>

          ??1??1??、VueRouter

          ??1??1??.?1?? 前端路由

          url地址和組件之間的關系

          ??1??1??.?2?? 如果是模塊工程化(VueCLI)中使用VueRouter

          必須添加 Vue.use(VueRouter)

          import Vue from 'vue'
          import VueRouter from 'vue-router'
          Vue.use(VueRouter)
          

          ??1??1??.?3?? 路由起步代碼

          ??1??1??.?3??.?1?? HTML

          • router-link
            使用 router-link 來導航 最后會被渲染成a標簽
            可以通過 tag屬性 來設置最后被渲染的標簽
            to屬性 指定跳轉的鏈接
          <router-link to="/login" tag="span">登陸</router-link>
          <router-link to="/logout" tag="span">注冊</router-link>
          
          • router-view
            router-view 路由出口 路由匹配到的組件將渲染到這里
          <router-view></router-view>
          

          ??1??1??.?3??.?2?? JavaScript

          • 定義組件
          const login={ template: "#tempLogin" };
          const logout={ template: "#tempLogout" };
          
          • 定義路由
          const routes=[
            { path: "/login", component: login },
            { path: "/logout", component: logout }
          ];
          
          • 創建路由
          const router=new VueRouter({
            routes
          });
          
          • 綁定路由
            在Vue實例中 綁定router
          new Vue({
            el:"xxx",
            router
          })
          

          ??1??1??.?4?? 路由高亮

          設置路由匹配成功后 router-link 的樣式屬性

          • active-class 模糊匹配
            to設置的路由和url上面的路由只要前面的/xxx 匹配成功就會添加樣式
          /login=> /login/user
          觸發 添加樣式
          
          • exact-active-class 全部匹配
            to設置的路由和url上的路由必須全部匹配才會添加樣式
          /login/user=> /login/user
          觸發 添加樣式
          

          ??1??1??.?5?? 聲明式導航

          點了跳轉 沒有任何邏輯 類似于(a標簽設置了href) <router-link to="地址">XXX</router-link>

          ??1??1??.?6?? 編程式導航

          跳轉的同時執行其他需要執行的邏輯 router.push('地址')

          ??1??1??.?7?? 動態路由匹配

          • 將原本 router-link to 中的地址 /user=> /user/:id
            :id 只是一個占位
          • 切換路由 /user=> /user/123
          • 可以在組件中通過 this.$route.params.(id) 獲取傳遞過來的數據

          ??1??1??.?8?? 路由重定向

          • redirect : "跳轉的新地址"
          • {path:"地址1",redirect:"跳轉到的新地址2"}
          • 能夠實現 匹配到地址1之后 立刻跳轉到地址2

          ??1??1??.?9?? 前置導航守衛

          • 導航<路由> 當路由發生改變后 就會觸發導航守衛再進行路由跳轉
          const router=new VueRouter({ ... })
          router.beforeEach((to, from, next)=> {
            // ...
            next()
          })
          

          to

          去哪個路由 一般通過to來判斷對應路由做對應處理

          from

          來自哪個路由

          next()

          必須next()才可以繼續跳轉頁面(像node"express"里面的中間件)

          • 執行時機 比組件的beforeCreate還要早

          1.判斷登陸狀態 如判斷token... 2.可以在跳轉路由時先判斷這個頁面這個用戶是否有權限訪問... 3.可以每次路由跳轉前都提示用戶跳轉至什么頁面...

          ??1??1??.??1??0?? 路由元信息

          • 給路由配置一個標示 配合導航守衛定位到這個路由 做一些對這個路由的邏輯處理
          • 給路由規則中配置一個meta對象
            meta: { requiresAuth: true }
          • 在導航守衛中就可以通過 to.meta.requiresAuth 是否為true 來判斷是否是對應路由

          ??1??1??.??1??1?? 嵌套路由

          • 在需要使用嵌套路由的組件中 找到需要動態替換的位置
            <router-view></router-view>
          • 修改路由規則
            在需要嵌套路由的組件的路由規則中添加 children:[ ]
            注意 嵌套路由的path不要加 /
          { path: '/user', component: User,
            children: [
              {
                path: 'index',
                component: Index
              }
            ]
          }
          

          ??1??1??.?1??2?? 統一404頁面

          配置錯誤路由規則

          • 錯誤路由
            {path:"/NotFound",component:NotFound}
          • 配置404
            {path:"*",redirect:'.NotFound'}
            注意 :這個匹配必須寫在路由規則的最下面 (當上面的路由匹配規則都不成功就會執行這個路由 然后跳轉到404錯誤頁面)

          ??1??1??.?1??3?? 路由懶加載

          • 當打包構建應用是 JavaScript 包會變得非常大 影響頁面加載 路由懶加載 把不同路由對應的組件分割成不同的代碼塊 當路由被訪問的時候才加載對應組件
          • 將原先 在router.js 中的 import Foo from "./Foo.vue"; 修改成 const Foo=()=> import('./Foo.vue') 其他不變 即可
          • 路由懶加載并不能提速 只是把時間分開了 總時間沒變

          ??1??2??、資源請求

          ??1??2??.?1?? Axios

          ??1??2??.?1??.?1?? Axios是什么?

          Axios是一個基于 promise(實現了鏈式調用) 的 HTTP 庫 可以用在瀏覽器和 Node.js 中 專注于發請求 專注于網絡請求的一個庫`

          ??1??2??.?1??.?2?? CDN

          <script src="https://unpkg.com/axios/dist/axios.min.js"></script>

          ??1??2??.?1??.?3?? .then

          成功回調

          ??1??2??.?1??.?4?? .catch

          失敗回調

          ??1??2??.?1??.?5?? get請求

          // 為給定 ID 的 user 創建請求
          axios.get('/user?ID=12345')
            .then(function (response) {
              console.log(response);
            })
            .catch(function (error) {
              console.log(error);
            });
          
          // 可選地,上面的請求可以這樣做
          axios.get('/user', {
              params: {
                ID: 12345
              }
            })
            .then(function (response) {
              console.log(response);
            })
            .catch(function (error) {
              console.log(error);
            });
          

          ??1??2??.?1??.?6?? post請求

          axios.post('/user', {
              firstName: 'Fred',
              lastName: 'Flintstone'
            })
            .then(function (response) {
              console.log(response);
            })
            .catch(function (error) {
              console.log(error);
            });
          

          ??1??2??.?1??.?7?? 基地址

          基礎的地址應用 沒有必要每次都寫 可以直接抽離出來

          axios.defaults.baseURL='設置的基地址'
          Vue.prototype.$axios=axios
          

          axios填寫路徑時后面直接寫對應的路徑即可 前面的公共部分不需在寫(寫了也不會影響)

          ??1??2??.?1??.?8?? 設置跨域攜帶cookie

          axios.defaults.withCredentials=true

          ??1??2??.?1??.?8??.?1?? 面試問及

          • 坑點 axios 跨域默認不攜帶cookie
          • 某個項目 登陸狀態的判斷 后端用的是cookie
          • 登陸成功之后 服務器返回了cookie 標記登陸
          • 但axios在請求不同源的接口時 默認不會攜帶cookie
          • 所以后端接口后續一直無法獲取登陸狀態
          • 抓包后檢測網絡請求 發現瀏覽器并沒有把服務器返回的cookie給保留
          • 所以導致每次都沒設置成功cookie (set-cookie)
          • 設置 axios.defaults.withCredentials=true
          • 允許跨域攜帶cookie 這樣瀏覽器就能在跨域的時候存下cookie
          • 瀏覽器中無法直接查看跨域的cookie 瀏覽器隱藏了 可以通過抓包查看

          ??1??2??.?1??.?9?? 創建克隆對象 多基地址設置

          const xxx=axios.create({
            // 即地址
            baseURL: 'https://some-domain.com/api/',
            // 可以統一設置請求頭
            headers: {Authorization: token}
          });
          xxx.get()
          xxx.post()
          
          • 只需要使用axios的create創建多個副本 每個副本設置一個不同的基地址
          • 請求某個基地址的時候 使用該副本的對應方法即可

          ??1??2??.?1??.?1??0?? Axios攔截器

          ??1??2??.?1??.?1??0??.?1?? 請求攔截器

          axios.interceptors.request.use(function (config) {
              // 可以在發請求之前在這里設置一些請求頭
              `config.headers.Authorization=token`
              return config;
            }, function (error) {
              // Do something with request error
              return Promise.reject(error);
            });
          

          ??1??2??.?1??.?1??0??.?2?? 響應攔截器

          axios.interceptors.response.use(function (response) {
             // 可以在獲取響應數據之后設置一些提示 如獲取失敗/成功
             `response.data.code==200?`
              return response;
            }, function (error) {
              // Do something with response error
              return Promise.reject(error);
            });
          
          • 可以在響應攔截器中判斷token是否造假
          • 是造假則可以直接清除本地的token...

          ??1??2??.?2?? vue-resource

          vue-resource已經不再更新 推薦使用Axios


          ??1??3??、Vue動畫鉤子

          ??1??3??.?1?? Vue動畫鉤子是什么?

          Vue提供的讓程序員可以在動畫的各個時機 添加 自定義邏輯 的鉤子 也可稱之為 動畫鉤子或動畫函數

          ??1??3??.?2?? Vue動畫的理解

          • 操作 css 和 trasition 或 animation
          • Vue 會給目標元素添加/移除特定的 class
          • 過渡的相關類名
          // 指定顯示的transition
          xxx-enter-active
          // 指定隱藏的transition
          xxx-leave-active
          // 指定隱藏時的樣式
          xxx-enter/xxx-leave-to
          

          ??1??3??.?3?? 單個元素動畫

          transition標簽包裹

          ??1??3??.?4?? 列表過渡動畫

          transition-group標簽包裹

          ??1??3??.?5?? name

          動畫樣式的開始類名

          ??1??3??.?6?? tag

          解析為的標簽名

          ??1??3??.?7?? 過渡類名參數

          • v-enter:
            定義進入過渡的開始狀態。在元素被插入之前生效,在元素被插入之后的下一幀移除。
          • v-enter-active
            定義進入過渡生效時的狀態。在整個進入過渡的階段中應用,在元素被插入之前生效,在過渡/動畫完成之后移除。這個類可以被用來定義進入過渡的過程時間,延遲和曲線函數。
          • v-enter-to
            2.1.8版及以上 定義進入過渡的結束狀態。在元素被插入之后下一幀生效 (與此同時 v-enter 被移除),在過渡/動畫完成之后移除。
          • v-leave
            定義離開過渡的開始狀態。在離開過渡被觸發時立刻生效,下一幀被移除。
          • v-leave-active
            定義離開過渡生效時的狀態。在整個離開過渡的階段中應用,在離開過渡被觸發時立刻生效,在過渡/動畫完成之后移除。這個類可以被用來定義離開過渡的過程時間,延遲和曲線函數。
          • v-leave-to
            2.1.8版及以上 定義離開過渡的結束狀態。在離開過渡被觸發之后下一幀生效 (與此同時 v-leave 被刪除),在過渡/動畫完成之后移除。

          ??1??3??.?8?? 動畫時機

          • 條件渲染 (使用 v-if)
          • 條件展示 (使用 v-show)
          • 動態組件
          • 組件根節點
          • 動態的增刪元素 就會觸發進入動畫 以及移除動畫

          ??1??3??.?9?? 動畫鉤子代碼

          ??1??3??.?9??.?1?? HTML

          <transition
            v-on:before-enter="beforeEnter"
            v-on:enter="enter"
            v-on:after-enter="afterEnter"
            v-on:enter-cancelled="enterCancelled"
          
            v-on:before-leave="beforeLeave"
            v-on:leave="leave"
            v-on:after-leave="afterLeave"
            v-on:leave-cancelled="leaveCancelled"
          >
            <!-- ... -->
          </transition>
          

          ??1??3??.?9??.?2?? JavaScript

          // ...
          methods: {
            // --------
            // 進入中
            // --------
          
            beforeEnter: function (el) {
              // ...
            },
            // 當與 CSS 結合使用時
            // 回調函數 done 是可選的
            enter: function (el, done) {
              // ...
              done()
            },
            afterEnter: function (el) {
              // ...
            },
            enterCancelled: function (el) {
              // ...
            },
          
            // --------
            // 離開時
            // --------
          
            beforeLeave: function (el) {
              // ...
            },
            // 當與 CSS 結合使用時
            // 回調函數 done 是可選的
            leave: function (el, done) {
              // ...
              done()
            },
            afterLeave: function (el) {
              // ...
            },
            // leaveCancelled 只用于 v-show 中
            leaveCancelled: function (el) {
              // ...
            }
          }
          

          ??1??3??.??1??0?? 過渡動畫生命周期



          ??1??4??、VueX

          ??1??4??.1?? Vuex是什么?

          • 集中管理所有組件的數據
          • 可以把它理解為是一個倉庫
          • 將組件中公有的數據都抽到VueX中
          • VueX中的數據 所有的組件都可以獲取 所有的組件都可以修改

          ??1??4??.2?? 起步

          ??1??4??.2??.1?? 下載

          npm install vuex --save

          ??1??4??.2??.2?? 創建VueX倉庫

          import Vue from 'vue'
          import Vuex from 'vuex'
          
          Vue.use(Vuex)
          
          const store=new Vuex.Store({
            state: {
            // 數據
              count: 0
            },
            mutations: {
              // 方法
              increment (state) {
                state.count++
              }
            }
          })
          
          new Vue({
              el:xxx,
              // 掛載到Vue實例上
              store
          })
          

          ??1??4??.2??.3?? 在組件中獲取VueX的數據

          • HTML
            {{$store.state.count}}
          • JavaScript
            this.$store.state.count

          ??1??4??.2??.4?? 在組件中修改VueX的數據

          • VueX修改數據必須通過 mutations 中的方法修改數據
            this.$store.commit(''mutations中的方法,'參數')

          ??1??4??.3?? VueX - state

          • 數據
          • 所有組件的都可以使用 獲取數據

          ??1??4??.4?? VueX - mutation

          • 方法 修改state中的數據

          ??1??5??、VueCLI

          ??1??5??.1?? 單文件組件

          ??1??5??.1??.1?? 用一個文件能夠包含組件的所有內容

          • 結構
          <template>
          </template>
          
          • 邏輯
          <script>
          export default {
          }
          </script>
          
          • 樣式
          <style>
          </style>
          

          ??1??5??.1??.2?? 單文件開發的好處

          • 更利于編碼
          • 利于后期維護
          • 一個文件包含了所有內容

          ??1??5??.2?? 什么是Vue-CLI

          • 腳手架
          • 可以把.vue文件翻譯成瀏覽器可以識別的內容
          • 自動刷新瀏覽器
          • 自動壓縮代碼
          • 自動的把高版本的JavaScript翻譯成低版本的JavaScript
          • 作為代理服務器
          • ...

          把很多開發中需要用到的功能整合到了一起 讓Vue開發人員專注于邏輯代碼即可 是用webpack配置出來的

          ??1??5??.3?? 搭建一個腳手架

          vue create 項目名 <=項目名不要有中文!!!不要大些 cd 項目名 npm run serve

          ??1??5??.4?? Vue-CLI搭建項目的本質

          • 創建文件夾
          • 下載第三方模塊
          • 創建項目的基本結構
          • 設置各個文件之間的關系
          • 創建git倉庫

          1??5??.5?? Vue-cli項目結構

          • main.js
            主要的文件 所有和頂級Vue實例相關的都放到這里
          • App.vue
            最頂級的組件 僅次于Vue實例 看到的頂級頁面結構一般都放在這里
          • /components
            組件的文件夾
          • /assets
            靜態資源

          1??5??.6?? 搭建webpack-vue腳手架(詳細版本)

          npm init webpack "項目名" cd "項目名" npm instal npm run dev

          最后一步選 No, I will handle that myself 自己再npm i 下載速度會快一點


          1??5??.7?? webpack-vue項目結構

          |-- build : webpack 相關的配置文件夾(基本不需要修改) 
                  |-- dev-server.js : 通過 express 啟動后臺服務器
          |-- config: webpack 相關的配置文件夾(基本不需要修改)
                  |-- index.js: 指定的后臺服務的端口號和靜態資源文件夾
          |-- node_modules 
          |-- src : 源碼文件夾
                  |-- components: vue 組件及其相關資源文件夾 
                  |-- App.vue: 應用根主組件
                  |-- main.js: 應用入口 js
          |-- static: 靜態資源文件夾
          |-- .babelrc: babel 的配置文件
          |-- .eslintignore: eslint 檢查忽略的配置
          |-- .eslintrc.js: eslint 檢查的配置
          |-- .gitignore: git 版本管制忽略的配置
          |-- index.html: 主頁面文件
          |-- package.json: 應用包配置文件
          |-- README.md: 應用描述說明的 readme 文件
          

          1??5??.8?? Vue-CLI項目編碼

          1??5??.8??.1?? 編碼位置

          • 組件的邏輯直接寫在xxx.vue中
          • 靜態資源放在assets文件夾下面 直接使用對應路徑引用即可

          1??5??.8??.2?? 引入css

          • 全局引入
            main.js=> import "路徑"
          • 局部引入
            組件內的script標簽=> @import url("路徑")

          1??5??.8??.3?? 注冊組件

          • 全局組件
            引入在main.js中
            import 組件 from 地址
            Vue.component('組件名',組件)
            任意地方都可以使用 將組件名作為標簽名 一次注冊 全部使用
          • 局部組件
            在需要用到這個組件的地方 導入import 組件名 form '地址'
            導入后 設置給components 就可以在導入的組件中通過組件名使用該組件
            根據使用的位置 決定局部或者全局注冊 只在某些地方用 用局部組件
          • 組件中的name屬性
            直接在組件的內部寫name:值即可
            不能用中文
            寫了只會 Chrome的Vue插件中就可以看見這個名字 更加利于檢索 利于編碼

          1??5??.8??.4?? 整合路由

          1??5??.8??.4??.1?? 下包

          npm install vue-router

          1??5??.8??.4??.2?? 導包

          import VueRouter from 'vue-router'

          1??5??.8??.4??.3?? 用包

          • 創建路由規則
            在components文件夾下創建一個組件xxx.vue
            import 組件名 from '組件路徑'
            const routes=[{path:"/xxx/:xx},component:組件名]
          • 創建路由對象
          `const router=new VueRouter({
              routes
          })`
          
          • 設置給Vue實例
          `new Vue({
              router
          })`
          

          1??5??.8??.4??.4?? 編碼位置

          • 導入 注冊路由 main.js
          • router-link router-view app.vue
          • 添加組件components
          • 靜態資源assets

          1??5??.9?? 在Vue中使用其他插件

          • 可以將插件寫到Vue原型中 這樣在其他組件中都可以使用這個插件
          • (main.js)Vue.prototype.$XXX=XXX
          • (其他組件) this.$XXX
          • $XXX 的$的目的是 區分是Vue自帶的屬性還是后面自定義在原型中的屬性

          1??5??.9??.1?? 面試問及

          • Vue原型用過沒
          • 為了共享 將插件設置在Vue原型上
          • 所有組件都是Vue的實例
          • 所有在其他組件中 可以通過 this.$XXX 獲取

          1??5??.1??0?? css預處理與css作用域

          1??5??.1??0??.1?? css預處理

          1??5??.1??0??.1??.1??使用less

          • 下載
            -npm install -D less-loader less
          • 使用
            <style lang='less'></style> 也可以直接導入less文件

          1??5??.1??0??.1??.2?? 使用sass

          • 下載
            -npm install -D sass-loader node-sass
          • 使用
            <style lang='scss'></style> 也可以至今導入scss文件

          1??5??.1??0??.2?? css作用域

          • 為style標簽 添加 scoped 屬性即可
          • 生成樣式,和渲染組件時

          為元素添加隨機屬性 樣式中添加屬性選擇器 2者結合 就把css的作用范圍 約束

          • 為了不影響其他 可以添加這個屬性
          • 注意
            樣式的屬性是隨機生成的 如果要修改樣式
            直接修改在scoped中的樣式 不要抽離成樣式文件導入

          1??5??.1??1?? ES6模塊化語法

          1??5??.1??1??.1?? 默認導出導入

          • 導出
            export default xxx 只能寫一個 如果需要暴露多個 可以在default后面寫對象
          • 導入
            import xxx from "模塊"

          1??5??.1??1??.2?? 按名字導出導入

          • 導出
            export const bbb 導出和導入的名字必須一樣
          • 導入
            import {bbb} from "模塊"

          1??5??.1??2?? Vue全家桶

          • Vue
          • axios
          • Vue-router
          • 餓了么ui

          餓了么前端團隊開發的PC端的基于Vue的組件 內部封裝了很多現成的組件 在VueCLI中使用elementUI npm i element-ui import ElementUI from 'element-ui' import 'element-ui/lib/theme-chalk/index.css' Vue.use(ElementUI) 有些組件并沒有在組件內部使用原生事件 但是有些情況需要一些原生事件 就可以使用.native修飾符來觸發

          • Vuex

          ??1??6??、擴展

          ??1??6??.1?? link 和 @import 的區別

          ??1??6??.1??.1?? link

          • link是html提供引入樣式的標簽
          • link沒有兼容性問題
          • 可以通過JavaScript來控制link標簽 修改樣式文件路徑
          • 會和html一起加載

          ??1??6??.1??.2?? @import

          • @import是提供的提供導入樣式的方法
          • @import有兼容問題 ie5以下不支持
          • 不能通過JavaScript來操縱@import
          • 等html全部加載完畢后再加載@import

          ??1??6??.2?? JavaScript數組方法

          • arr.filter()

          返回所有匹配成功的值 創建一個新數組, 其包含通過所提供函數實現的測試的所有元素 (數組過濾)

          const oldArr=["dajsk", "dkjdklas", "kgjftlk", "ksf", "ds", "mfksjjks"];
          let res=oldArr.filter((val, index)=> val.indexOf("d") !=-1); // 返回所有匹配成功的值
          console.log(res); // [ 'dajsk', 'dkjdklas', 'ds' ]
          
          • arr.find()

          返回匹配的第一個值 返回數組中滿足提供的測試函數的第一個元素的值 沒有匹配成功返回undefined

          const oldArr=["dajsk", "dkjdklas", "kgjftlk", "ksf", "ds", "mfksjjks"];
          let res1=oldArr.find((val, index)=> val.indexOf("d") !=-1); // 返回匹配的第一個值
          console.log(res1); // dajsk
          
          • arr.map()

          將匹配成功的值做對應的計算后再次返回 創建一個新數組 其結果是該數組中的每個元素都調用一個提供的函數后返回的結果

          const oldArrMap=[3, 4, 7, 1, 8, 5];
          let res2=oldArrMap.map((val, index)=> {
            // 將匹配成功的值做對應的計算后再次返回
            if (val > 5) {
              val=val * 2;
            }
            return val;
          });
          console.log(res2); // [ 3, 4, 14, 1, 16, 5 ]
          

          因為這些方法都是返回的新數組 并沒有覆蓋原來的數組所以可以繼續鏈式調用數組的方法繼續過濾

          • arr.forEach()

          遍歷數組 方法對數組的每個元素執行一次提供的函數

          const oldArrForEach=[3, 6, 8, 2, 8, 0];
          let num=0;
          oldArrForEach.forEach((val, index)=> {
            num +=val;
          });
          console.log(num); // 27
          oldArrForEach.forEach((val, index)=> {
            if (index==2) return console.log(val); // 8
          });
          

          ??1??6??.3?? 解決跨域方案

          • CORS
            服務器設置允許訪問 響應一個響應頭
            存在低版本不識別這個響應頭
          • JSONP
            瀏覽器script的src支持跨域訪問 發送一個callback去服務器
            服務器接收callback 返回一個函數的調用攜帶數據
            瀏覽器接收到返回值當作js執行 執行代碼

          注意 需要在瀏覽器聲明callback去的函數 需要在script請求前聲明 兼容性強 只能發送get請求

          • flash
            現已不用 蘋果不支持flash
          • sliverlight
          • WebSocket
          • postmessage
          • iframe
          • ...

          ??1??6??.4?? 接口的請求方法和restful api

          網絡請求設計方法時 考慮到數據的操作主要:增刪改查 方法的命名可以體現這個操作 一般常用的就是get和post

          1. GET(SELECT):從服務器取出資源(一項或多項).
          2. POST(CREATE):在服務器新建一個資源.
          3. PUT(UPDATE):在服務器更新資源(客戶端提供改變后的完整資源).
          4. PATCH(UPDATE):在服務器更新資源(客戶端提供改變的屬性).
          5. DELETE(DELETE):從服務器刪除資源.
          6. HEAD:獲取資源的元數據.
          7. OPTIONS:獲取信息,關于資源的哪些屬性是客戶端可以改變的.

          ??1??6??.5?? Cookie、Session、token、localStorage、sessionStorage

          ??1??6??.5??.1?? Cookie

          • 用來解決http 是無狀態 的
          • 什么是無狀態?

          每次請求 瀏覽器和服務器交互完畢后 彼此并沒有留下什么 繼續請求 也無法判斷你是誰 如登陸功能 為了能夠保存一些信息 服務器返回響應報文時 會偷偷的帶一個響應頭 作用是在瀏覽器中偷偷保存一些信息set-cookie 瀏覽器接收到這個響應頭后 會在本地保存這個響應頭 第二次請求時 瀏覽器就會自動帶上這個信息去服務器 服務器接收到這個信息 就知道你是誰了 ajax跨域請求 默認不攜帶cookie 需要設置 跨域cookie在瀏覽器中無法看到 需要抓包

          ??1??6??.5??.2?? Session

          Seesion 是將用戶數據存儲在服務器中 通過sessionId來驗證查找服務器中的用戶信息 sessionId一般是存放在瀏覽器的cookie中的

          所以Session需要配合瀏覽器的cookie或者瀏覽器的其他存儲技術一起使用

          ??1??6??.5??.3?? token

          和cookie差不多 也可以記錄登陸狀態 服務器生成的 通過用戶瀏覽器版本、用戶信息...生成的一個密鑰

          瀏覽器不會自動保存 可以接口本地存儲來保存token 瀏覽器不會自動攜帶發送 每次請求接口時可以通過headers攜帶存儲的token headers{ Authorization :token }

          ??1??6??.5??.4?? localStorage

          可以把數據存儲到本地(瀏覽器) 只要用戶不刪除 則會一直保存 每個域名都是獨立的保存數據 不同域名不能互相訪問 長久保存數據可以存儲到 localStorage 可以存儲5M數據

          • 保存數據 localStorage.setItem(key,value)
          • 獲取數據 localStorage.getItem(key)=> 如果沒有這個數據 則返回 null
          • 刪除一個數據 localStorage.removeItem(key)
          • 清空所有數據 localStorage.clear()

          ??1??6??.5??.5?? sessionStorage

          短暫存儲數據 可以多頁面傳值 相當于localStorage會更安全 瀏覽器關閉后就不會保存了 可以存儲5M數據

          • 保存數據 sessionStorage.setItem(key,value)
          • 獲取數據 sessionStorage.getItem(key)=> 如果沒有這個數據 則返回 null
          • 刪除一個數據 sessionStorage.removeItem(key)
          • 清空所有數據 sessionStorage.clear()

          ??1??7??、Xmind筆記


          很多都是自己的話去解釋和理解 可能會存在錯誤 或者有錯別字 歡迎指出謝謝

          若有感興趣的小伙伴,需要VUE學習文檔思維導圖原圖的,關注我,私信回復獲取:VUE學習文檔思維導圖


          作者:藍海00
          轉載鏈接:https://www.jianshu.com/p/125ce0c89603

          、MVVM簡介

          如果你是第一次學前端,那么本節知識一定要了解,什么是MVVM。

          MVVM是Model-View-ViewModel的簡寫。它本質上就是MVC 的改進版。MVVM 就是將其中的View 的狀態和行為抽象化,讓我們將視圖 UI 和業務邏輯分開。當然這些事 ViewModel 已經幫我們做了,它可以取出 Model 的數據同時幫忙處理 View 中由于需要展示內容而涉及的業務邏輯。MVVM的核心是ViewModel層,負責轉換Model中的數據對象來讓數據變得更容易管理和使用。是一種簡化用戶界面的事件驅動編程方式

          下邊我們來畫張圖來大體了解下MVVM的工作原理圖:

          該層向上與視圖層進行雙向數據綁定

          向下與Model層通過接口請求進行數據交互

          (1)View

          View是視圖層, 也就是用戶界面。前端主要由HTH L和csS來構建, 為了更方便地展現vi eu to del或者Hodel層的數據, 已經產生了各種各樣的前后端模板語言, 比如FreeMarker,Thyme leaf等等, 各大MV VM框架如Vue.js.Angular JS, EJS等也都有自己用來構建用戶界面的內置模板語言。

          (2)Model

          Model是指數據模型, 泛指后端進行的各種業務邏輯處理和數據操控, 主要圍繞數據庫系統展開。這里的難點主要在于需要和前端約定統一的接口規則

          (3)ViewModel

          ViewModel是由前端開發人員組織生成和維護的視圖數據層。在這一層, 前端開發者對從后端獲取的Model數據進行轉換處理, 做二次封裝, 以生成符合View層使用預期的視圖數據模型。

          View Model所封裝出來的數據模型包括視圖的狀態和行為兩部分, 而Model層的數據模型是只包含狀態的

          視圖狀態和行為都封裝在了View Model里。這樣的封裝使得View Model可以完整地去描述View層。由于實現了雙向綁定, View Model的內容會實時展現在View層, 這是激動人心的, 因為前端開發者再也不必低效又麻煩地通過操縱DOM去更新視圖。 MVVM框架已經把最臟最累的一塊做好了, 我們開發者只需要處理和維護View Model, 更新數據視圖就會自動得到相應更新,真正實現事件驅動編程。 View層展現的不是Model層的數據, 而是ViewModel的數據, 由ViewModel負責與Model層交互, 這就完全解耦了View層和Model層, 這個解耦是至關重要的, 它是前后端分離方案實施的重要一環。


          2、為什么要使用MVVM

          MVVM模式和MVC模式一樣,主要目的是分離視圖(View)和模型(Model),有幾大優點

          (1) 低耦合。視圖(View)可以獨立于Model變化和修改,一個ViewModel可以綁定到不同的"View"上,當View變化的時候Model可以不變,當Model變化的時候View也可以不變。

          (2) 可重用性。你可以把一些視圖邏輯放在一個ViewModel里面,讓很多view重用這段視圖邏輯。

          (3)獨立開發。開發人員可以專注于業務邏輯和數據的開發(ViewModel),設計人員可以專注于頁面設計,使用Expression Blend可以很容易設計界面并生成xaml代碼。

          (4)可測試。界面素來是比較難于測試的,測試可以針對ViewModel來寫


          3、VUE概述

          (1)什么是vue?

          Vue是一套用于構建用戶界面的漸進式框架。與其它大型框架不同的是,Vue 被設計為可以自底向上逐層應用。Vue 的核心庫只關注視圖層,不僅易于上手,還便于與第三方庫或既有項目整合

          這是官網給出的介紹,可能不是那么容易理解。簡單來說,Vue是一個視圖層框架,幫助我們更好的構建應用。

          使用Vue和原生JS一個最顯著的差別就是,Vue不再對DOM直接進行操作,而是通過對數據的操作,來改變頁面。使用Vue構建的頁面,是有一個個的組件組成的,當組件中定義的數據發生變化時,組件的顯示也會跟著變化,且此過程無需刷新頁面。

          (2)MVVM模式的實現者

          Model:模型層, 在這里表示JavaScript對象 View:視圖層, 在這里表示DOM(HTML操作的元素) ViewModel:連接視圖和數據的中間件, Vue.js就是MVVM中的View Model層的實現者 在MVVM架構中, 是不允許數據和視圖直接通信的, 只能通過ViewModel來通信, 而View Model就是定義了一個Observer觀察者

          ViewModel能夠觀察到數據的變化, 并對視圖對應的內容進行更新 ViewModel能夠監聽到視圖的變化, 并能夠通知數據發生改變 至此, 我們就明白了, Vue.js就是一個MV VM的實現者, 他的核心就是實現了DOM監聽與數據綁定

          (3)為什么要使用Vue

          易用:熟悉HTML、CSS、JavaScript之后,可快速度上手vue。學習曲線平穩。

          輕量級:Vue.js壓縮后有只有20多kb,超快虛擬DOM

          高效:吸取了Angular(模塊化) 和React(虛擬DOM) 的優勢, 并擁有自己獨特的功能

          開源:文檔齊全,社區活躍度高


          4、VUE之Hello World!

          步驟一:創建空文件

          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>Document</title>
          </head>
          <body>
          
          </body>
          </html>

          步驟二:引入vue.js (本人下載的開發版的vue.js,跟本html文件放在了同一目錄下,所以直接引用)

          <script type="text/javascript" src="vue.js"></script>

          步驟三:創建vue實例

          <script type="text/javascript">
                  var vm=new Vue({
                      el:'#app',
                      data:{
                          msg:'Hello World'
                      }
                  });
          </script>

          步驟四:數據與頁面元素綁定

          <div id="app">
                  {{msg}}
          </div>

          完整的html

          <!DOCTYPE html>
          <html lang="en">
          <body>
              <div id="app">
                  {{msg}}
              </div>
              <script type="text/javascript" src="vue.js"></script>
              <script type="text/javascript">
                  var vm=new Vue({
                      el:'#app',
                      data:{
                          msg:'Hello World'
                      }
                  });
              </script>
          </body>
          </html>

          瀏覽器打開:

          參數分析:

          el : '#app' -- 綁定元素的ID(元素的掛載位置,值可以是CSS選擇器或者是DOM元素)

          data : { msg : 'Hello World' } -- 模型數據,屬性名:msg 值:Hello World

          {{msg}} : 在綁定的元素中使用{{ }}將Vue創建的名為msg的屬性包起來, 即可實現數據綁定功能,我們在調試狀態下手動修改下msg的值,在不刷新頁面的情況下就會展示我們修改后的值,這就是借助了Vue的數據綁定功能實現的。 MV VM模式中要求View Model層就是使用觀察者模式來實現數據的監聽與綁定, 以做到數據與視圖的快速響應

          下一篇:VUE入門教程(二)之模板語法(指令)



          者: CHICAGO

          轉發連接:https://juejin.im/post/5e475829f265da57444ab10f


          主站蜘蛛池模板: 国产精品日韩一区二区三区| 无码中文字幕乱码一区| 国产韩国精品一区二区三区久久| 人妻体内射精一区二区| 青娱乐国产官网极品一区| 国产一区二区在线观看麻豆 | 无码av中文一区二区三区桃花岛| 国产精品亚洲综合一区在线观看| 婷婷国产成人精品一区二| 亚洲爆乳精品无码一区二区| 无码中文字幕人妻在线一区二区三区| 无码少妇一区二区| 国产香蕉一区二区三区在线视频| 国产小仙女视频一区二区三区| 亚洲av无码一区二区三区人妖 | 国产区精品一区二区不卡中文| 国产精品高清一区二区人妖| 午夜福利国产一区二区| 国产一区二区免费| 国产精品一区二区三区99| 国产一区二区在线|播放| 国产成人综合一区精品| 人妻夜夜爽天天爽爽一区| 亚洲综合无码一区二区痴汉| 国产精品免费视频一区| 国产情侣一区二区三区| 国产精品视频一区二区噜噜| 国产在线一区二区杨幂| 高清国产AV一区二区三区| 九九久久99综合一区二区| 日韩在线视频不卡一区二区三区| 日韩精品一区二区三区在线观看l| 久久久久人妻一区二区三区vr| 美女啪啪一区二区三区| 亚洲av无码一区二区三区天堂古代 | 日本伊人精品一区二区三区| 一区二区精品视频| 国产在线视频一区二区三区98| 国产aⅴ精品一区二区三区久久| 中文国产成人精品久久一区| 久久免费视频一区|