閑聊:
自從進了現在的公司,小穎就再沒怎么接觸vue了,最近不太忙,所以想再學習下vue,就看了看vue相關視頻,順便做個筆記嘻嘻。
視頻地址:Vue 入門到實戰1、Vue 入門到實戰2
學習內容:
什么是vue?
官網回答:
Vue (讀音 /vjuː/,類似於 view) 是一套用於構建用戶界面的漸進式框架。與其它大型框架不同的是,Vue 被設計為可以自底向上逐層應用。Vue 的核心庫只關注視圖層,不僅易於上手,還便於與第三方庫或既有項目整合。另一方面,當與現代化的工具鏈以及各種支持類庫結合使用時,Vue 也完全能夠為復雜的單頁應用提供驅動。
視頻筆記:
vue是目前最火的前端框架、react是目前最流行的前端框架(react除了開發網站,還可以開發手機app,vue語法也可以用於開發手機app,需借助Weex)
vue是一套構建用戶界面的框架,只關注視圖層,所以易上手,而且也便於與第三方庫或既有項目整合。(vue的優點)
庫和框架的區別
框架:是一套完整的解決方案,對項目的侵入性比較大,項目如果需要換框架,則需重新搭建整個項目。
庫:提供一個小功能,對項目的入侵性比較小,如果某個庫無法完成某些需求,可以很容易切換到其它庫實現需求。
如何理解MVVM
MVVM是前端視圖層的分層開發思想,分成M、V和VM,其中VM是MVVM核心思想,因為VM是M和V之間的調度者。
——>取 ——> 取 M:ajax獲取的數據
M VM V VM:M、V之間的調度者
< ——存 <—— 存 V:每個頁面中的html代碼
使用MVVM的優點:為了我們開發更加方便,因為MVVM提供了數據的雙向綁定。(數據的雙向綁定是由VM提供的)。
vue指令:
v-cloak:能解決插值表達式閃爍問題。(經驗證目前版本不存在閃爍問題 Vue.js v2.5.16)
v-text:更新元素的 textContent
。如果要更新部分的 textContent
,需要使用 {{ Mustache }}
插值。
示例:
<span v-text="msg"></span> <!-- 和下面的一樣 --> <span>{{msg}}</span>
v-text與插值表達式({{}})的區別
v-text會覆蓋元素中原來的內容,但是差值表達式只會替換自己的占位符,不會把整個元素內容清空。
示例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue測試</title> <script src="js/vue.js"></script> </head> <body> <div id="app"> <p>+++{{msg}}---</p> <p v-text="msg">====</p> </div> <script> var vm = new Vue({ el: '#app', data: { msg: '123' } }); </script> </body> </html>
v-html:更新元素的 innerHTML
。注意:內容按普通 HTML 插入 - 不會作為 Vue 模板進行編譯 。如果試圖使用 v-html
組合模板,可以重新考慮是否通過使用組件來替代。
注意:
在網站上動態渲染任意 HTML 是非常危險的,因為容易導致 XSS 攻擊。只在可信內容上使用 v-html
,永不用在用戶提交的內容上。
在單文件組件里,scoped
的樣式不會應用在 v-html
內部,因為那部分 HTML 沒有被 Vue 的模板編譯器處理。如果你希望針對 v-html
的內容設置帶作用域的 CSS,你可以替換為 CSS Modules 或用一個額外的全局 <style>
元素手動設置類似 BEM 的作用域策略。
v-bind:
動態地綁定一個或多個特性,或一個組件 prop 到表達式。
在綁定 class
或 style
特性時,支持其它類型的值,如數組或對象。可以通過下面的教程鏈接查看詳情。
在綁定 prop 時,prop 必須在子組件中聲明。可以用修飾符指定不同的綁定類型。
沒有參數時,可以綁定到一個包含鍵值對的對象。注意此時 class
和 style
綁定不支持數組和對象。
示例:
詳細示例請移步到vue官網:vue
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue測試</title> <script src="js/vue.js"></script> </head> <body> <div id="app"> <p>+++{{msg}}---</p> <p v-text="msg">====</p> <input type="button" value="按鈕" v-bind:title="mytitle"> </div> <script> var vm = new Vue({ el: '#app', data: { msg: '123', mytitle: '這是一個自定義的title' } }); </script> </body> </html>
好玩的跑馬燈效果:
效果圖:
代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue測試</title> <script src="js/vue.js"></script> </head> <body> <div id="app"> <input type="button" value="浪起來" @click="lang"> <input type="button" value="低調" @click="stop"> <p>{{msg}}</p> </div> <script> var vm = new Vue({ el: '#app', data: { msg: '猥瑣發育,別浪····!', time: null }, methods: { lang() { //防止開多個定時器 if (this.time != null) { return } //每隔400毫秒執行一次,讓自己動起來 this.time = setInterval(() => {//箭頭函數內部的this永遠指向箭頭函數外部的this var start = this.msg.substring(0, 1); var end = this.msg.substring(1); this.msg = end + start; }, 400); }, stop() { // 清除定時器 clearInterval(this.time); this.time = null; } } }); </script> </body> </html>
v-for:
公用代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue測試</title> <script src="js/vue.js"></script> </head> <body> <div id="app"> </div> <script> var vm = new Vue({ el: '#app', data: { arryList: ['qq', 'www', 'zz', 'gg'], jsonList: [{ name: '豆豆' }, { name: '香香' }, { name: '七七' }], user: { name: 'ddddd', sex: '男', phone: '15398085656' } } }); </script> </body> </html>
1.迭代數組。
<p v-for="item in arryList">{{item}}</p>
<p v-for="(item,i) in arryList">{{i}}---{{item}}</p>
<p v-for="(item,key) in jsonList">第{{key}}個:name:{{item.name}}</p>
2.迭代對象中的屬性。
<p v-for="(item,key) in user">值:{{item}}--------鍵:{{key}}</p>
<!--注意在遍歷對象身上的鍵值對時,除了(val,key)還有一個索引的位置即(val,key,index)--> <p v-for="(item,key,i) in user">值:{{item}}--------鍵:{{key}}---索引:{{i}}</p>
3.迭代數字。
<!--注意:如果使用v-for迭代數字的話,count值是從1開始的。--> <p v-for="i in 5">{{i}}</p>
注意:
2.2.0+ 的版本里,當在組件中使用 v-for
時,key
現在是必須的。
為何呢?我們來看個示例,大家就明白了。嘻嘻
公用代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue測試</title> <script src="js/vue.js"></script> </head> <body> <div id="app"> <div class="editArry"> <label>id:</label> <input type="text" v-model="id"> <label>name:</label> <input type="text" v-model="name"> <button @click="add">添加</button> </div> <p v-for="item in user"> <input type="checkbox">id:{{item.id}}---name:{{item.name}} </p> </div> <script> var vm = new Vue({ el: '#app', data: { id: '', name: '', user: [{ id: '1', name: '李琪琪' }, { id: '2', name: '小穎穎' }, { id: '3', name: '大黑熊' }] }, methods: { add() { } } }); </script> </body> </html>
沒問題的 add 方法:
add() { var obj = { id: this.id, name: this.name } this.user.push(obj); }
有問題時:
add() { var obj = { id: this.id, name: this.name } this.user.unshift(obj); }
大家會發現每次新增一個后,checkbox的位置就會前移一個,這樣其實是不對的,但當我們加上key
html:
<!--注意:在使用v-for循環時,key的值只能是number或string·--> <!--注意:key在使用的時候,必須使用v-bind屬性綁定的形式,指定key的值·--> <p v-for="item in user" :key="item.id"> <input type="checkbox">id:{{item.id}}---name:{{item.name}} </p>
v-if和v-show
官網:
v-if
是“真正”的條件渲染,因為它會確保在切換過程中條件塊內的事件監聽器和子組件適當地被銷毀和重建。
v-if
也是惰性的:如果在初始渲染時條件為假,則什么也不做——直到條件第一次變為真時,才會開始渲染條件塊。
相比之下,v-show
就簡單得多——不管初始條件是什么,元素總是會被渲染,並且只是簡單地基於 CSS 進行切換。
一般來說,v-if
有更高的切換開銷,而 v-show
有更高的初始渲染開銷。因此,如果需要非常頻繁地切換,則使用 v-show
較好;如果在運行時條件很少改變,則使用 v-if
較好。
v-if的特點:每次都會重新刪除或創建元素。
v-if的缺點:有較高的切換性能消耗。
v-show的特點:每次不會重新進行dom的刪除和創建操作,只是切換了元素的display:none樣式。
v-show的缺點:有較高的初始渲染消耗。
如果元素涉及到頻繁的切換,最好不要使用v-if,如果元素可能永遠也不會被顯示出來被用戶看到,則推薦使用v-if。
使用v-model實現計算器的案例
v-model適用於在表單控件或者組件上創建雙向綁定。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue測試</title> <script src="js/vue.js"></script> </head> <body> <div id="app"> <input type="number" v-model="n1"> <select v-model="opt"> <!--<template v-for="(list,index) in optionList">--> <!--<option :value="list.value">{{list.text}}</option>--> <!--</template>--> <option value="+">+</option> <option value="-">-</option> <option value="*">*</option> <option value="/">/</option> </select> <input type="number" v-model="n2"> <input type="button" value="=" @click="calculation"> <span>{{result}}</span> </div> <script> var vm = new Vue({ el: '#app', data: { n1: 0, opt: '+', n2: 0, result: 0, optionList: [{ value: '+', text: '+' }, { value: '-', text: '-' }, { value: '*', text: '*' }, { value: '/', text: '/' }] }, methods: { calculation() { // switch (this.opt) { // case '+': // this.result = parseInt(this.n1) + parseInt(this.n2); // break; // case '-': // this.result = parseInt(this.n1) - parseInt(this.n2); // break; // case '*': // this.result = parseInt(this.n1) * parseInt(this.n2); // break; // case '/': // this.result = parseInt(this.n1) / parseInt(this.n2); // break; // } // 注意這是投機取巧的方法,實際開發中,盡量少用 var codeStr = 'parseInt(this.n1)' + this.opt + 'parseInt(this.n2)'; this.result = eval(codeStr); } } }); </script> </body> </html>
通過屬性綁定為元素設置class
公用代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue測試</title> <script src="js/vue.js"></script> <style type="text/css"> .red { color: red;; } .thin { font-weight: 200; } .italic { font-style: italic; } .active { letter-spacing: 0.5rem; } </style> </head> <body> <div id="app"> </div> <script> var vm = new Vue({ el: '#app', data: { flag: true } }); </script> </body> </html>
1.數組
<h1 :class="['red','thin']">這是一個很大的h1</h1>
2.數組中使用三元表達式
<h1 :class="['red','thin',flag?'active':'']">這是一個很大的h1</h1>
3.數組中嵌套對象
<h1 :class="['red','thin',{'active':flag}]">這是一個很大的h1</h1>
4.直接使用對象
<body> <div id="app"> <h1 :class="{red:cla1,thin:cla2,italic:cla3,active:flag}">這是一個很大的h1</h1> </div> <script> var vm = new Vue({ el: '#app', data: { cla1: true, cla2: true, cla3: true, flag: true } }); </script> </body>
通過屬性綁定為元素綁定style
1.直接在元素上,通過 :style 形式書寫樣式。
<h1 :style="{color:'red','font-size':'40px'}">這是一個很大的h1</h1>
2.將樣式對象,定義到data中,並直接引用到 :style 中
<h1 :style="h1Style">這是一個很大的h1</h1>
3. 在 :style 中通過數組,引用多個data中的樣式對象。
<h1 :style="[h1Style,h1Style2]">這是一個很大的h1</h1>
事件修飾符的介紹
公用代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue測試</title> <script src="js/vue.js"></script> <style type="text/css"> .div1{ padding: 40px; background-color: pink; } .div2{ height: 200px; background-color: aquamarine; } </style> </head> <body> <div id="app"></div> <script> var vm = new Vue({ el: '#app', data: {}, methods: { div1Click() { console.log('最外層div'); }, div2Click() { console.log('第二層div'); }, btnClick() { console.log('點擊按鈕'); }, aClick(){ console.log('點擊a鏈接'); } } }); </script> </body> </html>
.stop 阻止事件冒泡
<!--.stop阻止事件冒泡--> <div class="div1" @click="div1Click"> <div class="div2" @click="div2Click"> <input type="button" value="按鈕" @click.stop="btnClick"> </div> </div>
點擊兩個div中的按鈕后只執行了 btnClick 事件
不加.stop時
.prevent 阻止默認行為
<a href="https://www.baidu.com" @click.prevent="aClick">有問題找百度</a>
點擊a標簽
頁面不跳轉
.capture
添加事件偵聽器時,使用事件的捕獲模式
<div class="div2" @click.capture="div2Click"> <input type="button" value="按鈕" @click="btnClick"> </div>
點擊按鈕
.self 只出發元素自身的事件
<div class="div1" @click="div1Click"> <div class="div2" @click.self="div2Click"> <input type="button" value="按鈕" @click="btnClick"> </div> </div>
點擊按鈕
.once
事件只觸發一次
<a href="https://www.baidu.com" @click.prevent.once="aClick">有問題找百度</a>
點擊a標簽只有第一次會阻止默認事件,並且觸發a標簽的點擊事件,第二次就不會了阻止默認事件,也不會觸發a標簽的點擊事件。
按鍵修飾符的介紹
用法:
<!-- 同上 --> <input v-on:keyup.enter="submit"> <!-- 縮寫語法 --> <input @keyup.enter="submit">
全部的按鍵別名:
1. .enter
2. .tab
3. .delete (捕獲 刪除 和 退格 鍵)
4. .esc
5. .space
6. .up
7. .down
8. .left
9. .right
小穎就不一一試了,拿 enter 鍵做個示例吧
.enter
代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue測試</title> <script src="js/vue.js"></script> </head> <body> <div id="app"> <div class="editArry"> <label>id:</label> <input type="text" v-model="id"> <label>name:</label> <input type="text" v-model="name" @keyup.enter="add"> <button @click="add">添加</button> </div> <!--注意:在使用v-for循環時,key的值只能是number或string·--> <!--注意:key在使用的時候,必須使用v-bind屬性綁定的形式,指定key的值·--> <p v-for="item in user" :key="item.id"> <input type="checkbox">id:{{item.id}}---name:{{item.name}} </p> </div> <script> var vm = new Vue({ el: '#app', data: { id: '', name: '', user: [{ id: '1', name: '李琪琪' }, { id: '2', name: '小穎穎' }, { id: '3', name: '大黑熊' }] }, methods: { add() { var obj = { id: this.id, name: this.name } this.user.push(obj); } } }); </script> </body> </html>
如何自定義按鍵修飾符呢
示例:
html中調用:
<input type="text" v-model="name" @keyup.f2="add">
js:
Vue.config.keyCodes.f2 = 13;
自定義指令
注意:vue中所有的指令,在調用的時候,都以 v- 開頭
全局
示例:
<div id="app"> <input type="text" v-focus> </div> <script> // 注冊一個全局自定義指令 `v-focus` Vue.directive('focus', { // 當被綁定的元素插入到 DOM 中時…… inserted: function (el) { // 聚焦元素 el.focus() } }); var vm = new Vue({ el: '#app' }); </script>
私有(局部)
示例:
<div id="app"> <input type="text" v-focus> <p v-fontweight="800">{{1+1}}</p> </div> <script> var vm = new Vue({ el: '#app', directives: { focus: { // 指令的定義 inserted: function (el) { el.focus() } }, fontweight: { bind: function (el, binding) { el.style.fontWeight = binding.value; } } } }); </script>