vue 多选自动触发_Vue,初次邂逅(二)
一、前言
二、Vue常用指令
2.1 什么是指令?
指令 (Directives) 是帶有 v- 前綴的特殊特性。指令特性的預期值是:單個 JavaScript 表達式。指令的職責是,當表達式的值改變時,將其產生的連帶影響,響應式地作用于 DOM。 例如我們在入門案例中的v-on,代表綁定事件。
2.2 插值表達式
2.2.1.花括號
格式:
{{表達式}}說明:
- 該表達式支持JS語法,可以調用js內置函數(必須有返回值)
- 表達式必須有返回結果。例如 1 + 1,沒有結果的表達式不允許使用,如:var a = 1 + 1;
- 可以直接獲取Vue實例中定義的數據或函數
示例:
HTML:
<div id="app">{{name}}</div>JS:
var app = new Vue({el:"#app",data:{name:"Jack"} })2.2.2 插值閃爍
使用{{}}方式在網速較慢時會出現問題。在數據未加載完成時,頁面會顯示出原始的{{}},加載完畢后才顯示正確數據,我們稱為插值閃爍。
我們將網速調慢一些,然后試試看剛才的案例:
刷新頁面:
2.2.3 v-text和v-html
使用v-text和v-html指令來替代{{}}
說明:
- v-text:將數據輸出到元素內部,如果輸出的數據有HTML代碼,會作為普通文本輸出
- v-html:將數據輸出到元素內部,如果輸出的數據有HTML代碼,會被渲染
示例:
HTML:
<div id="app">v-text:<span v-text="hello"></span> <br/>v-html:<span v-html="hello"></span> </div>JS:
var vm = new Vue({el:"#app",data:{hello: "<h1>大家好,我是峰哥</h1>"} })效果:
并且不會出現插值閃爍,當沒有數據時,會顯示空白。
2.3 v-model指令
剛才的v-text和v-html可以看做是單向綁定,數據影響了視圖渲染,但是反過來就不行。接下來學習的v-model是雙向綁定,視圖(View)和模型(Model)之間會互相影響。
既然是雙向綁定,一定是在視圖中可以修改數據,這樣就限定了視圖的元素類型。目前v-model的可使用元素有:
- input
- select
- textarea
- checkbox
- radio
- components(Vue中的自定義組件)
基本上除了最后一項,其它都是表單的輸入項。
舉例:
html:
<div id="app"><input type="checkbox" v-model="language" value="Java" />Java<br/><input type="checkbox" v-model="language" value="PHP" />PHP<br/><input type="checkbox" v-model="language" value="Swift" />Swift<br/><h1>你選擇了:{{language.join(',')}}</h1> </div> <script src="./node_modules/vue/dist/vue.js"></script> <script type="text/javascript">var vm = new Vue({el:"#app",data:{language: []}}) </script>- 多個CheckBox對應一個model時,model的類型是一個數組,單個checkbox值默認是boolean類型
- radio對應的值是input的value值
- input 和textarea 默認對應的model是字符串
- select單選對應字符串,多選對應也是數組
效果:
2.4 v-on指令
2.4.1 基本用法
v-on指令用于給頁面元素綁定事件。
語法:
v-on:事件名="js片段或函數名"示例:
<div id="app"><!--事件中直接寫js片段--><button v-on:click="num++">增加一個</button><br/><!--事件指定一個回調函數,必須是Vue實例中定義的函數--><button v-on:click="decrement">減少一個</button><br/><h1>有{{num}}個女神迷戀峰哥</h1> </div> <script src="./node_modules/vue/dist/vue.js"></script> <script type="text/javascript">var app = new Vue({el:"#app",data:{num:100},methods:{decrement(){this.num--;}}}) </script>另外,事件綁定可以簡寫,例如v-on:click='add'可以簡寫為@click='add'
2.4.2 事件修飾符
在事件處理程序中調用 event.preventDefault() 或 event.stopPropagation() 是非常常見的需求。盡管我們可以在方法中輕松實現這點,但更好的方式是:方法只有純粹的數據邏輯,而不是去處理 DOM 事件細節。
為了解決這個問題,Vue.js 為 v-on 提供了事件修飾符。修飾符是由點開頭的指令后綴來表示的。
- .stop :阻止事件冒泡到父元素
- .prevent:阻止默認事件發生
- .capture:使用事件捕獲模式
- .self:只有元素自身觸發事件才執行。(冒泡或捕獲的都不執行)
- .once:只執行一次
阻止默認事件
<div id="app"><!--右擊事件,并阻止默認事件發生--><button v-on:contextmenu.prevent="num++">增加一個</button><br/><!--右擊事件,不阻止默認事件發生--><button v-on:contextmenu="decrement($event)">減少一個</button><br/><h1>有{{num}}個女神迷戀峰哥</h1> </div> <script src="./node_modules/vue/dist/vue.js"></script> <script type="text/javascript">var app = new Vue({el: "#app",data: {num: 100},methods: {decrement(ev) {// ev.preventDefault();this.num--;}}}) </script>效果:(右鍵“增加一個”,不會觸發默認的瀏覽器右擊事件;右鍵“減少一個”,會觸發默認的瀏覽器右擊事件)
2.4.3 按鍵修飾符
在監聽鍵盤事件時,我們經常需要檢查常見的鍵值。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
2.4.4 組合按鈕
可以用如下修飾符來實現僅在按下相應按鍵時才觸發鼠標或鍵盤事件的監聽器。
- .ctrl
- .alt
- .shift
例如:
<!-- Alt + C --> <input @keyup.alt.67="clear"><!-- Ctrl + Click --> <div @click.ctrl="doSomething">Do something</div>三、Vue高級指令
3.1 v-for指令
遍歷數據渲染頁面是非常常用的需求,Vue中通過v-for指令來實現。
3.1.1 遍歷數組
語法:
v-for="item in items"- items:要遍歷的數組,需要在vue的data中定義好。
- item:迭代得到的數組元素的別名
示例
<div id="app"><ul><li v-for="user in users">{{user.name}} - {{user.gender}} - {{user.age}}</li></ul> </div> <script src="./node_modules/vue/dist/vue.js"></script> <script type="text/javascript">var app = new Vue({el: "#app",data: {users:[{name:'柳巖', gender:'女', age: 21},{name:'峰哥', gender:'男', age: 18},{name:'范冰冰', gender:'女', age: 24},{name:'劉亦菲', gender:'女', age: 18},{name:'古力娜扎', gender:'女', age: 25}]},}) </script>效果:
3.1.2 數組角標
在遍歷的過程中,如果我們需要知道數組角標,可以指定第二個參數:
語法
v-for="(item,index) in items"- items:要迭代的數組
- item:迭代得到的數組元素別名
- index:迭代到的當前元素索引,從0開始。
示例
<ul><li v-for="(user, index) in users">{{index + 1}}. {{user.name}} - {{user.gender}} - {{user.age}}</li></ul>效果:
3.1.3 遍歷對象
v-for除了可以迭代數組,也可以迭代對象。語法基本類似
語法:
v-for="value in object" v-for="(value,key) in object" v-for="(value,key,index) in object"- 1個參數時,得到的是對象的屬性
- 2個參數時,第一個是屬性,第二個是鍵
- 3個參數時,第三個是索引,從0開始
示例:
<div id="app"><ul><li v-for="(value, key, index) in user">{{index + 1}}. {{key}} - {{value}}</li></ul> </div> <script src="./node_modules/vue/dist/vue.js"></script> <script type="text/javascript">var vm = new Vue({el:"#app",data:{user:{name:'峰哥', gender:'男', age: 18}}}) </script>效果:
3.1.4 key
當 Vue.js 用 v-for 正在更新已渲染過的元素列表時,它默認用“就地復用”策略。如果數據項的順序被改變,Vue 將不會移動 DOM 元素來匹配數據項的順序, 而是簡單復用此處每個元素,并且確保它在特定索引下顯示已被渲染過的每個元素。
這個功能可以有效的提高渲染的效率。
但是要實現這個功能,你需要給Vue一些提示,以便它能跟蹤每個節點的身份,從而重用和重新排序現有元素,你需要為每項提供一個唯一 key 屬性。理想的 key 值是每項都有的且唯一的 id。
示例:
<ul><li v-for="(item,index) in items" :key=index></li> </ul>- 這里使用了一個特殊語法::key="" 我們后面會講到,它可以讓你讀取vue中的屬性,并賦值給key屬性
- 這里我們綁定的key是數組的索引,應該是唯一的
3.2 v-if指令和v-show指令
3.2.1 基本使用
v-if,顧名思義,條件判斷。當得到結果為true時,所在的元素才會被渲染。
語法:
v-if="布爾表達式"示例:
<div id="app"><button v-on:click="show = !show">點我呀</button><br><h1 v-if="show">看到我啦?!</h1><h1 v-show="show">看到我啦?!show</h1> </div> <script src="./node_modules/vue/dist/vue.js"></script> <script type="text/javascript">var app = new Vue({el: "#app",data: {show: true}}) </script>效果:
3.2.2 與v-for結合
當v-if和v-for出現在一起時,v-for優先級更高。也就是說,會先遍歷,再判斷條件。
修改v-for中的案例,添加v-if:
<ul><li v-for="(user, index) in users" v-if="user.gender == '女'">{{index + 1}}. {{user.name}} - {{user.gender}} - {{user.age}}</li></ul>效果:
只顯示女性用戶信息
3.2.3 v-else
你可以使用 v-else 指令來表示 v-if 的“else 塊”:
<div id="app"><h1 v-if="Math.random() > 0.5">看到我啦?!if</h1><h1 v-else>看到我啦?!else</h1> </div>v-else 元素必須緊跟在帶 v-if 或者 v-else-if 的元素的后面,否則它將不會被識別。
v-else-if,顧名思義,充當 v-if 的“else-if 塊”,可以連續使用:
<div id="app"><button v-on:click="random=Math.random()">點我呀</button><span>{{random}}</span><h1 v-if="random >= 0.75">看到我啦?!if</h1><h1 v-else-if="random > 0.5">看到我啦?!if 0.5</h1><h1 v-else-if="random > 0.25">看到我啦?!if 0.25</h1><h1 v-else>看到我啦?!else</h1> </div> <script src="./node_modules/vue/dist/vue.js"></script> <script type="text/javascript">var app = new Vue({el: "#app",data: {random: 1}}) </script>類似于 v-else,v-else-if 也必須緊跟在帶 v-if 或者 v-else-if 的元素之后。
演示:
3.2.4 v-show
另一個用于根據條件展示元素的選項是 v-show 指令。用法大致一樣:
<h1 v-show="ok">Hello!</h1>不同的是帶有 v-show 的元素始終會被渲染并保留在 DOM 中。v-show 只是簡單地切換元素的 CSS 屬性 display。
示例:
<div id="app"><!--事件中直接寫js片段--><button v-on:click="show = !show">點擊切換</button><br/><h1 v-if="show">你好</h1></div><script src="./node_modules/vue/dist/vue.js"></script><script type="text/javascript">var app = new Vue({el:"#app",data:{show:true}})</script>代碼:
3.3 v-bind指令
html屬性不能使用雙大括號形式綁定,只能使用v-bind指令。
在將 v-bind 用于 class 和 style 時,Vue.js 做了專門的增強。表達式結果的類型除了字符串之外,還可以是對象或數組。
<div id="app"><!--可以是數據模型,可以是具有返回值的js代碼塊或者函數--><div v-bind:title="title" style="border: 1px solid red; width: 50px; height: 50px;"></div> </div> <script src="./node_modules/vue/dist/vue.js"></script> <script type="text/javascript">var app = new Vue({el: "#app",data: {title: "title",}}) </script>效果:
在將 v-bind 用于 class 和 style 時,Vue.js 做了專門的增強。表達式結果的類型除了字符串之外,還可以是對象或數組。
3.3.1 綁定class樣式
數組語法
我們可以借助于v-bind指令來實現:
HTML:
<div id="app"><div v-bind:class="activeClass"></div><div v-bind:class="errorClass"></div><div v-bind:class="[activeClass, errorClass]"></div> </div> <script src="./node_modules/vue/dist/vue.js"></script> <script type="text/javascript">var app = new Vue({el: "#app",data: {activeClass: 'active',errorClass: ['text-danger', 'text-error']}}) </script>渲染后的效果:(具有active和hasError的樣式)
對象語法
我們可以傳給 v-bind:class 一個對象,以動態地切換 class:
<div v-bind:class="{ active: isActive }"></div>上面的語法表示 active 這個 class 存在與否將取決于數據屬性 isActive 的 truthiness(所有的值都是真實的,除了false,0,“”,null,undefined和NaN)。
你可以在對象中傳入更多屬性來動態切換多個 class。此外,v-bind:class 指令也可以與普通的 class 屬性共存。如下模板:
<div class="static"v-bind:class="{ active: isActive, 'text-danger': hasError }"> </div>和如下 data:
data: {isActive: true,hasError: false }結果渲染為:
<div class="static active"></div>active樣式和text-danger樣式的存在與否,取決于isActive和hasError的值。本例中isActive為true,hasError為false,所以active樣式存在,text-danger不存在。
通常情況下,綁定的數據對象不必內聯定義在模板里:
<div class="static" v-bind:class="classObject"></div>數據:
data: {classObject: {active: true,'text-danger': false} }效果和之前一樣:
<div class="static active"></div>3.3.2 綁定style樣式
數組語法
數組語法可以將多個樣式對象應用到同一個元素上:
<div v-bind:style="[baseStyles, overridingStyles]"></div>數據:
data: {baseStyles: {'background-color': 'red'},overridingStyles: {border: '1px solid black'} }渲染后的結果:
<div style="background-color: red; border: 1px solid black;"></div>對象語法
v-bind:style 的對象語法十分直觀——看著非常像 CSS,但其實是一個 JavaScript 對象。CSS 屬性名可以用駝峰式 (camelCase) 或短橫線分隔 (kebab-case,記得用單引號括起來) 來命名:
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>數據:
data: {activeColor: 'red',fontSize: 30 }效果:
<div style="color: red; font-size: 30px;"></div>直接綁定到一個樣式對象通常更好,這會讓模板更清晰:
<div v-bind:style="styleObject"></div> data: {styleObject: {color: 'red',fontSize: '13px'} }效果同上。
3.3.3 簡寫
v-bind:class可以簡寫為:class
3.4 計算屬性
在插值表達式中使用js表達式是非常方便的,而且也經常被用到。
但是如果表達式的內容很長,就會顯得不夠優雅,而且后期維護起來也不方便,例如下面的場景,我們有一個日期的數據,但是是毫秒值:
data:{birthday:1529032123201 // 毫秒值 }我們在頁面渲染,希望得到yyyy-MM-dd的樣式:
<h1>您的生日是:{{new Date(birthday).getFullYear() + '-'+ new Date(birthday).getMonth()+ '-' + new Date(birthday).getDay()}} </h1>雖然能得到結果,但是非常麻煩。
Vue中提供了計算屬性,來替代復雜的表達式:
var vm = new Vue({el:"#app",data:{birthday:1429032123201 // 毫秒值},computed:{birth(){// 計算屬性本質是一個方法,但是必須返回結果const d = new Date(this.birthday);return d.getFullYear() + "-" + d.getMonth() + "-" + d.getDay();}} })- 計算屬性本質就是方法,但是一定要返回數據。然后頁面渲染時,可以把這個方法當成一個變量來使用。
頁面使用:
<div id="app"><h1>您的生日是:{{birth}} </h1></div>效果:
我們可以將同一函數定義為一個方法而不是一個計算屬性。兩種方式的最終結果確實是完全相同的。然而,不同的是計算屬性是基于它們的依賴進行緩存的。計算屬性只有在它的相關依賴發生改變時才會重新求值。這就意味著只要birthday還沒有發生改變,多次訪問 birthday 計算屬性會立即返回之前的計算結果,而不必再次執行函數。
3.5 watch
watch可以讓我們監控一個值的變化。從而做出相應的反應。
示例:
<div id="app"><input type="text" v-model="message"> </div> <script src="./node_modules/vue/dist/vue.js"></script> <script type="text/javascript">var vm = new Vue({el:"#app",data:{message:""},watch:{message(newVal, oldVal){console.log(newVal, oldVal);}}}) </script>效果:
四、Vue組件化
在大型應用開發的時候,頁面可以劃分成很多部分。往往不同的頁面,也會有相同的部分。例如可能會有相同的頭部導航。
但是如果每個頁面都獨自開發,這無疑增加了我們開發的成本。所以我們會把頁面的不同部分拆分成獨立的組件,然后在不同頁面就可以共享這些組件,避免重復開發。
4.1 全局組件
我們通過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}}})var app = new Vue({el:"#app"}) </script>- 組件其實也是一個Vue實例,因此它在定義時也會接收:data、methods、生命周期函數等
- 不同的是組件不會與頁面的元素綁定,否則就無法復用了,因此沒有el屬性。
- 但是組件渲染需要html模板,所以增加了template屬性,值就是HTML模板
- 全局組件定義完畢,任何vue實例都可以直接在HTML中通過組件名稱來使用組件了。
- data必須是一個函數,不再是一個對象。
效果:
4.2 組件的復用
定義好的組件,可以任意復用多次:
<div id="app"><!--使用定義好的全局組件--><counter></counter><counter></counter><counter></counter> </div>效果:
你會發現每個組件互不干擾,都有自己的count值。怎么實現的?
組件的data屬性必須是函數!
當我們定義這個 <counter> 組件時,它的data 并不是像這樣直接提供一個對象:
data: {count: 0 }取而代之的是,一個組件的 data 選項必須是一個函數,因此每個實例可以維護一份被返回對象的獨立的拷貝:
data: function () {return {count: 0} }如果 Vue 沒有這條規則,點擊一個按鈕就會影響到其它所有實例!
4.3 局部注冊
一旦全局注冊,就意味著即便以后你不再使用這個組件,它依然會隨著Vue的加載而加載。
因此,對于一些并不頻繁使用的組件,我們會采用局部注冊。
我們先在外部定義一個對象,結構與創建組件時傳遞的第二個參數一致:
const counter = {template:'<button v-on:click="count++">你點了我 {{ count }} 次,我記住了.</button>',data(){return {count:0}} };然后在Vue中使用它:
var app = new Vue({el:"#app",components:{counter:counter // 將定義的對象注冊為組件} })- components就是當前vue對象子組件集合。
- 其key就是子組件名稱
- 其值就是組件對象的屬性
- 效果與剛才的全局注冊是類似的,不同的是,這個counter組件只能在當前的Vue實例中使用
4.4 組件通信
通常一個單頁應用會以一棵嵌套的組件樹的形式來組織:
- 頁面首先分成了頂部導航、左側內容區、右側邊欄三部分
- 左側內容區又分為上下兩個組件
- 右側邊欄中又包含了3個子組件
各個組件之間以嵌套的關系組合在一起,那么這個時候不可避免的會有組件間通信的需求。
4.4.1 props(父向子傳遞)
父組件使用子組件,并自定義了title屬性:
<div id="app"><h1>打個招呼:</h1><!--使用子組件,同時傳遞title屬性--><introduce title="大家好,我是鋒哥"/> </div> <script src="./node_modules/vue/dist/vue.js"></script> <script type="text/javascript">Vue.component("introduce",{// 直接使用props接收到的屬性來渲染頁面template:'<h1>{{title}}</h1>',props:['title'] // 通過props來接收一個父組件傳遞的屬性})var app = new Vue({el:"#app"}) </script>效果:
4.4.2 props驗證
我們定義一個子組件,并接受復雜數據:
const myList = {template: '<ul><li v-for="item in items" :key="item.id">{{item.id}} : {{item.name}}</li></ul>',props: {items: {type: Array,default: [],required: true}}};- 這個子組件可以對 items 進行迭代,并輸出到頁面。
- props:定義需要從父組件中接收的屬性
- items:是要接收的屬性名稱
- type:限定父組件傳遞來的必須是數組
- default:默認值
- required:是否必須
- items:是要接收的屬性名稱
當 prop 驗證失敗的時候,(開發環境構建版本的) Vue 將會產生一個控制臺的警告。
我們在父組件中使用它:
<div id="app"><h2>傳智播客已開設如下課程:</h2><!-- 使用子組件的同時,傳遞屬性,這里使用了v-bind,指向了父組件自己的屬性lessons --><my-list :items="lessons"/> </div> var app = new Vue({el:"#app",components:{myList // 當key和value一樣時,可以只寫一個},data:{lessons:[{id:1, name: 'java'},{id:2, name: 'php'},{id:3, name: 'ios'},]} })效果:
type類型,可以有:
4.4.3 動態靜態傳遞
給 prop 傳入一個靜態的值:
<introduce title="大家好,我是鋒哥"/>給 prop 傳入一個動態的值: (通過v-bind從數據模型中,獲取title的值)
<introduce :title="title"/>靜態傳遞時,我們傳入的值都是字符串類型的,但實際上任何類型的值都可以傳給一個 props。
<!-- 即便 `42` 是靜態的,我們仍然需要 `v-bind` 來告訴 Vue --> <!-- 這是一個JavaScript表達式而不是一個字符串。--> <blog-post v-bind:likes="42"></blog-post><!-- 用一個變量進行動態賦值。--> <blog-post v-bind:likes="post.likes"></blog-post>4.4.4 子向父的通信
來看這樣的一個案例:
<div id="app"><h2>num: {{num}}</h2><!--使用子組件的時候,傳遞num到子組件中--><counter :num="num"></counter> </div> <script src="./node_modules/vue/dist/vue.js"></script> <script type="text/javascript">Vue.component("counter", {// 子組件,定義了兩個按鈕,點擊數字num會加或減template:'<div><button @click="num++">加</button> <button @click="num--">減</button> </div>',props:['num']// count是從父組件獲取的。})var app = new Vue({el:"#app",data:{num:0}}) </script>- 子組件接收父組件的num屬性
- 子組件定義點擊按鈕,點擊后對num進行加或減操作
我們嘗試運行,好像沒問題,點擊按鈕試試:
子組件接收到父組件屬性后,默認是不允許修改的。怎么辦?
既然只有父組件能修改,那么加和減的操作一定是放在父組件:
var app = new Vue({el:"#app",data:{num:0},methods:{ // 父組件中定義操作num的方法increment(){this.num++;},decrement(){this.num--;}} })但是,點擊按鈕是在子組件中,那就是說需要子組件來調用父組件的函數,怎么做?
我們可以通過v-on指令將父組件的函數綁定到子組件上:
<div id="app"><h2>num: {{num}}</h2><counter :count="num" @inc="increment" @dec="decrement"></counter> </div>在子組件中定義函數,函數的具體實現調用父組件的實現,并在子組件中調用這些函數。當子組件中按鈕被點擊時,調用綁定的函數:
Vue.component("counter", {template:'<div><button @click="plus">加</button> <button @click="reduce">減</button> </div>',props:['count'],methods:{plus(){this.$emit("inc");},reduce(){this.$emit("dec");}}})- vue提供了一個內置的this.$emit()函數,用來調用父組件綁定的函數
效果:
五、尾聲
Vue,初次邂逅(二),完成了。
天天打碼,天天進步!!!
總結
以上是生活随笔為你收集整理的vue 多选自动触发_Vue,初次邂逅(二)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 李宁-2015年7月13日-个人文档
- 下一篇: 无忧开通了博客园博客主页