Vue完整总结
目錄
- Vue
- MVVM思想
- Vue簡介
- 入門案例
- 安裝
- HelloWorld
- vue聲明式渲染
- 雙向綁定
- 事件處理
- 概念
- 創建Vue實例
- 模板或元素
- 數據
- 方法
- 指令
- 插值表達式
- 花括號
- 插值閃爍
- v-text和v-html
- v-bind
- 綁定class
- 綁定style
- 綁定其他任意屬性
- v-bind縮寫
- v-model
- v-on
- 基本用法
- 事件修飾符
- 按鍵修飾符
- 組合按鈕
- v-for
- 遍歷數組
- 數組角標
- 遍歷對象
- Key
- v-if和v-show
- 基本用法
- 與v-for結合
- v-else和v-else-if
- 計算屬性和偵聽器
- 計算屬性(computed)
- 偵聽(watch)
- 過濾器(filters)
- 局部過濾器
- 全局過濾器
- 組件化
- 全局組件
- 組件的復用
- 局部組件
- 生命周期鉤子函數
- 生命周期
- 鉤子函數
- vue模塊化開發
- 模塊化開發
- 項目結構
- Vue單文件組件
- 導入element-ui快速開發
Vue
MVVM思想
- M:即Model,模型,包括數據和一些基本操作
- V:即View,視圖,頁面渲染結果
- VM:即View-Model,模型與視圖間的雙向操作(無需開發人員干涉)
在MVVM之前,開發人員從后端獲取需要的數據模型,然后要通過DOM操作Model渲染到View中。而后當用戶操作視圖,還需要通過DOM獲取View中的數據,然后同步到Model中。
而MVVM中的VM要做的事情就是把DOM操作完全封裝起來,開發人員不用再關心Model和View之間是如何互相影響的:
- 只要Model發生了改變,View上自然就會表現出來。
- 當用戶修改了View,Model中的數據也會跟著改變。
把開發人員從繁瑣的DOM操作中解放出來,把關注點放在如何操作Model上。
Vue簡介
Vue(讀音/vju?/,類似于view)是一套用于構建用戶界面的漸進式框架。與其它大型框架不同的是,Vue被設計為可以自底向上逐層應用。Vue的核心庫只關注視圖層,不僅易于上
手,還便于與第三方庫或既有項目整合。另一方面,當與現代化的工具鏈以及各種支持類庫結合使用時,Vue也完全能夠為復雜的單頁應用提供驅動。
官網:https://cn.vuejs.org/
參考:https://cn.vuejs.org/v2/guide/
Git地址:https://github.com/vuejs
尤雨溪,Vue.js創作者,VueTechnology創始人,致力于Vue的研究開發。
入門案例
安裝
官網文檔提供了3中安裝方式:
1.直接script引入本地vue文件。需要通過官網下載vue文件。
2.通過script引入CDN代理。需要聯網,生產環境可以使用這種方式
3.通過npm安裝。這種方式也是官網推薦的方式,需要nodejs環境。
本課程就采用第三種方式
HelloWorld
h2中要輸出一句話:xx是技術類公眾號。前面的xx是要渲染的數據。
<div id="#app"><h2>{{name}}, 是技術類公眾號</h2> </div> <script src="./node_modules/vue/dist/vue.min.js"></script> <script>let vm = new Vue({el: "#app",data: {name: "后端碼匠"}}); </scipt>vue聲明式渲染
<body><div id="app"><h1>{{name}}, 是技術類公眾號</h1></div><script src="./node_modules/vue/dist/vue.min.js"></script><script>let vm = new Vue({el: "#app",data: {name: "后端碼匠"}});</script> </body>- 首先通過newVue()來創建Vue實例
- 然后構造函數接收一個對象,對象中有一些屬性:
- el:是element的縮寫,通過id選中要渲染的頁面元素,本例中是一個div
- data:數據,數據是一個對象,里面有很多屬性,都可以渲染到視圖中
- name:這里指定了一個name屬性
- 頁面中的h2元素中,通過{{name}}的方式,來渲染剛剛定義的name屬性。
更神奇的在于,當你修改name屬性時,頁面會跟著變化:
雙向綁定
<body><div id="app"><h1>{{name}}, 是技術類公眾號, 有{{num}}個人關注</h1></div><script src="https://cdn.jsdelivr.net/gh/xzMhehe/StaticFile_CDN@main/static/vue.min.js"></script><script>let vm = new Vue({el: "#app",data: {name: "后端碼匠",num: 10000}});</script> </body>雙向綁定:
效果:修改表單項,num會發生變化。修改num,表單項也會發生變化。為了實時觀察到這個變化,將num輸出到頁面。
事件處理
<body><div id="app"><button v-on:click="num++">關注</button><h1>{{name}}, 是技術類公眾號, 有{{num}}個人關注</h1></div><script src="https://cdn.jsdelivr.net/gh/xzMhehe/StaticFile_CDN@main/static/vue.min.js"></script><script>let vm = new Vue({el: "#app",data: {name: "后端碼匠",num: 10000}});</script> </body>- 這里用v-on指令綁定點擊事件,而不是普通的onclick,然后直接操作num
- 普通click是無法直接操作num的。
- 未來會見到更多v-xxx,這些都是vue定義的不同功能的指令。
簡單使用總結:
- 使用Vue實例管理DOM
- DOM與數據/事件等進行相關綁定
- 只需要關注數據,事件等處理,無需關心視圖如何進行修改
概念
創建Vue實例
每個Vue應用都是通過用Vue函數創建一個新的Vue實例開始的:
let app = new Vue({ });在構造函數中傳入一個對象,并且在對象中聲明各種Vue需要的數據和方法,包括:
- el
- data
- methods
等等
模板或元素
每個Vue實例都需要關聯一段Html模板,Vue會基于此模板進行視圖渲染。
可以通過el屬性來指定。
例如一段html模板:
然后創建Vue實例,關聯這個div
let vm = new Vue({el: "#app" });這樣,Vue就可以基于id為app的div元素作為模板進行渲染了。在這個div范圍以外的部
分是無法使用vue特性的。
數據
當Vue實例被創建時,它會嘗試獲取在data中定義的所有屬性,用于視圖的渲染,并且監視data中的屬性變化,當data發生改變,所有相關的視圖都將重新渲染,這就是“響應式
“系統。
html:
JS:
let vm = new Vue({el: "#app",data: {name: "后端碼匠"} });- name的變化會影響到input的值
- input中輸入的值,也會導致vm中的name發生改變
方法
Vue實例中除了可以定義data屬性,也可以定義方法,并且在Vue實例的作用范圍內使用。
Html:
JS:
let vm = new Vue({el: "#app",data: {num: 0},methods: {add: function(){//this代表的當前vue實例this.num++;}} });指令
什么是指令?
- 指令(Directives)是帶有v-前綴的特殊特性。
- 指令特性的預期值是:單個JavaScript表達式。
- 指令的職責是,當表達式的值改變時,將其產生的連帶影響,響應式地作用于DOM。
例如在入門案例中的v-on,代表綁定事件。
插值表達式
花括號
格式:{{表達式}}
說明:
- 該表達式支持JS語法,可以調用js內置函數(必須有返回值)
- 表達式必須有返回結果。例如1+1,沒有結果的表達式不允許使用,如:let a = 1 + 1;
- 可以直接獲取Vue實例中定義的數據或函數
插值閃爍
使用
{{}}方式在網速較慢時會出現問題。在數據未加載完成時,頁面會顯示出原始的
{{}}加載完畢后才顯示正確數據,稱為插值閃爍。
將網速調慢一些,然后刷新頁面,試試看案例:
v-text和v-html
可以使用v-text和v-html指令來替代
{{}}說明:
- v-text:將數據輸出到元素內部,如果輸出的數據有HTML代碼,會作為普通文本輸出
- v-html:將數據輸出到元素內部,如果輸出的數據有HTML代碼,會被渲染
示例:
<div id = "app">v-text:<span v-text = "hello"></span><br/>v-html:<span v-html = "hello"></span> </div> <script>let vm = new Vue({el: "#app",data: {hello: "<h1>大家好</h1>"},methods: {} }); </script>并且不會出現插值閃爍,當沒有數據時,會顯示空白或者默認數據。
v-bind
html屬性不能使用雙大括號形式綁定,使用v-bind指令給HTML標簽屬性綁定值;
而且在將v-bind用于class和style時,Vue.js做了專門的增強。
綁定class
<div class="static"v-bind:class="{active: isActive, 'text-danger': hasError}"> </div> <script>let vm = new Vue({el: "#app",data: {isActive: true,hasError: false}}) </script>綁定style
v-bind:style的對象語法十分直觀,看著非常像CSS,但其實是一個JavaScript對象。style屬性名可以用駝峰式(camelCase)或短橫線分隔(kebab-case,這種方式記得用單引號括起來)來命名。
例如:font-size–>fontSize
結果:
綁定其他任意屬性
<div id = "app" v-bind:style="{color: activeColor, fontSize: fontSize + 'px'}" v-bind:user = "userName"></div> <script>let vm = new Vue({el: "#app",data: {activeColor: 'red',fontSize: 30,userName: 'zhangsan'}}) </script>效果:
v-bind縮寫
<div id = "app" :style="{color: activeColor, fontSize: fontSize + 'px'}" :user = userName> </div>v-model
剛才的v-text、v-html、v-bind可以看做是單向綁定,數據影響了視圖渲染,但是反過來就不行。接下來的v-model是雙向綁定,視圖(View)和模型(Model)之間會互相影響。
既然是雙向綁定,一定是在視圖中可以修改數據,這樣就限定了視圖的元素類型。目前v-model的可使用元素有:
- input
- select
- textarea
- checkbox
- radio
- components(Vue中的自定義組件)
基本上除了最后一項,其它都是表單的輸入項。
示例:
- 多個CheckBox對應一個model時,model的類型是一個數組,單個checkbox值默認是boolean類型
- radio對應的值是input的value值
- text和textarea默認對應的model是字符串
- select單選對應字符串,多選對應也是數組
v-on
基本用法
v-on指令用于給頁面元素綁定事件。語法:v-on:事件名=“js片段或函數名”
示例:
另外,事件綁定可以簡寫,例如v-on:click='add'可以簡寫為@click='add'
事件修飾符
在事件處理程序中調用event.preventDefault()或event.stopPropagation()是非常常見的需求。盡管可以在方法中輕松實現這點,但更好的方式是:方法只有純粹的數據邏輯,而不是去處理DOM事件細節。
為了解決這個問題,Vue.js為v-on提供了事件修飾符。修飾符是由點開頭的指令后綴來表示的。
- .stop:阻止事件冒泡到父元素
- .prevent:阻止默認事件發生
- .capture:使用事件捕獲模式
- .self:只有元素自身觸發事件才執行。(冒泡或捕獲的都不執行)
- .once:只執行一次
效果:右鍵“點贊”,不會觸發默認的瀏覽器右擊事件;右鍵“取消”,會觸發默認的瀏覽器右擊事件)
按鍵修飾符
在監聽鍵盤事件時,經常需要檢查常見的鍵值。Vue允許為v-on在監聽鍵盤事件時添加按鍵修飾符:
<!--只有在`keyCode`是13時調用`vm.submit()`--> <input v-on:keyup.13 = "submit">記住所有的keyCode比較困難,所以Vue為最常用的按鍵提供了別名:
<!--同上--> <input v-on:keyup.enter = "submit"> <input @keyup.enter = "submit"> <!--縮寫語法-->全部的按鍵別名:
- enter
- tab
- .delete(捕獲“刪除”和“退格”鍵)
- esc
- .space
- .up
- down
- left
- .right
組合按鈕
可以用如下修飾符來實現僅在按下相應按鍵時才觸發鼠標或鍵盤事件的監聽器。
- ctrl
- alt
- shift
v-for
遍歷數據渲染頁面是非常常用的需求,Vue中通過v-for指令來實現。
遍歷數組
語法:v-for = “item in items”
- items:要遍歷的數組,需要在vue的data中定義好。
- item:迭代得到的當前正在遍歷的元素
數組角標
在遍歷的過程中,如果需要知道數組角標,可以指定第二個參數:
語法:v-for="(item, index) in items"
- items:要迭代的數組
- item:迭代得到的數組元素別名
- index:迭代到的當前元素索引,從0開始。
遍歷對象
v-for除了可以迭代數組,也可以迭代對象。語法基本類似
語法:
v-for=“valueinobject”
v-for="(value,key)inobject"
v-for="(value,key,index)inobject"
- 1個參數時,得到的是對象的屬性值
- 2個參數時,第一個是屬性值,第二個是屬性名
- 3個參數時,第三個是索引,從0開始
示例:
<div id="app"><ul><li v-for = "(value, key, index) in users">{{index + 1}}.{{key}} - {{value}}</li></ul> </div> <script src="https://cdn.jsdelivr.net/gh/xzMhehe/StaticFile_CDN@main/static/vue.min.js"></script> <script>let vm = new Vue({el: "#app",data: {users: [user: {name: '張三', gender: '男', age: 18}]},methods: {decrement(ev) {//ev.preventDefault();this.num--;}}}); </script>效果:
- 1.name - 張三
- 2.gender - 男
- 3.age - 18
Key
用來標識每一個元素的唯一特征,這樣Vue可以使用“就地復用”策略有效的提高渲染的效率。
示例:
如果items是數組,可以使用index作為每個元素的唯一標識
如果items是對象數組,可以使用item.id作為每個元素的唯一標識
v-if和v-show
基本用法
v-if,顧名思義,條件判斷。當得到結果為true時,所在的元素才會被渲染。v-show,當得到結果為true時,所在的元素才會被顯示。
語法:v-if=“布爾表達式”,v-show=“布爾表達式”,
與v-for結合
當v-if和v-for出現在一起時,v-for優先級更高。也就是說,會先遍歷,再判斷條件。修改v-for中的案例,添加v-if:
- {{index + 1}}.{{user.name}} - {{user.gender}} - {{user.age}}
v-else和v-else-if
v-else元素必須緊跟在帶v-if或者v-else-if的元素的后面,否則它將不會被識別。
<div id = "app"><button v-on:click = "random = Math.random()">點我呀</button><span>{{random}}</span><h1 v-if = "random >= 0.75">看到我啦?!v-if>=0.75</h1><h1 v-else-if = "random > 0.5">看到我啦?!v-else-if>0.5</h1><h1 v-else-if = "random > 0.25">看到我啦?!v-else-if>0.25</h1><h1 v-else>看到我啦?!v-else</h1> </div> <script src="../node_modules/vue/dist/vue.js"></script> <script type="text/javascript">let app = new Vue({el: "#app",data: {random: 1}}); </script>計算屬性和偵聽器
計算屬性(computed)
某些結果是基于之前數據實時計算出來的,可以利用計算屬性。來完成
<div id = "app"><ul><li>西游記:價格{{xyjPrice}},數量:<input type = "number" v-model = "xyjNum"></li><li>水滸傳:價格{{shzPrice}},數量:<input type = "number" v-model = "shzNum"></li><li>總價:{{totalPrice}}</li></ul> </div> <script src = "../node_modules/vue/dist/vue.js"></script> <script type = "text/javascript">let app = new Vue({el: "#app",data: {xyjPrice: 56.73,shzPrice: 47.98,xyjNum: 1,shzNum: 1},computed:{totalPrice() {return this.xyjPrice * this.xyjNum + this.shzPrice * this.shzNum;}})}; </script>效果:只要依賴的屬性發生變化,就會重新計算這個屬性
偵聽(watch)
watch可以讓監控一個值的變化。從而做出相應的反應。
<div id = "app"><ul><li>西游記:價格{{xyjPrice}},數量:<input type = "number" v-model = "xyjNum"></li><li>水滸傳:價格{{shzPrice}},數量:<input type = "number" v-model = "shzNum"></li><li>總價:{{totalPrice}}</li>{{msg}}</ul> </div> <script src = "../node_modules/vue/dist/vue.js"></script> <script type = "text/javascript">letapp=newVue({el: "#app",data: {xyjPrice: 56.73,shzPrice: 47.98,xyjNum: 1,shzNum: 1,msg: ""},computed:{totalPrice() {return this.xyjPrice * this.xyjNum + this.shzPrice * this.shzNum;}},atch: {xyjNum(newVal, oldVal){if(newVal >= 3) {this.msg = "西游記沒有更多庫存了";this.xyjNum = 3;} else {his.msg="";}}})}; </script>過濾器(filters)
過濾器不改變真正的data,而只是改變渲染的結果,并返回過濾后的版本。在很多不同的
情況下,過濾器都是有用的,比如盡可能保持API響應的干凈,并在前端處理數據的格式。
示例:展示用戶列表性別顯示男女
<div id = "app"><table><tr v-for = "user in userList"><td>{{user.id}}</td><td>{{user.name}}</td><!--使用代碼塊實現,有代碼侵入--><td>{{user.gender === 1 ? "男" : "女"}}</td></tr></table> </div> <script src = "../node_modules/vue/dist/vue.js"></script> <script type = "text/javascript">let app = new Vue({el: "#app",data: {userList:[{id: 1, name: 'jacky', gender: 1},{id: 2, name: 'peter', gender: 0}]})}; </script>局部過濾器
冊在當前vue實例中,只有當前實例能用
<script type = "text/javascript">let app = new Vue({el: "#app",data: {userList:[{id: 1, name: 'jacky', gender: 1},{id: 2, name: 'peter', gender: 0}]},//filters定義局部過濾器,只可以在當前vue實例中使用filters: {myGenderFilter(gender){return gender === 1 ? '男~' : '女~';})}; </script> {{user.gender | myGenderFilter}}全局過濾器
//在創建Vue實例之前全局定義過濾器: Vue.filter('capitalize', function(value) {return value.charAt(0).toUpperCase() + value.slice(1) })任何vue實例都可以使用:
{{user.name | capitalize}}過濾器常用來處理文本格式化的操作。過濾器可以用在兩個地方:雙花括號插值和v-bind表達式
組件化
在大型應用開發的時候,頁面可以劃分成很多部分。往往不同的頁面,也會有相同的部分。
例如可能會有相同的頭部導航。
但是如果每個頁面都獨自開發,這無疑增加了開發的成本。所以會把頁面的不同部分拆分成獨立的組件,然后在不同頁面就可以共享這些組件,避免重復開發。
在vue里,所有的vue實例都是組件
例如你可能會有頁頭、側邊欄、內容區、等組件, 每個組件又包含了其他的導航鏈接、博文之類的組件
全局組件
通過Vue的component方法來定義一個全局組件。
<div id = "app"><!--使用定義好的全局組件--><counter></counter> </div> <script src="../node_modules/vue/dist/vue.js"></script> <script type = "text/javascript">//定義全局組件,兩個參數:1,組件名稱。2,組件參數Vue.component("counter", {template:'<button v-on:click="count++">你點了我{{count}}次,我記住了.</button>',data(){return{count: 0}}})let app = new Vue({el: "#app"}) </script>- 組件其實也是一個Vue實例,因此它在定義時也會接收:data、methods、生命周期函數等
- 不同的是組件不會與頁面的元素綁定,否則就無法復用了,因此沒有el屬性。
- 但是組件渲染需要html模板,所以增加了template屬性,值就是HTML模板
- 全局組件定義完畢,任何vue實例都可以直接在HTML中通過組件名稱來使用組件了
- data必須是一個函數,不再是一個對象。
組件的復用
定義好的組件,可以任意復用多次:
<div id = "app"><!--使用定義好的全局組件--><counter></counter><counter></counter><counter></counter> </div>組件的data屬性必須是函數!
一個組件的data選項必須是一個函數,因此每個實例可以維護一份被返回對象的獨立的拷
貝;
否則:
https://cn.vuejs.org/v2/guide/components.html#data-%E5%BF%85%E9%A1%BB%E6%98%AF%E4%B8%80%E4%B8%AA%E5%87%BD%E6%95%B0
局部組件
一旦全局注冊,就意味著即便以后你不再使用這個組件,它依然會隨著Vue的加載而加載。因此,對于一些并不頻繁使用的組件,會采用局部注冊。
先在外部定義一個對象,結構與創建組件時傳遞的第二個參數一致:
const counter = {template: '<buttonv-on:click="count++">你點了我{{count}}次,我記住了.</button>',data(){return{count:0}} };然后在Vue中使用它:
let app = new Vue({el: "#app",components:{counter: counter//將定義的對象注冊為組件} })- components就是當前vue對象子組件集合。
- 其key就是子組件名稱
- 其值就是組件對象名
- 效果與剛才的全局注冊是類似的,不同的是,這個counter組件只能在當前的Vue實例中使用
簡寫:
let app = new Vue({el: "#app",components:{counter//將定義的對象注冊為組件} })生命周期鉤子函數
生命周期
每個Vue實例在被創建時都要經過一系列的初始化過程:創建實例,裝載模板,渲染模板等等。Vue為生命周期中的每個狀態都設置了鉤子函數(監聽函數)。每當Vue實例處于不同的生命周期時,對應的函數就會被觸發調用。
生命周期:你不需要立馬弄明白所有的東西。
鉤子函數
- beforeCreated:在用Vue時都要進行實例化,因此,該函數就是在Vue實例化時調用,也可以將他理解為初始化函數比較方便一點,在Vue1.0時,這個函數的名字就是init。
- created:在創建實例之后進行調用。
- beforeMount:頁面加載完成,沒有渲染。如:此時頁面還是{{name}}
- mounted:可以將他理解為原生js中的window.οnlοad=function({.,.}),或許大家也在用jquery,所以也可以理解為jquery中的$(document).ready(function(){….}),他的功能就是:在dom文檔渲染完畢之后將要執行的函數,該函數在Vue1.0版本中名字為compiled。此時頁面中的{{name}}已被渲染成張三
- beforeDestroy:該函數將在銷毀實例前進行調用。
- destroyed:改函數將在銷毀實例時進行調用。
- beforeUpdate:組件更新之前。
- updated:組件更新之后。
vue模塊化開發
- npminstallwebpack-g
全局安裝webpack - npminstall-g@vue/cli-init
全局安裝vue腳手架 - 初始化vue項目;
vueinitwebpackappname:vue腳手架使用webpack模板初始化一個appname項目 - 啟動vue項目;
項目的package.json中有scripts,代表能運行的命令
npmstart=npmrundev:啟動項目
npmrunbuild:將項目打包
模塊化開發
項目結構
運行流程
進入頁面首先加載index.html和main.js文件。
- main.js導入了一些模塊【vue、app、router】,并且創建vue實例,關聯index.html頁面的<divid=”app”>元素。使用了router,導入了App組件。并且使用標簽引用了這個組件
- 第一次默認顯示App組件。App組件有個圖片和,所以顯示了圖片。但是由于代表路由的視圖,默認是訪問/#/路徑(router路徑默認使用HASH模式)。在router中配置的/是顯示HelloWorld組件。
- 所以第一次訪問,顯示圖片和HelloWorld組件。
- 嘗試自己寫一個組件,并且加入路由。點擊跳轉。需要使用<router-linkto="/foo">GotoFoo標簽
Vue單文件組件
Vue單文件組件模板有三個部分;
<template><div class="hello"><h1>{{msg}}</h1></div> </template><script>export default{name: 'HelloWorld',data() {return{msg: 'WelcometoYourVue.jsApp'}}} </script><!--Add"scoped"attributetolimitCSStothiscomponentonly--> <style scoped>h1, h2 {font-weight: normal;} </style>- Template:編寫模板
- Script:vue實例配置
- Style:樣式
導入element-ui快速開發
1、安裝element-ui:npmielement-ui
2、在main.js中引入element-ui就可以全局使用了。
3、將App.vue改為element-ui中的后臺布局
4、添加測試路由、組件,測試跳轉邏輯
(1)、參照文檔el-menu添加router屬性
(2)、參照文檔el-menu-item指定index需要跳轉的地址
總結
- 上一篇: hexo d后 ERROR Deploy
- 下一篇: 第三方服务整合-阿里云OSS上传文件-填