Vue常用特性
表單基本操作
-
獲取單選框中的值
- 通過v-model
<!-- 1乘凸、 兩個單選框需要同時通過v-model 雙向綁定 一個值 2、 每一個單選框必須要有value屬性 且value 值不能一樣 3冀偶、 當(dāng)某一個單選框選中的時候 v-model 會將當(dāng)前的 value值 改變 data 中的 數(shù)據(jù) gender 的值就是選中的值进鸠,我們只需要實時監(jiān)控他的值就可以了 --> <input type="radio" id="male" value="1" v-model='gender'> <label for="male">男</label> <input type="radio" id="female" value="2" v-model='gender'> <label for="female">女</label> <script> new Vue({ data: { // 默認(rèn)會讓當(dāng)前的 value 值為 2 的單選框選中 gender: 2, }, }) </script>
-
獲取復(fù)選框中的值
- 通過v-model
- 和獲取單選框中的值一樣
- 復(fù)選框
checkbox
這種的組合時 data 中的 hobby 我們要定義成數(shù)組 否則無法實現(xiàn)多選
<!-- 1霞幅、 復(fù)選框需要同時通過v-model 雙向綁定 一個值 2司恳、 每一個復(fù)選框必須要有value屬性 且value 值不能一樣 3、 當(dāng)某一個單選框選中的時候 v-model 會將當(dāng)前的 value值 改變 data 中的 數(shù)據(jù) hobby 的值就是選中的值猎塞,我們只需要實時監(jiān)控他的值就可以了 --> <div> <span>愛好:</span> <input type="checkbox" id="ball" value="1" v-model='hobby'> <label for="ball">籃球</label> <input type="checkbox" id="sing" value="2" v-model='hobby'> <label for="sing">唱歌</label> <input type="checkbox" id="code" value="3" v-model='hobby'> <label for="code">寫代碼</label> </div> <script> new Vue({ data: { // 默認(rèn)會讓當(dāng)前的 value 值為 2 和 3 的復(fù)選框選中 hobby: ['2', '3'], }, }) </script>
-
獲取下拉框和文本框中的值
- 通過v-model
<div> <span>職業(yè):</span> <!-- 1比藻、 需要給select 通過v-model 雙向綁定 一個值 2款违、 每一個option 必須要有value屬性 且value 值不能一樣 3、 當(dāng)某一個option選中的時候 v-model 會將當(dāng)前的 value值 改變 data 中的 數(shù)據(jù) occupation 的值就是選中的值请梢,我們只需要實時監(jiān)控他的值就可以了 --> <!-- multiple 多選 --> <select v-model='occupation' multiple> <option value="0">請選擇職業(yè)...</option> <option value="1">教師</option> <option value="2">軟件工程師</option> <option value="3">律師</option> </select> <!-- textarea 是 一個雙標(biāo)簽 不需要綁定value 屬性的 --> <textarea v-model='desc'></textarea> </div> <script> new Vue({ data: { // 默認(rèn)會讓當(dāng)前的 value 值為 2 和 3 的下拉框選中 occupation: ['2', '3'], desc: 'nihao' }, }) </script>
表單修飾符
-
.number 轉(zhuǎn)換為數(shù)值
- 注意點:
- 當(dāng)開始輸入非數(shù)字的字符串時当窗,因為Vue無法將字符串轉(zhuǎn)換成數(shù)值
- 所以屬性值將實時更新成相同的字符串元咙。即使后面輸入數(shù)字,也將被視作字符串简识。
-
.trim 自動過濾用戶輸入的首尾空白字符
- 只能去掉首尾的 不能去除中間的空格
-
.lazy 將input事件切換成change事件
- .lazy 修飾符延遲了同步更新屬性值的時機(jī)陪白。即將原本綁定在 input 事件的同步邏輯轉(zhuǎn)變?yōu)榻壎ㄔ?change 事件上
-
在失去焦點 或者 按下回車鍵時才更新
<!-- 自動將用戶的輸入值轉(zhuǎn)為數(shù)值類型 --> <input v-model.number="age" type="number"> <!--自動過濾用戶輸入的首尾空白字符 --> <input v-model.trim="msg"> <!-- 在“change”時而非“input”時更新 --> <input v-model.lazy="msg" >
自定義指令
- 內(nèi)置指令不能滿足我們特殊的需求
- Vue允許我們自定義指令
Vue.directive 注冊全局指令
<!--
使用自定義的指令拷泽,只需在對用的元素中,加上'v-'的前綴形成類似于內(nèi)部指令'v-if'脂矫,'v-text'的形式。
-->
<input type="text" v-focus>
<script>
// 注意點:
// 1拄轻、 在自定義指令中 如果以駝峰命名的方式定義 如 Vue.directive('focusA',function(){})
// 2、 在HTML中使用的時候 只能通過 v-focus-a 來使用
// 注冊一個全局自定義指令 v-focus
Vue.directive('focus', {
// 當(dāng)綁定元素插入到 DOM 中斧抱。 其中 el為dom元素
inserted: function (el) {
// 聚焦元素
el.focus();
}
});
new Vue({
el:'#app'
});
</script>
Vue.directive 注冊全局指令 帶參數(shù)
<input type="text" v-color='msg'>
<script type="text/javascript">
/*
自定義指令-帶參數(shù)
bind - 只調(diào)用一次,在指令第一次綁定到元素上時候調(diào)用
*/
Vue.directive('color', {
// bind聲明周期, 只調(diào)用一次,指令第一次綁定到元素時調(diào)用弛槐。在這里可以進(jìn)行一次性的初始化設(shè)置
// el 為當(dāng)前自定義指令的DOM元素
// binding 為自定義的函數(shù)形參 通過自定義屬性傳遞過來的值 存在 binding.value 里面
bind: function(el, binding){
// 根據(jù)指令的參數(shù)設(shè)置背景色
// console.log(binding.value.color)
el.style.backgroundColor = binding.value.color;
}
});
var vm = new Vue({
el: '#app',
data: {
msg: {
color: 'blue'
}
}
});
</script>
自定義指令局部指令
- 局部指令慕蔚,需要定義在 directives 的選項 用法和全局用法一樣
- 局部指令只能在當(dāng)前組件里面使用
- 當(dāng)全局指令和局部指令同名時以局部指令為準(zhǔn)
<input type="text" v-color='msg'>
<input type="text" v-focus>
<script type="text/javascript">
/*
自定義指令-局部指令
*/
var vm = new Vue({
el: '#app',
data: {
msg: {
color: 'red'
}
},
//局部指令丐黄,需要定義在 directives 的選項
directives: {
color: {
bind: function(el, binding){
el.style.backgroundColor = binding.value.color;
}
},
focus: {
inserted: function(el) {
el.focus();
}
}
}
});
</script>
計算屬性 computed
- 模板中放入太多的邏輯會讓模板過重且難以維護(hù) 使用計算屬性可以讓模板更加的簡潔
- 計算屬性是基于它們的響應(yīng)式依賴進(jìn)行緩存的
- computed比較適合對多個變量或者對象進(jìn)行處理后返回一個結(jié)果值,也就是數(shù)多個變量中的某一個值發(fā)生了變化則我們監(jiān)控的這個值也就會發(fā)生變化
<div id="app">
<!--
當(dāng)多次調(diào)用 reverseString 的時候
只要里面的 num 值不改變 他會把第一次計算的結(jié)果直接返回
直到data 中的num值改變 計算屬性才會重新發(fā)生計算
-->
<div>{{reverseString}}</div>
<div>{{reverseString}}</div>
<!-- 調(diào)用methods中的方法的時候 他每次會重新調(diào)用 -->
<div>{{reverseMessage()}}</div>
<div>{{reverseMessage()}}</div>
</div>
<script type="text/javascript">
/*
計算屬性與方法的區(qū)別:計算屬性是基于依賴進(jìn)行緩存的孔飒,而方法不緩存
*/
var vm = new Vue({
el: '#app',
data: {
msg: 'Nihao',
num: 100
},
methods: {
reverseMessage: function(){
console.log('methods')
return this.msg.split('').reverse().join('');
}
},
//computed 屬性 定義 和 data 已經(jīng) methods 平級
computed: {
// reverseString 這個是我們自己定義的名字
reverseString: function(){
console.log('computed')
var total = 0;
// 當(dāng)data 中的 num 的值改變的時候 reverseString 會自動發(fā)生計算
for(var i=0;i<=this.num;i++){
total += i;
}
// 這里一定要有return 否則 調(diào)用 reverseString 的 時候無法拿到結(jié)果
return total;
}
}
});
</script>
偵聽器 watch
- 使用watch來響應(yīng)數(shù)據(jù)的變化
- 一般用于異步或者開銷較大的操作
- watch 中的屬性 一定是data 中 已經(jīng)存在的數(shù)據(jù)
- 當(dāng)需要監(jiān)聽一個對象的改變時灌闺,普通的watch方法無法監(jiān)聽到對象內(nèi)部屬性的改變艰争,只有data中的數(shù)據(jù)才能夠監(jiān)聽到變化甩卓,此時就需要deep屬性對對象進(jìn)行深度監(jiān)聽
<div id="app">
<div>
<span>名:</span>
<span>
<input type="text" v-model='firstName'>
</span>
</div>
<div>
<span>姓:</span>
<span>
<input type="text" v-model='lastName'>
</span>
</div>
<div>{{fullName}}</div>
</div>
<script type="text/javascript">
/*
偵聽器
*/
var vm = new Vue({
el: '#app',
data: {
firstName: 'Jim',
lastName: 'Green',
// fullName: 'Jim Green'
},
//watch 屬性 定義 和 data 已經(jīng) methods 平級
watch: {
// 注意: 這里firstName 對應(yīng)著data 中的 firstName
// 當(dāng) firstName 值 改變的時候 會自動觸發(fā) watch
firstName: function(val) {
this.fullName = val + ' ' + this.lastName;
},
// 注意: 這里 lastName 對應(yīng)著data 中的 lastName
lastName: function(val) {
this.fullName = this.firstName + ' ' + val;
}
}
});
</script>
過濾器
- Vue.js允許自定義過濾器弱匪,可被用于一些常見的文本格式化。
- 過濾器可以用在兩個地方:雙花括號插值和v-bind表達(dá)式穷当。
- 過濾器應(yīng)該被添加在JavaScript表達(dá)式的尾部毁习,由“管道”符號指示
- 支持級聯(lián)操作
- 過濾器不改變真正的
data
猜嘱,而只是改變渲染的結(jié)果益楼,并返回過濾后的版本 - 全局注冊時是filter坠陈,沒有s的贮匕。而局部過濾器是filters,是有s的
<div id="app">
<input type="text" v-model='msg'>
<!-- upper 被定義為接收單個參數(shù)的過濾器函數(shù)腥刹,表達(dá)式 msg 的值將作為參數(shù)傳入到函數(shù)中 -->
<div>{{msg | upper}}</div>
<!--
支持級聯(lián)操作
upper 被定義為接收單個參數(shù)的過濾器函數(shù)葫男,表達(dá)式msg 的值將作為參數(shù)傳入到函數(shù)中。
然后繼續(xù)調(diào)用同樣被定義為接收單個參數(shù)的過濾器 lower 丈积,將upper 的結(jié)果傳遞到lower中
-->
<div>{{msg | upper | lower}}</div>
<div :abc='msg | upper'>測試數(shù)據(jù)</div>
</div>
<script type="text/javascript">
// lower 為全局過濾器
Vue.filter('lower', function(val) {
return val.charAt(0).toLowerCase() + val.slice(1);
});
var vm = new Vue({
el: '#app',
data: {
msg: ''
},
//filters 屬性 定義 和 data 已經(jīng) methods 平級
// 定義filters 中的過濾器為局部過濾器
filters: {
// upper 自定義的過濾器名字
// upper 被定義為接收單個參數(shù)的過濾器函數(shù)擒悬,表達(dá)式 msg 的值將作為參數(shù)傳入到函數(shù)中
upper: function(val) {
// 過濾器中一定要有返回值 這樣外界使用過濾器的時候才能拿到結(jié)果
return val.charAt(0).toUpperCase() + val.slice(1);
}
}
});
</script>
過濾器中傳遞參數(shù)
<div id="box">
<!--
filterA 被定義為接收三個參數(shù)的過濾器函數(shù)。
其中 message 的值作為第一個參數(shù)溺忧,
普通字符串 'arg1' 作為第二個參數(shù),表達(dá)式 arg2 的值作為第三個參數(shù)。
-->
{{ message | filterA('arg1', 'arg2') }}
</div>
<script>
// 在過濾器中 第一個參數(shù) 對應(yīng)的是 管道符前面的數(shù)據(jù) n 此時對應(yīng) message
// 第2個參數(shù) a 對應(yīng) 實參 arg1 字符串
// 第3個參數(shù) b 對應(yīng) 實參 arg2 字符串
Vue.filter('filterA',function(n,a,b){
if(n<10){
return n+a;
}else{
return n+b;
}
});
new Vue({
el:"#box",
data:{
message: "哈哈哈"
}
})
</script>
生命周期
- 事物從出生到死亡的過程
- Vue實例從創(chuàng)建 到銷毀的過程 ,這些過程中會伴隨著一些函數(shù)的自調(diào)用。我們稱這些函數(shù)為鉤子函數(shù)
常用的 鉤子函數(shù)
beforeCreate | 在實例初始化之后展融,數(shù)據(jù)觀測和事件配置之前被調(diào)用 此時data 和 methods 以及頁面的DOM結(jié)構(gòu)都沒有初始化 什么都做不了 |
---|---|
created | 在實例創(chuàng)建完成后被立即調(diào)用此時data 和 methods已經(jīng)可以使用 但是頁面還沒有渲染出來 |
beforeMount | 在掛載開始之前被調(diào)用 此時頁面上還看不到真實數(shù)據(jù) 只是一個模板頁面而已 |
mounted | el被新創(chuàng)建的vm.$el替換,并掛載到實例上去之后調(diào)用該鉤子。 數(shù)據(jù)已經(jīng)真實渲染到頁面上 在這個鉤子函數(shù)里面我們可以使用一些第三方的插件 |
beforeUpdate | 數(shù)據(jù)更新時調(diào)用,發(fā)生在虛擬DOM打補(bǔ)丁之前。 頁面上數(shù)據(jù)還是舊的 |
updated | 由于數(shù)據(jù)更改導(dǎo)致的虛擬DOM重新渲染和打補(bǔ)丁,在這之后會調(diào)用該鉤子。 頁面上數(shù)據(jù)已經(jīng)替換成最新的 |
beforeDestroy | 實例銷毀之前調(diào)用 |
destroyed | 實例銷毀后調(diào)用 |
數(shù)組變異方法
- 在 Vue 中,直接修改對象屬性的值無法觸發(fā)響應(yīng)式才避。當(dāng)你直接修改了對象屬性的值劈彪,你會發(fā)現(xiàn)屯曹,只有數(shù)據(jù)改了稿蹲,但是頁面內(nèi)容并沒有改變
- 變異數(shù)組方法即保持?jǐn)?shù)組方法原有功能不變的前提下對其進(jìn)行功能拓展
push() |
往數(shù)組最后面添加一個元素,成功返回當(dāng)前數(shù)組的長度 |
---|---|
pop() |
刪除數(shù)組的最后一個元素歇竟,成功返回刪除元素的值 |
shift() |
刪除數(shù)組的第一個元素长窄,成功返回刪除元素的值 |
unshift() |
往數(shù)組最前面添加一個元素滔吠,成功返回當(dāng)前數(shù)組的長度 |
splice() |
有三個參數(shù),第一個是想要刪除的元素的下標(biāo)(必選)挠日,第二個是想要刪除的個數(shù)(必選)疮绷,第三個是刪除 后想要在原位置替換的值 |
sort() |
sort() 使數(shù)組按照字符編碼默認(rèn)從小到大排序,成功返回排序后的數(shù)組 |
reverse() |
reverse() 將數(shù)組倒序,成功返回倒序后的數(shù)組 |
替換數(shù)組
- 不會改變原始數(shù)組肆资,但總是返回一個新數(shù)組
filter | filter() 方法創(chuàng)建一個新的數(shù)組矗愧,新數(shù)組中的元素是通過檢查指定數(shù)組中符合條件的所有元素。 |
---|---|
concat | concat() 方法用于連接兩個或多個數(shù)組郑原。該方法不會改變現(xiàn)有的數(shù)組 |
slice | slice() 方法可從已有的數(shù)組中返回選定的元素唉韭。該方法并不會修改數(shù)組,而是返回一個子數(shù)組 |
動態(tài)數(shù)組響應(yīng)式數(shù)據(jù)
- Vue.set(a,b,c) 讓 觸發(fā)視圖重新更新一遍犯犁,數(shù)據(jù)動態(tài)起來
- a是要更改的數(shù)據(jù) 属愤、 b是數(shù)據(jù)的第幾項、 c是更改后的數(shù)據(jù)
圖書列表案例
- 靜態(tài)列表效果
- 基于數(shù)據(jù)實現(xiàn)模板效果
- 處理每行的操作按鈕
1酸役、 提供的靜態(tài)數(shù)據(jù)
- 數(shù)據(jù)存放在vue 中 data 屬性中
var vm = new Vue({
el: '#app',
data: {
books: [{
id: 1,
name: '三國演義',
date: ''
},{
id: 2,
name: '水滸傳',
date: ''
},{
id: 3,
name: '紅樓夢',
date: ''
},{
id: 4,
name: '西游記',
date: ''
}]
}
}); var vm = new Vue({
el: '#app',
data: {
books: [{
id: 1,
name: '三國演義',
date: ''
},{
id: 2,
name: '水滸傳',
date: ''
},{
id: 3,
name: '紅樓夢',
date: ''
},{
id: 4,
name: '西游記',
date: ''
}]
}
});
2住诸、 把提供好的數(shù)據(jù)渲染到頁面上
- 利用 v-for循環(huán) 遍歷 books 將每一項數(shù)據(jù)渲染到對應(yīng)的數(shù)據(jù)中
<tbody>
<tr :key='item.id' v-for='item in books'>
<!-- 對應(yīng)的id 渲染到頁面上 -->
<td>{{item.id}}</td>
<!-- 對應(yīng)的name 渲染到頁面上 -->
<td>{{item.name}}</td>
<td>{{item.date}}</td>
<td>
<!-- 阻止 a 標(biāo)簽的默認(rèn)跳轉(zhuǎn) -->
<a href="" @click.prevent>修改</a>
<span>|</span>
<a href="" @click.prevent>刪除</a>
</td>
</tr>
</tbody>
3驾胆、 添加圖書
- 通過雙向綁定獲取到輸入框中的輸入內(nèi)容
- 給按鈕添加點擊事件
- 把輸入框中的數(shù)據(jù)存儲到 data 中的 books 里面
<div>
<h1>圖書管理</h1>
<div class="book">
<div>
<label for="id">
編號:
</label>
<!-- 3.1、通過雙向綁定獲取到輸入框中的輸入的 id -->
<input type="text" id="id" v-model='id'>
<label for="name">
名稱:
</label>
<!-- 3.2贱呐、通過雙向綁定獲取到輸入框中的輸入的 name -->
<input type="text" id="name" v-model='name'>
<!-- 3.3丧诺、給按鈕添加點擊事件 -->
<button @click='handle'>提交</button>
</div>
</div>
</div>
<script type="text/javascript">
/*
圖書管理-添加圖書
*/
var vm = new Vue({
el: '#app',
data: {
id: '',
name: '',
books: [{
id: 1,
name: '三國演義',
date: ''
},{
id: 2,
name: '水滸傳',
date: ''
},{
id: 3,
name: '紅樓夢',
date: ''
},{
id: 4,
name: '西游記',
date: ''
}]
},
methods: {
handle: function(){
// 3.4 定義一個新的對象book 存儲 獲取到輸入框中 書 的id和名字
var book = {};
book.id = this.id;
book.name = this.name;
book.date = '';
// 3.5 把book 通過數(shù)組的變異方法 push 放到 books 里面
this.books.push(book);
//3.6 清空輸入框
this.id = '';
this.name = '';
}
}
});
</script>
4 修改圖書-上
- 點擊修改按鈕的時候 獲取到要修改的書籍名單
- 4.1 給修改按鈕添加點擊事件, 需要把當(dāng)前的圖書的id 傳遞過去 這樣才知道需要修改的是哪一本書籍
- 把需要修改的書籍名單填充到表單里面
- 4.2 根據(jù)傳遞過來的id 查出books 中 對應(yīng)書籍的詳細(xì)信息
- 4.3 把獲取到的信息填充到表單
<div id="app">
<div class="grid">
<div>
<h1>圖書管理</h1>
<div class="book">
<div>
<label for="id">
編號:
</label>
<input type="text" id="id" v-model='id' :disabled="flag">
<label for="name">
名稱:
</label>
<input type="text" id="name" v-model='name'>
<button @click='handle'>提交</button>
</div>
</div>
</div>
<table>
<thead>
<tr>
<th>編號</th>
<th>名稱</th>
<th>時間</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr :key='item.id' v-for='item in books'>
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.date}}</td>
<td>
<!---
4.1 給修改按鈕添加點擊事件奄薇, 需要把當(dāng)前的圖書的id 傳遞過去
這樣才知道需要修改的是哪一本書籍
--->
<a href="" @click.prevent='toEdit(item.id)'>修改</a>
<span>|</span>
<a href="" @click.prevent>刪除</a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<script type="text/javascript">
/*
圖書管理-添加圖書
*/
var vm = new Vue({
el: '#app',
data: {
flag: false,
id: '',
name: '',
books: [{
id: 1,
name: '三國演義',
date: ''
},{
id: 2,
name: '水滸傳',
date: ''
},{
id: 3,
name: '紅樓夢',
date: ''
},{
id: 4,
name: '西游記',
date: ''
}]
},
methods: {
handle: function(){
// 3.4 定義一個新的對象book 存儲 獲取到輸入框中 書 的id和名字
var book = {};
book.id = this.id;
book.name = this.name;
book.date = '';
// 3.5 把book 通過數(shù)組的變異方法 push 放到 books 里面
this.books.push(book);
//3.6 清空輸入框
this.id = '';
this.name = '';
},
toEdit: function(id){
console.log(id)
//4.2 根據(jù)傳遞過來的id 查出books 中 對應(yīng)書籍的詳細(xì)信息
var book = this.books.filter(function(item){
return item.id == id;
});
console.log(book)
//4.3 把獲取到的信息填充到表單
// this.id 和 this.name 通過雙向綁定 綁定到了表單中 一旦數(shù)據(jù)改變視圖自動更新
this.id = book[0].id;
this.name = book[0].name;
}
}
});
</script>
5 修改圖書-下
- 5.1 定義一個標(biāo)識符驳阎, 主要是控制 編輯狀態(tài)下當(dāng)前編輯書籍的id 不能被修改 即 處于編輯狀態(tài)下 當(dāng)前控制書籍編號的輸入框禁用
- 5.2 通過屬性綁定給書籍編號的 綁定 disabled 的屬性 flag 為 true 即為禁用
- 5.3 flag 默認(rèn)值為false 處于編輯狀態(tài) 要把 flag 改為true 即當(dāng)前表單為禁用
- 5.4 復(fù)用添加方法 用戶點擊提交的時候依然執(zhí)行 handle 中的邏輯如果 flag為true 即 表單處于不可輸入狀態(tài) 此時執(zhí)行的用戶編輯數(shù)據(jù)數(shù)據(jù)
<div id="app">
<div class="grid">
<div>
<h1>圖書管理</h1>
<div class="book">
<div>
<label for="id">
編號:
</label>
<!-- 5.2 通過屬性綁定 綁定 disabled 的屬性 flag 為 true 即為禁用 -->
<input type="text" id="id" v-model='id' :disabled="flag">
<label for="name">
名稱:
</label>
<input type="text" id="name" v-model='name'>
<button @click='handle'>提交</button>
</div>
</div>
</div>
<table>
<thead>
<tr>
<th>編號</th>
<th>名稱</th>
<th>時間</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr :key='item.id' v-for='item in books'>
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.date}}</td>
<td>
<a href="" @click.prevent='toEdit(item.id)'>修改</a>
<span>|</span>
<a href="" @click.prevent>刪除</a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<script type="text/javascript">
/*圖書管理-添加圖書*/
var vm = new Vue({
el: '#app',
data: {
// 5.1 定義一個標(biāo)識符, 主要是控制 編輯狀態(tài)下當(dāng)前編輯書籍的id 不能被修改
// 即 處于編輯狀態(tài)下 當(dāng)前控制書籍編號的輸入框禁用
flag: false,
id: '',
name: '',
},
methods: {
handle: function() {
/*
5.4 復(fù)用添加方法 用戶點擊提交的時候依然執(zhí)行 handle 中的邏輯
如果 flag為true 即 表單處于不可輸入狀態(tài) 此時執(zhí)行的用戶編輯數(shù)據(jù)數(shù)據(jù)
*/
if (this.flag) {
// 編輯圖書
// 5.5 根據(jù)當(dāng)前的ID去更新數(shù)組中對應(yīng)的數(shù)據(jù)
this.books.some((item) => {
if (item.id == this.id) {
// 箭頭函數(shù)中 this 指向父級作用域的this
item.name = this.name;
// 完成更新操作之后馁蒂,需要終止循環(huán)
return true;
}
});
// 5.6 編輯完數(shù)據(jù)后表單要處以可以輸入的狀態(tài)
this.flag = false;
// 5.7 如果 flag為false 表單處于輸入狀態(tài) 此時執(zhí)行的用戶添加數(shù)據(jù)
} else {
var book = {};
book.id = this.id;
book.name = this.name;
book.date = '';
this.books.push(book);
// 清空表單
this.id = '';
this.name = '';
}
// 清空表單
this.id = '';
this.name = '';
},
toEdit: function(id) {
/*
5.3 flag 默認(rèn)值為false 處于編輯狀態(tài) 要把 flag 改為true 即當(dāng)前表單為禁 用
*/
this.flag = true;
console.log(id)
var book = this.books.filter(function(item) {
return item.id == id;
});
console.log(book)
this.id = book[0].id;
this.name = book[0].name;
}
}
});
</script>
6 刪除圖書
- 6.1 給刪除按鈕添加事件 把當(dāng)前需要刪除的書籍id 傳遞過來
- 6.2 根據(jù)id從數(shù)組中查找元素的索引
- 6.3 根據(jù)索引刪除數(shù)組元素
<tbody>
<tr :key='item.id' v-for='item in books'>
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.date}}</td>
<td>
<a href="" @click.prevent='toEdit(item.id)'>修改</a>
<span>|</span>
<!-- 6.1 給刪除按鈕添加事件 把當(dāng)前需要刪除的書籍id 傳遞過來 -->
<a href="" @click.prevent='deleteBook(item.id)'>刪除</a>
</td>
</tr>
</tbody>
<script type="text/javascript">
/*
圖書管理-添加圖書
*/
var vm = new Vue({
methods: {
deleteBook: function(id){
// 刪除圖書
#// 6.2 根據(jù)id從數(shù)組中查找元素的索引
// var index = this.books.findIndex(function(item){
// return item.id == id;
// });
#// 6.3 根據(jù)索引刪除數(shù)組元素
// this.books.splice(index, 1);
// -------------------------
#// 方法二:通過filter方法進(jìn)行刪除
# 6.4 根據(jù)filter 方法 過濾出來id 不是要刪除書籍的id
# 因為 filter 是替換數(shù)組不會修改原始數(shù)據(jù) 所以需要 把 不是要刪除書籍的id 賦值給 books
this.books = this.books.filter(function(item){
return item.id != id;
});
}
}
});
</script>
常用特性應(yīng)用場景
1 過濾器
- Vue.filter 定義一個全局過濾器
<tr :key='item.id' v-for='item in books'>
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<!-- 1.3 調(diào)用過濾器 -->
<td>{{item.date | format('yyyy-MM-dd hh:mm:ss')}}</td>
<td>
<a href="" @click.prevent='toEdit(item.id)'>修改</a>
<span>|</span>
<a href="" @click.prevent='deleteBook(item.id)'>刪除</a>
</td>
</tr>
<script>
#1.1 Vue.filter 定義一個全局過濾器
Vue.filter('format', function(value, arg) {
function dateFormat(date, format) {
if (typeof date === "string") {
var mts = date.match(/(\/Date\((\d+)\)\/)/);
if (mts && mts.length >= 3) {
date = parseInt(mts[2]);
}
}
date = new Date(date);
if (!date || date.toUTCString() == "Invalid Date") {
return "";
}
var map = {
"M": date.getMonth() + 1, //月份
"d": date.getDate(), //日
"h": date.getHours(), //小時
"m": date.getMinutes(), //分
"s": date.getSeconds(), //秒
"q": Math.floor((date.getMonth() + 3) / 3), //季度
"S": date.getMilliseconds() //毫秒
};
format = format.replace(/([yMdhmsqS])+/g, function(all, t) {
var v = map[t];
if (v !== undefined) {
if (all.length > 1) {
v = '0' + v;
v = v.substr(v.length - 2);
}
return v;
} else if (t === 'y') {
return (date.getFullYear() + '').substr(4 - all.length);
}
return all;
});
return format;
}
return dateFormat(value, arg);
})
#1.2 提供的數(shù)據(jù) 包含一個時間戳 為毫秒數(shù)
[{
id: 1,
name: '三國演義',
date: 2525609975000
},{
id: 2,
name: '水滸傳',
date: 2525609975000
},{
id: 3,
name: '紅樓夢',
date: 2525609975000
},{
id: 4,
name: '西游記',
date: 2525609975000
}];
</script>
2 自定義指令
- 讓表單自動獲取焦點
- 通過Vue.directive 自定義指定
<!-- 2.2 通過v-自定義屬性名 調(diào)用自定義指令 -->
<input type="text" id="id" v-model='id' :disabled="flag" v-focus>
<script>
# 2.1 通過Vue.directive 自定義指定
Vue.directive('focus', {
inserted: function (el) {
el.focus();
}
});
</script>
3 計算屬性
- 通過計算屬性計算圖書的總數(shù)
- 圖書的總數(shù)就是計算數(shù)組的長度
<div class="total">
<span>圖書總數(shù):</span>
<!-- 3.2 在頁面上 展示出來 -->
<span>{{total}}</span>
</div>
<script type="text/javascript">
/*
計算屬性與方法的區(qū)別:計算屬性是基于依賴進(jìn)行緩存的呵晚,而方法不緩存
*/
var vm = new Vue({
data: {
flag: false,
submitFlag: false,
id: '',
name: '',
books: []
},
computed: {
total: function(){
// 3.1 計算圖書的總數(shù)
return this.books.length;
}
},
});
</script>