品牌案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="../lib/vue.js"></script>
<link rel="stylesheet" href="../lib/bootstrap3.3.7.css">
</head>
<body>
<div id="app">
<!-- 快捷鍵 bs3-panel -->
<!-- 在vue中使用事件綁定機制,爲元素指定處理函數的時候,如果加了小括號,就可以給函數傳參了 -->
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">添加品牌</h3>
</div>
<div class="panel-body form-inline">
<label for="">
ID:
<input type="text" class="form-control" v-model="id">
</label>
<label for="">
Name:
<!-- enter回車鍵 -->
<!-- <input type="text" class="form-control" v-model="name" @keyup.enter="add"> -->
<!-- 系統內置給我們提供了幾個,如果不夠就可以自定義 比如我要按F2添加 -->
<input type="text" class="form-control" v-model="name" @keyup.f2="add">
</label>
<!-- 不傳參數add後面的括號可省略 -->
<input type="button" value="添加" class="btn btn-primary" @click="add">
<label for="">
搜索名稱關鍵字:
<!-- Vue中所有的指令,在調用的時候都以v-開頭,包括自定義 -->
<!-- 如果blue沒有單引號只有雙引號,就是個變量,會在date中找這個變量的值,但是Blue我們是作爲參數傳遞進自定義指令中的,以字符串形式傳遞 -->
<input type="text" class="form-control" v-model="keywords" id="search" v-focus v-color="'blue'">
</label>
</div>
</div>
<table class="table table-bordered table-hover table-striped">
<thead>
<tr>
<th>ID</th>
<th>name</th>
<th>Ctime</th>
<th>Operation</th>
</tr>
</thead>
<tbody>
<!-- 之前v-for中的數據,都是直接從data上的list中直接渲染過來的 現在我們自定義一個search方法,同時
把所有的關鍵字通過傳參的形式傳遞給了search方法-->
<!-- 在search方法內部,通過執行for循環,把所有符合搜索關鍵字的數據,保存到一個新數組中,返回-->
<tr v-for="item in search(keywords)" :key="item.id">
<td>{{item.id}}</td>
<td v-text="item.name">{{item.name}}</td>
<td>{{item.Ctime|dateFormat('')}}</td>
<td>
<!-- 加點擊事件和阻止默認行爲(a標籤會刷新頁面) 括號裏傳參 這個a鏈接屬於for循環內部,所以能訪問到item.id -->
<a href="" @click.prevent="del(item.id)">刪除</a>
</td>
</tr>
</tbody>
</table>
</div>
<div id="app2">
<h3 v-color="'pink'" v-fontweight="900" v-fontsize="'50px'">{{dt|dateFormat}}</h3>
</div>
<script>
//全局的過濾器,進行時間的格式化
//所謂的全局過濾器,就是所有的Vue實例共享的
Vue.filter('dateFormat', function (dateStr, pattern = ' ') {
//根據給定的時間字符串,得到特定的時間
var dt = new Date(dateStr)
var y = dt.getFullYear();
var m = dt.getMonth() + 1;
var d = dt.getDate()
if (pattern && pattern.toLowerCase() === "yyyy-mm-dd") {
return `${y}-${m}-${d}`
} else {
var hh = dt.getHours()
var mm = dt.getMinutes()
var ss = dt.getSeconds()
return `${y}-${m}-${d} ${hh} :${mm}:${ss} `
}
})
//系統內置給我們提供了幾個,如果不夠就可以自定義
// 自定義全局按鍵修飾符 config是配置 keyCodes鍵盤碼
Vue.config.keyCodes.f2 = 113 //113是f2的碼
//定義全局指令,其中參1是指令的名稱,在定義的時候,指令的名稱前面不需要加前綴- 調用的時候必須在指令名稱前加上v-前綴
// 參數2是個對象 這個對象身上有一些指令相關的函數,這個函數可以在特定的階段執行相關的操作
// 在每個函數中,第一個參數永遠是el,表示被綁定了指令的那個元素.這個el參數是一個原生的js對象
Vue.directive('focus', {
bind: function (el) {
// 在元素剛綁定了指令的時候,還沒有插入到DOM中,這時候調用focus方法沒有作用,因爲一個元素只有插入DOM之後,才能獲取焦點
//每當指令綁定到元素上el的時候,會立即執行這個函數,只執行一次
},
inserted: function (el) {
// 表示元素插入到DOM中的時候,執行這個函數,觸發一次
el.focus()
},
update: function (el) {
// 當vNode更新的時候,會執行這個函數,可能會觸發多次
}
})
//自定義一個設置字體的顏色,只要通過指令綁定給了元素,不管這個元素有沒有被插入到頁面中去,這個元素肯定有了內聯的樣式.不需要在Inserted 因爲改變樣式不需要DOM
//和樣式相關的在Bind裏渲染,和js行爲相關的最後在Inserted中取執行,防止js行爲不生效
/*
鉤子函數的參數有:
el: 指令所綁定的元素,可以用來直接操作 DOM 。
binding: 一個對象,包含以下屬性:
name: 指令名,不包括 v- 前綴。
value: 指令的綁定值, 例如: v-my-directive="1 + 1", value 的值是 2。
oldValue: 指令綁定的前一個值,僅在 update 和 componentUpdated 鉤子中可用。無論值是否改變都可用。
expression: 綁定值的表達式或變量名。 例如 v-my-directive="1 + 1" , expression 的值是 "1 + 1"。
arg: 傳給指令的參數。例如 v-my-directive:foo, arg 的值是 "foo"。
modifiers: 一個包含修飾符的對象。 例如: v-my-directive.foo.bar, 修飾符對象 modifiers 的值是 { foo: true, bar: true }。
*/
Vue.directive('color', {
bind: function (el, binding) { //括號裏的是形參,形參名字是什麼都可以
//上面的Input裏的v-color
// el.style.color = 'red';
// console.log(binding.expression);
// console.log(binding.value);
el.style.color = binding.value
},
inserted: function (el) {},
update: function (el) {}
})
var vm = new Vue({
el: "#app",
data: {
id: '',
name: '',
keywords: '', //搜索關鍵字
list: [{
id: 1,
name: '瑪莎拉蒂',
Ctime: new Date()
},
{
id: 2,
name: '保時捷',
Ctime: new Date()
}
]
},
methods: {
add() {
var car = {
id: this.id,
name: this.name,
Ctime: new Date()
};
this.list.push(car);
// 添加完自動清空輸入框的id和name
this.id = this.name = '';
},
del(id) { //爲什麼這裏不寫item.id
//1.數組的some方法
//分析:如果根據ID,找到要刪除的這一項索引,如果找到索引了,直接調用數組的splice方法
//在數組的some方法中,如果return true就立刻終止這個數組的後續循環
// this.list.some((item,i)=>{
// if(item.id==id){
// this.list.splice(i,1)
// }
// return true;
// })
//2.findIndex方法 返回索引
var index = this.list.findIndex(item => {
if (item.id == id) {
return true;
}
})
// console.log(index);
this.list.splice(index, 1);
},
search(keywords) { //根據關鍵字進行數據的搜索
//1.方法一
/* var newList = [];
this.list.forEach(item => {
if (item.name.indexOf(keywords) != -1) {
newList.push(item);
}
})
return newList;*/
//2.方法二 注意:forEach some filter findIndex這些都屬於數組的新方法,都會對數組中的每一項進行遍歷,執行相關的操作,,會有一些差別
//各有各的用法
return this.list.filter(item => {
//ES6的新方法includes 如果包含,返回true,否則返回false
if (item.name.includes(keywords))
return item;
})
}
},
})
var vm2 = new Vue({
//過濾器調用的時候,採用的是就近原則,如果私有過濾器和全局過濾器名稱一致,優先調用私有過濾器
el: "#app2",
data: {
dt: new Date()
},
methods: {},
//定義一個私有的過濾器(局部 )有兩個條件 過濾器名稱和處理函數
filters: {
//定義私有過濾器,過濾器有兩個條件【過濾器名稱和處理函數】
dateFormat: function (dateStr, pattern = ' ') {
//根據給定的時間字符串,得到特定的時間
//padStart(這是補開頭的)爲了使時間不足兩位的不足兩位,比如2月是02,可以使用es6的方法,是字符串獨有的方法,數字不行,所以要把數字轉成字符串
var dt = new Date(dateStr)
var y = dt.getFullYear();
var m = (dt.getMonth() + 1).toString().padStart('2', "0");
var d = (dt.getDate()).toString().padStart('2', "0");
if (pattern && pattern.toLowerCase() === "yyyy-mm-dd") {
return `${y}-${m}-${d}`
} else {
var hh = (dt.getHours()).toString().padStart('2', "0");
var mm = (dt.getMinutes()).toString().padStart('2', "0");
var ss = (dt.getSeconds()).toString().padStart('2', "0");
return `${y}-${m}-${d} ${hh} :${mm}:${ss} ~~~`
}
}
},
//自定義私有指令
directives: {
'fontweight': { //設置字體粗細
bind: function (el, binding) {
el.style.fontWeight = binding.value
}
},
//簡寫方式
//注意:這個function等同於把代碼寫到bind和update裏去
'fontsize': function (el, binding) {
el.style.fontSize = parseInt(binding.value)+'px'//因爲50px是作爲字符串傳過來的,所以要轉成parseint 由於可能傳過來的是50,我們不知道是不是帶px,所以手動加個px
}
}
})
</script>
</body>
</html>
改造後的品牌案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="../lib/vue.js"></script>
<link rel="stylesheet" href="../lib/bootstrap3.3.7.css">
</head>
<body>
<div id="app">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">添加品牌</h3>
</div>
<div class="panel-body form-inline">
<!-- 我們遷移到數據庫 會自動遞增ID,所以不需要寫ID -->
<label for="">
Name:
<input type="text" v-model="name" calss="form-control">
</label>
<input type="button" value="添加" @click="add" class="btn btn-primary">
</div>
</div>
<table class="table table-bordered table-hover table-striped">
<thead>
<tr>
<th>Id</th>
<th>Ctime</th>
<th>Ctime</th>
<th>Operation</th>
</tr>
</thead>
<tbody>
<tr v-for="item in list" :key="item.id">
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.Ctime}}</td>
<td>
<a href="" @click.prevent="del(item.id)">刪除</a>
</td>
</tr>
</tbody>
</table>
</div>
<script>
//如果我們通過全局配置了請求的數據接口 根域名,則在每次單獨發起http的時候,請求的url路徑應該以相對路徑開頭,前面不能帶斜線/,否則不會啓用根路徑做拼接
Vue.http.options.root='http://vue.studyit.io/';
//全局啓用emulateJSON選項 這樣在get或者post等方法中的括號可以刪掉emulateJSON縮短代碼
Vue.http.options.emulateJSON=true;
var vm = new Vue({
el: "#app",
data: {
name: "",
list: [{
id: 1,
name: '瑪莎拉蒂',
Ctime: new Date()
},
{
id: 2,
name: '保時捷',
Ctime: new Date()
}
]
},
created() {
//當vm實例的data和methods初始化完畢後,vm實例會自動執行created這個生命週期函數
this.getAllList()
},
methods: {
getAllList() {
//獲取所有的品牌列表
// 分析:1.由於已經導入了Vue-resource這個包,所以可以直接通過this.$http來發起數據請求
// 2.根據接口API文檔知道獲取列表的時候,應該發起一個get請求
//3.this.$http.get('url').then(function(result){})
//4.當通過then指定回調函數之後 在回調函數中可以拿到數據服務器返回的result
//5.先判斷result.status是否等於0,如果等於0就成功了,可以把result.message賦值給this.list,.如果不等於0,彈框提醒獲取數據失敗
this.$http.get('api/getprodlist').then(result => {
//注意:通過$httml獲取到的數據,都在result.body上放着
var result = result.body
if (result.status === 0) {
this.list = result.message
} else {
alert("獲取數據失敗")
}
})
},
add() {
//添加品牌列表到後臺服務器
//通過查看數據API接口的文檔 要發送一個Post請求
//this.$http.post()中接收三個參數 第一個參數:要請求的URL地址 第二個參數:要提交給服務器的數據,
//要以對象形式提交給服務器{name:this.name}
//第三個參數:是一個配置對象,要以哪種表單數據類型提交過去{emulateJSON:true}以普通表格格式將數據提交給服務器
//在post方法中,使用.then來設置成功的回調函數,如果想要拿到成功的結果,用result.body
this.$http.post('api/addproduct',{name:this.name}).then(result => {
//注意:通過$httml獲取到的數據,都在result.body上放着
var result = result.body
if (result.status === 0) {
//添加完成後,只需要手動再調用以下getAllList就能刷新品牌列表了
this.getAllList()
//清空name
this.name=''
} else {
alert("添加失敗")
}
})
},
del(id){//刪除品牌列表
this.$http.get('api/delproduct'+id).then(result => {
//注意:通過$httml獲取到的數據,都在result.body上放着
var result = result.body
if (result.status === 0) {
//刪除成功
this.getAllList()
} else {
alert("刪除失敗")
}
})
}
}
})
</script>
</body>
</html>