一.表單基本操作
1. 單選框操作
<head>
<meta charset="utf-8" />
<title>vue特性</title>
</head>
<body>
<!-- 測試 vue input 單選框選中 -->
<div id="app">
<!-- 在vue根據后台數據來選中男女以前基本使用if判斷 -->
<div v-if="gender===1">
<!-- 如果為1讓男選中 -->
<input type="radio" name="" id="man" value="1" checked="checked" />
<label for="man">男</label>
</div>
<div v-else>
<!-- 如果為1讓男選中 -->
<input type="radio" name="" id="man" value="1" />
<label for="man">男</label>
</div>
<div v-if="gender===2">
<!-- 如果為2讓女選中 -->
<input type="radio" name="" id="woman" value="2" checked="checked" />
<label for="woman">女</label>
</div>
<div v-else>
<!--如果不為2讓女不選中 -->
<input type="radio" name="" id="man" value="1" />
<label for="man">女</label>
</div>
<br>
<!-- 使用if判斷會顯得格外的繁瑣 -->
<hr>
<!-- vue通過v-model的雙向綁定的來監控 若 gender的值與該單選框的value的值想等則該
單選框選中,可以試着把value都改為2試試
-->
<input type="radio" name="" id="man" value="1" v-model="gender" />
<label for="man">男</label>
<input type="radio" name="" id="woman" value="2" v-model="gender" />
<label for="woman">女</label>
</div>
<!-- 測試時將gender值切換 -->
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
new Vue({
el: "#app",
data: {
// 假設 存儲的性別為 2 即為女
gender: 2,
}
})
</script>
</body>
2.復選框操作
我們如法炮制寫一下復選框
<body>
<div id="app">
<!-- 定義三組愛好 -->
<input type="checkbox" name="" id="daqiu" value="打球" v-model="hobby" />
<label for="daqiu">打球</label>
<input type="checkbox" name="" id="qiaodaima" value="敲代碼" v-model="hobby" />
<label for="qiaodaima">敲代碼</label>
<input type="checkbox" name="" id="xuexi" value="學習" v-model="hobby" />
<label for="xuexi">學習</label>
</div>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
new Vue({
el: "#app",
data: {
/* 定義復選框 數據時使用數組,與單選框同樣的性質 ,若 hobby
的值有單選框中的value值則選中
*/
hobby: ['打球', '敲代碼']
},
})
</script>
</body>
3.表單修飾符
<body>
<div id="app">
<!--
number 修飾符 type="number" 是html 表單自帶的屬性
在表面上一看其實加不加number都無所謂,其實在獲取表單value
時我們獲取的都是字符串類型,加上了.number會自動轉換為整型(或浮點型)
-->
<input type="number" v-model.number="number" />
<!-- v-model.trim的作用是清除用戶輸入的兩端空格 -->
<input v-model.trim="msg" v-on:focusout="print" />
<br>
<hr />
<p style="color: red;">
.lazy 在更新頁面數據時不會實時更新而是當input失去焦點,回車這些事件時二發生改變下面兩個 表單一個加了.lazy一個沒有加
</p>
<input v-model.lazy="msg">
<input v-model="msg">
<span v-text="msg"></span>
</div>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
new Vue({
el: "#app",
data: {
number: 121 + "212.2",
msg: "定義一個有空格的字符串",
},
methods: {
/* 失去焦點時將msg打印一下
會發現v-model.trim會清空 兩端空格
而普通的v-model 不會
*/
print: function() {
console.log(this.msg);
}
}
})
</script>
</body>
4.自定義指令
Vue.directive自定義全局指令
<body>
<div id="app">
<input type="text" v-focus />
</div>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
// 全局指令在定義時 定義在其他vue實例之外
/*
自定義指令在定義時 如果采用駝峰命名法,例如
定義為 focusF 則在視圖使用時應該 用v-focus-f 這樣使用
如果只是單純的focusf 則用 v-focusf 這樣使用
*/
// 自定義一個全局指令 自動聚焦
Vue.directive('focus', {
inserted: function(el) {
el.focus();
el.placeholder = "自定義自動聚焦指令"
}
});
new Vue({
el: "#app",
})
</script>
</body>
- Vue.directive 注冊全局指令帶參數
<body>
<div id="app">
<div v-color="msg">
</div>
</div>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
// 定義全局帶參指令 v-color
/* 全局變量將 用戶傳入 的數據解析 並賦值給該實例 */
Vue.directive('color', {
//bind - 只調用一次,在指令第一次綁定到元素上時候調用
// binding 為自定義的函數形參 通過自定義屬性傳遞過來的值 存在 binding.value 里面
bind: function(el, binding) {
// 根據指令的參數設置背景色 寬 高
el.style.backgroundColor = binding.value.color;
el.style.width = binding.value.width;
el.style.height = binding.value.height;
}
})
new Vue({
el: "#app",
data: {
// 定義一組樣式數據
msg: {
color: "red",
width: "200px",
height: "200px"
},
}
})
</script>
</body>
- 自定義局部指令
- 局部指令,需要定義在 directives 的選項 用法和全局用法一樣
- 局部指令只能在當前組件里面使用
- 當全局指令和局部指令同名時以局部指令為准
<body>
<div id="app" v-color="msg">
<input type="text" v-focus/>
</div>
<br><br>
<p>
在第二個app1實例中我們同樣使用了v-color指令,當有與v-color是app
中的局部指令所以無法生效,當v-focus卻可以生效
</p>
<div id="app1" v-color="msg">
<input type="text" v-focus/>
</div>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
// 在這里我們定義一個全局組件 它可以在 全局使用
Vue.directive('focus', {
inserted: function(el) {
el.focus();
el.placeholder = "我使用了自定義自動聚焦指令"
}
});
// 創建 第#app 實例
var vm = new Vue({
el: "#app",
data: {
msg: {
color: 'red',
width: "200px",
height: "200px"
},
},
// 在這里我們定義一個 局部指令 它只能在#app組件上使用
directives: {
color: {
bind: function(el, binding) {
// 根據指令的參數設置背景色 寬 高
el.style.backgroundColor = binding.value.color;
el.style.width = binding.value.width;
el.style.height = binding.value.height;
}
}
}
});
new Vue({
el:"#app1",
})
</script>
</body>
二.監聽器和過濾器
1.計算屬性
<body>
<div id="app">
<!--
當多次調用 reverseString 的時候
只要里面的 num 值不改變 他會把第一次計算的結果直接返回
直到data 中的num值改變 計算屬性才會重新發生計算
-->
<div>{{reverseString}}</div>
<div>{{reverseString}}</div>
<!-- 調用methods中的方法的時候 他每次會重新調用 -->
<div>{{reverseMessage()}}</div>
<div>{{reverseMessage()}}</div>
</div>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
/*
計算屬性與方法的區別:計算屬性是基於依賴進行緩存的,而方法不緩存
*/
var vm = new Vue({
el: '#app',
data: {
msg: 'Nihao',
num: 10
},
methods: {
reverseMessage: function() {
console.log('methods')
return this.msg.split('').reverse().join('');
}
},
//computed 屬性 定義 和 data 已經 methods 平級
computed: {
// reverseString 這個是我們自己定義的名字
reverseString: function() {
console.log('computed')
var total = 0;
// 當data 中的 num 的值改變的時候 reverseString 會自動發生計算
for (var i = 0; i <= this.num; i++) {
total += i;
}
// 這里一定要有return 否則 調用 reverseString 的 時候無法拿到結果
return total;
}
}
});
</script>
</body>
2.偵聽器 watch
- 使用watch來響應數據的變化
- 一般用於異步或者開銷較大的操作
- watch 中的屬性 一定是data 中 已經存在的數據
- 當需要監聽一個對象的改變時,普通的watch方法無法監聽到對象內部屬性的改變,只有data中的數據才能夠監聽到變化,此時就需要deep屬性對對象進行深度監聽
<body>
<div id="app">
<p>當 input值發生改變時觸發監聽器 求和</p>
<!-- 定義 兩個 數使用監聽器來 求和 -->
<label for="fristNumber">第一個數</label>
<input type="number" name="" id="fristNumber" v-model.number="fristNumber" />
<label for="lastNumber">第二個數</label>
<input type="number" name="" id="lastNumber" v-model.number="lastNumber" />
<br>兩者之和:{{sum}}
</div>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
new Vue({
el: "#app",
data: {
fristNumber: 21,
lastNumber: 12,
sum: ''
},
// mounted 鈎子函數 在初始化頁面 后執行
mounted: function() {
this.sum = this.fristNumber+this.lastNumber
},
// 監聽器
watch: {
// 第一個數的監聽器 當第一個數改變時,執行方法求和
fristNumber: function(val) {
this.sum = val + this.lastNumber;
},
// 第二個數的監聽器 當第一個數改變時,執行方法求和
lastNumber: function(val) {
this.sum = val + this.fristNumber;
}
}
})
</script>
</body>
3.過濾器
- vue.js允許自定義過濾器
- 過濾器不該變真正的data數據,改變的是渲染頁面的結果
- 全局過濾器使用filter定義,局部使用filters定義,一個不加s一個加s
- 支持級聯
1.全局過濾器
<body>
<div id="app">
<!-- <p>修改input值</p>
<input type="text" name="" id="" v-model="msg"/> -->
<!-- 在msg 渲染頁面時 ,先走了一遍msgFormat這個過濾器以過濾器反復的數據為准 -->
<p>{{msg | msgFormat}}</p>
// 全局 帶參
<p>{{msg | msgFormat2(1,3,5)}}</p>
</div>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
// 定義全局 過濾器
Vue.filter('msgFormat', function(msg) {
//
if (1 === msg) {
return "msg等於1";
} else {
return "msg不等於1";
}
});
<!-- 定義全局帶參過濾器 msg是實例中的msg,...arg是可變參數 -->
Vue.filter("msgFormat2", function(msg, ...arg) {
// 將過濾器傳入的值進行遍歷求和並返回渲染
var sun = 0;
for (var i = 0; i < arg.length; i++) {
sun = sun + arg[i]
}
sun = sun+msg;
return arg.length+"數之和加上msg等於"+sun
});
new Vue({
el: "#app",
data: {
// 設置msg等於1
msg: 1,
}
});
</script>
</body>
2.局部過濾器
<body>
<!--
局部過濾器和全局過濾器很相似 就像局部監聽器監聽器一樣只能
在當前實例中使用,在其他實例中使用不起效果
-->
<div id="app">
<p>{{msg | msgFormat}}</p>
</div>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
new Vue({
el: "#app",
data: {
msg: 1,
},
// 局部過濾器
filters: {
// msgFormat過濾器
msgFormat: function(msg) {
if (msg === 1) {
return "msg的值等於1";
} else {
return "msg的值不等於1";
}
}
}
})
</script>
</body>
三.生命周期和鈎子函數
1.生命周期
- 事物從出生到死亡的過程
- Vue實例從創建 到銷毀的過程 ,這些過程中會伴隨着一些函數的自調用。我們稱這些函數為鈎子函數
2.常用的鈎子函數
beforeCreate | 在實例初始化之后,數據觀測和事件配置之前被調用 此時data 和 methods 以及頁面的DOM結構都沒有初始化 什么都做不了 |
---|---|
created | 在實例創建完成后被立即調用此時data 和 methods已經可以使用 但是頁面還沒有渲染出來 |
beforeMount | 在掛載開始之前被調用 此時頁面上還看不到真實數據 只是一個模板頁面而已 |
mounted | el被新創建的vm.$el替換,並掛載到實例上去之后調用該鈎子。 數據已經真實渲染到頁面上 在這個鈎子函數里面我們可以使用一些第三方的插件 |
beforeUpdate | 數據更新時調用,發生在虛擬DOM打補丁之前。 頁面上數據還是舊的 |
updated | 由於數據更改導致的虛擬DOM重新渲染和打補丁,在這之后會調用該鈎子。 頁面上數據已經替換成最新的 |
beforeDestroy | 實例銷毀之前調用 |
destroyed | 實例銷毀后調用 |
3.鈎子函數使用演示
<body>
<div id="app">
<input v-model="msg" />
<p v-text="msg"></p>
<button type="button" v-on:click="destroyVm">點擊銷毀實例</button>
</div>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
var vm = new Vue({
el: "#app",
data: {
msg: "鈎子函數演示"
},
beforeCreate: function() {
console.log("beforeCreate實例初始化之后調用");
},
created: function() {
console.log("實例創建完成后created被調用");
},
beforeDestroy:function(){
console.log("銷毀之前調用");
},
destroyed:function(){
console.log("銷毀之后調用");
},
methods: {
destroyVm: function() {
alert("實例被銷毀");
// $destroy 銷毀 vm實例銷毀后vm實例將不存在
vm.$destroy();
}
}
});
</script>
</body>
四.vue數組拓展方法
- 在 Vue 中,直接修改對象屬性的值無法觸發響應式。當你直接修改了對象屬性的值,你會發現,只有數據改了,但是頁面內容並沒有改變
- 變異數組方法即保持數組方法原有功能不變的前提下對其進行功能拓展
push() |
往數組最后面添加一個元素,成功返回當前數組的長度 |
---|---|
pop() |
刪除數組的最后一個元素,成功返回刪除元素的值 |
shift() |
刪除數組的第一個元素,成功返回刪除元素的值 |
unshift() |
往數組最前面添加一個元素,成功返回當前數組的長度 |
splice() |
有三個參數,第一個是想要刪除的元素的下標(必選),第二個是想要刪除的個數(必選),第三個是刪除 后想要在原位置替換的值 |
sort() |
sort() 使數組按照字符編碼默認從小到大排序,成功返回排序后的數組 |
reverse() |
reverse() 將數組倒序,成功返回倒序后的數組 |
替換數組
- 不會改變原始數組,但總是返回一個新數組
filter | filter() 方法創建一個新的數組,新數組中的元素是通過檢查指定數組中符合條件的所有元素。 |
---|---|
concat | concat() 方法用於連接兩個或多個數組。該方法不會改變現有的數組 |
slice | slice() 方法可從已有的數組中返回選定的元素。該方法並不會修改數組,而是返回一個子數組 |
動態數組響應式數據
- Vue.set(a,b,c) 讓 觸發視圖重新更新一遍,數據動態起來
- a是要更改的數據 、 b是數據的第幾項、 c是更改后的數據
五.章節小題
- 使用vue完成頁面crud操作
<body>
<!-- 我們定義一個頁面級的增刪查改案例來練習數組的操作 -->
<div id="app" class="tableCard">
<input type="text" v-model="id" disabled="disabled" />
<span>{{name}}</span><input type="text" name="" id="name" value="" v-model="name" />
<button type="button" v-on:click="addList">提交</button>
<table class="tableBody">
<!-- 表頭 -->
<tr>
<th v-for="t in title">
{{t}}
</th>
</tr>
<!-- 主體 -->
<tr v-for="(list,index) in dataList">
<td>{{list.id}}</td>
<td>{{list.name}}</td>
<td>
<a href="#" v-on:click="update(list.id)">修改</a>
<a href="#" v-on:click="deleteData(list.id)">刪除<a>
</td>
</tr>
</table>
<div id="" style="text-align: center;">
總數據量:<span>{{total}}</span>
</div>
</div>
<script src="js/jquery-3.4.1.js" type="text/javascript" charset="utf-8"></script>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
new Vue({
el: "#app",
data: {
flag: false,
name: '',
id: '',
title: ["id", "姓名", "操作"],
dataList: [{
id: 1,
name: "李四"
},
{
id: 2,
name: "王五"
},
{
id: 3,
name: "張飛"
},
{
id: 4,
name: "小喬"
},
]
},
methods: {
// 定義添加 方法
addList: function() {
// 添加
if (this.flag === false) {
var data = {};
// 獲取 addName
data.name = this.name;
// console.log(addName);
// 求添加前數據長度
data.id = this.dataList.length + 1;
// console.log(dataSzie)
// push 操作 往數組最后一個添加數據
this.dataList.push(data);
} else {
// 修改
var list = this.dataList;
for (var i = 0; i <= list.length; i++) {
if (this.id == list[i].id) {
// 遍歷 數據集合 將 對應id的值改為修改后的值
list[i].name = this.name;
break;
}
}
this.flag = false;
/* this.name = '';
this.id = ''; */
}
// 添加 過后清空
this.name = '';
this.id = '';
},
update: function(dataId) {
var list = this.dataList;
for (var i = 0; i <= list.length; i++) {
if (list[i].id == dataId) {
this.id = list[i].id;
this.name = list[i].name;
this.flag = true;
}
}
},
deleteData: function(dataId) {
// 使用過濾器 將 刪除 的數據過濾出去
this.dataList = this.dataList.filter(function(item) {
return item.id != dataId;
});
}
},
computed: {
total: function() {
// 3.1 計算圖書的總數
return this.dataList.length;
}
}
})
</script>
</body>
dmoe下載:https://gitee.com/li_shang_shan/vue-feature-demo
個人學習,內容簡略