Vue.js 基礎入門(二)
1. 品牌管理案例
實現功能:
- 新增新品牌:
add
- 刪除品牌:陣列迴圈,根據 ID 查詢索引,呼叫
splice
方法刪除 - 根據品牌名過濾:陣列迴圈
- 格式化時間:過濾器
- 時間補全:
padStart()
, ES6 新增, 如:2020-2-6
補全後為2020-02-06
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <link rel="stylesheet" href="./lib/bootstrap-3.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"> <label> Id: <input type="text" class="form-control" v-model="id"> </label> <label> Name: <input type="text" class="form-control" v-model="name"> </label> <!-- 在Vue中,使用事件繫結機制,為元素指定處理函式的時候,如果加了小括號,就可以給函式傳參了 --> <input type="button" value="新增" class="btn btn-primary" @click="add()"> <label> 搜尋名稱關鍵字: <input type="text" class="form-control" v-model="keywords"> </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> <tr v-for="item in search(keywords)"> <td>{{ item.id }}</td> <td v-text="item.name"></td> <td>{{ item.ctime | dateFormat() }}</td> <td> <a href="/" @click.prevent="del(item.id)">刪除</a> </td> </tr> </tbody> </table> </div> <script src="./lib/vue-2.4.0.js"></script> <script> // 自定義過濾器 Vue.filter('dateFormat', function(dateStr, pattern = "") { 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.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}` } }) 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 newData = { id: this.id, name: this.name, ctime: new Date() }; this.list.push(newData); this.id = this.name = '' }, del(id) { // 根據 id 查詢陣列索引,再根據索引刪除元素 var index = this.list.findIndex(item => { if (item.id === id) { return true; } }) this.list.splice(index, 1) }, search(keywords) { // 根據關鍵字搜尋 // var newList = [] // this.list.forEach(item => { // if (item.name.indexOf(keywords) != -1) { // newList.push(item) // } // }) // return newList // ES6 中 String.prototype.includes('要包含的字串') return this.list.filter(item => { if (item.name.includes(keywords)) { return item } }) } } }) </script> </body> </html>
2. 過濾器
過濾器定義語法:
Vue.filter('過濾器的名稱', function(引數一, 引數二...){})
過濾器中的 function
,第一個引數,永遠都是過濾器管道符前面傳遞過來的資料。
使用:
{{ name | 過濾器的名稱 }}
2.1 全域性過濾器
<td>{{ item.ctime | dateFormat() }}</td> // 自定義過濾器 Vue.filter('dateFormat', function(dateStr, pattern = "") { 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.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}` } }) // Vue 例項 var vm = new Vue({ })
Tips:全域性過濾器在全域性 Vue 例項中使用
2.1 私有過濾器
私有過濾器在 Vue
例項中定義:
<div id="app2"> <h3>{{ dt | dateFormat }}</h3> </div> <script src="./lib/vue-2.4.0.js"></script> <script> // 自定義過濾器 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.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}` } }) var vm2 = new Vue({ el: '#app2', data: { dt: new Date() }, filters: { dateFormat: function (dateStr, pattern = '') { var dt = new Date(dateStr) var y = dt.getFullYear() var m = dt.getMonth() + 1 var d = dt.getDate() if (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}~~~` } } } }) </script>
Tips:若私有過濾器與全域性過濾器名字一致,則採取就近原則,即使用私有過濾器!
3. 鍵盤修飾符和自定義鍵盤修飾符
全部按鍵別名:enter、tab、delete(捕獲刪除和退格)、esc、up、down、left、right、ctrl、alt、shift、meta
// 回車觸發 add 事件
<input type="text" class="form-control" v-model="name" v-on:keyup.13="add">
// 簡寫 使用 keycode
<input type="text" class="form-control" v-model="name" @keyup.13="add">
// 或者使用按鍵別名
<input type="text" class="form-control" v-model="name" @keyup.enter="add">
自定義按鍵修飾符
我們自己也可以自定義按鍵修飾符,便於記憶。
// 配置,
Vue.config.keyCodes.f2 = 113;
// 使用
<input type="text" v-model="name" @keyup.f2="add">
參考文件:
- js 裡面的鍵盤事件對應的鍵碼:
https://www.cnblogs.com/wuhua1/p/6686237.html
4. 自定義指令
4.1 自定義全域性指令
語法:
// 引數一:指令名稱,定義時名稱前面不需要加 v-,但是在 html 中使用時,需要加 v- 的字首來呼叫
// 引數二:為一個物件,裡面可以配置一些指令相關的函式,這些函式在特定的階段,執行相關操作
// 常見的有 bind、inserted、updated
Vue.directive('指令名稱', {
// el 為被繫結指令的元素,為一個原生的 js 物件,因此可以進行一些 js 方面的操作
bind: function(el){
// 當指令繫結到元素上時,會立即執行,執行一次
},
inserted: function(el){
// 元素插入的 DOM 中時,會執行 inserted 函式,觸發一次
},
uodated: function(el) {
// 當VNode 更新的時候,會執行 updated,可能會觸發多次
}
})
何時用 bind、inserted 和 updated
- 與 JS 行為相關的操作,最好使用
inserted
中執行,放置 JS行為不生效 - 與樣式相關的操作,一般都可以在
bind
執行
示例一:
初始化頁面時,給搜尋框獲取焦點:
<div id="app">
<label>
搜尋名稱關鍵字:
<input type="text" class="form-control" v-model="keywords" v-focus>
</label>
</div>
<script src="./lib/vue-2.4.0.js"></script>
<script>
// 自定義全域性指令
Vue.directive('focus', {
bind: function(el) {},
inserted: function(el) {
el.focus()
},
updated: function(el) {}
})
var vm = new Vue({
el: '#app'
})
</script>
4.2 區域性自定義指令
<body>
<div id="app">
<label for="fo">頁面載入時自動聚焦</label>
<input v-focus id="fo"/>
</div>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.js"></script>
<script>
Vue.directive('focus', {
inserted: function(el) {
el.focus()
}
})
var vm = new Vue({
el: '#app',
// 區域性定義
directives: ('focus', {
inserted: function(el) {
el.focus()
}
})
})
</script>
</body>
4.3. 鉤子函式
指令定義函式提供了幾個鉤子函式(可選):
- bind: 只調用一次,指令第一次繫結到元素時呼叫,用這個鉤子函式可以定義一個在繫結時執行一次的初始化動作。
- inserted: 被繫結元素插入父節點時呼叫(父節點存在即可呼叫,不必存在於 document 中)。
- update: 被繫結元素所在的模板更新時呼叫,而不論繫結值是否變化。通過比較更新前後的繫結值,可以忽略不必要的模板更新(詳細的鉤子函式引數見下)。
- componentUpdated: 被繫結元素所在模板完成一次更新週期時呼叫。
- unbind: 只調用一次, 指令與元素解綁時呼叫。
鉤子函式引數
- 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 }。
- vnode: Vue 編譯生成的虛擬節點。
- oldVnode: 上一個虛擬節點,僅在 update 和 componentUpdated 鉤子中可用。
示例二:
自定義一個 設定字型顏色的 指令:
<div id="app">
<label>
搜尋名稱關鍵字:
<!-- <input type="text" class="form-control" v-model="keywords" v-focus v-color> -->
<input type="text" class="form-control" v-model="keywords" v-focus v-color="'red'">
</label>
</div>
<script src="./lib/vue-2.4.0.js"></script>
<script>
// 自定義全域性指令:顏色
Vue.directive('color', {
bind: function(el, binding) {
// el.style.color = 'red'
el.style.color = binding.value // 使用指令繫結的值
}
})
var vm = new Vue({
el: '#app'
})
</script>
4.4 函式簡寫
在很多時候,你可能想在 bind
和 update
時觸發相同行為,而不關心其它的鉤子。比如這樣寫:
Vue.directive('color-swatch', function (el, binding) {
el.style.backgroundColor = binding.value
})
示例三:
<div id="app2">
<h3 v-fontsize="50">{{ dt | dateFormat }}</h3>
</div>
<script>
// 自定義全域性指令,獲取焦點
Vue.directive('focus', {
bind: function(el) {},
inserted: function(el) {
el.focus()
},
updated: function(el) {}
})
// 自定義全域性指令:顏色
Vue.directive('color', {
bind: function(el, binding) {
el.style.color = binding.value
}
})
var vm2 = new Vue({
el: '#app2',
data: {
dt: new Date()
},
directives: {
'fontsize': function(el, binding) {
el.style.fontSize = parseInt(binding.value) + 'px'
}
}
})
</script>
5. vue例項的生命週期
什麼是生命週期:從Vue例項建立、執行、到銷燬期間,總是伴隨著各種各樣的事件,這些事件,統稱為生命週期!
宣告週期鉤子函式
即在生命週期內發生的事件,以下為所有鉤子函式:
- 建立期間的生命週期函式:
beforeCreate
:例項剛在記憶體中被創建出來,此時,還沒有初始化好 data 和 methods 屬性created
:例項已經在記憶體中建立OK,此時 data 和 methods 已經建立OK,此時還沒有開始 編譯模板beforeMount
:此時已經完成了模板的編譯,但是還沒有掛載到頁面中mounted
:此時,已經將編譯好的模板,掛載到了頁面指定的容器中顯示
- 執行期間的生命週期函式:
beforeUpdate
:狀態更新之前執行此函式, 此時 data 中的狀態值是最新的,但是介面上顯示的 資料還是舊的,因為此時還沒有開始重新渲染DOM節點updated
:例項更新完畢之後呼叫此函式,此時 data 中的狀態值 和 介面上顯示的資料,都已經完成了更新,介面已經被重新渲染好了!
- 銷燬期間的生命週期函式:
beforeDestroy
:例項銷燬之前呼叫。在這一步,例項仍然完全可用destroyed
:Vue 例項銷燬後呼叫。呼叫後,Vue 例項指示的所有東西都會解繫結,所有的事件監聽器會被移除,所有的子例項也會被銷燬。
示例
<body>
<div id="app">
<input type="button" value="修改msg" @click="msg='No'">
<h3 id="h3">{{ msg }}</h3>
</div>
<script src="./lib/vue-2.4.0.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
msg: 'Hello'
},
methods: {
show() {
console.log('函式 show')
}
},
beforeCreate() {
// 例項建立之前觸發
// 在 beforeCreate 生命週期函式執行的時候,data 和 methods 中的 資料都還沒有沒初始化
// console.log(this.msg)
// this.show()
},
created() {
// 例項建立後觸發
// 在 created 中,data 和 methods 都已經被初始化好了!
// 如果要呼叫 methods 中的方法,或者操作 data 中的資料,最早,只能在 created 中操作
// console.log(this.msg)
// this.show()
},
beforeMount() {
// 掛載之前觸發
// 模板已經在記憶體中編輯完成了,但是尚未把 模板渲染到 頁面中
// 在 beforeMount 執行的時候,頁面中的元素,還沒有被真正替換過來,只是之前寫的一些模板字串
// console.log(document.getElementById('h3').innerText) // {{ msg }}
},
mounted() {
// 模板掛載後觸發
// 記憶體中的模板,已經真實的掛載到了頁面中,使用者已經可以看到渲染好的頁面了
// mounted 是 例項建立期間的最後一個生命週期函式,當執行完 mounted 就表示,例項已經被完全建立好了,
// 此時,如果沒有其它操作的話,這個例項,就靜靜的 躺在我們的記憶體中,一動不動
// console.log(document.getElementById('h3').innerText) // Hello
},
// 執行中生命週期鉤子函式
// 以下兩個鉤子函式,當 data 發生改變時才會觸發,msg 內容原本為 Hello,當點選後變為 No
beforeUpdate() {
// 模板掛載完畢,只有當 data 發生改變時才會觸發
// 當執行 beforeUpdate 的時候,頁面中的顯示的資料,還是舊的,此時 data 資料是最新的,頁面尚未和 最新的資料保持同步
// console.log('介面上元素的內容:' + document.getElementById('h3').innerText) // No
// console.log('data 中的 msg 資料是:' + this.msg) // No
},
updated() {
// 模板掛載完畢,只有當 data 發生改變時才會出發
// updated 事件執行的時候,頁面和 data 資料已經保持同步了,都是最新的
console.log('介面上元素的內容:' + document.getElementById('h3').innerText) // No
console.log('data 中的 msg 資料是:' + this.msg) // No
}
})
</script>
</body>
參考文件:
6. vue-resource
Vue
要實現非同步載入需要使用到 vue-resource
庫。Vue.js 2.0
版本推薦使用 axios
來完成 ajax
請求。
6.1 GET 請求
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue-Resource</title>
<script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
<script src="https://cdn.staticfile.org/vue-resource/1.5.1/vue-resource.min.js"></script>
</head>
<body>
<div id="box">
<input type="button" @click="get" value="點我非同步獲取資料(Get)">
</div>
<script type = "text/javascript">
window.onload = function(){
var vm = new Vue({
el:'#box',
data:{
msg:'Hello World!',
},
methods:{
get() {
//傳送get請求
this.$http.get('/try/ajax/ajax_info.txt').then(function(res){
document.write(res.body);
},function(){
console.log('請求失敗處理');
});
}
}
});
}
</script>
</body>
</html>
如果需要傳遞資料,可以使用 this.$http.get('get.php',{params : jsonData})
格式,第二個引數 jsonData
就是傳到後端的資料。
this.$http.get('get.php',{params : {a:1,b:2}}).then(function(res){
document.write(res.body);
},function(res){
console.log(res.status);
});
6.2 POST 請求
post
傳送資料到後端,需要第三個引數 {emulateJSON:true}
。emulateJSON
的作用: 如果 Web
伺服器無法處理編碼為 application/json
的請求,你可以啟用 emulateJSON
選項。
<body>
<div id="box">
<input type="button" @click="post" value="點我非同步獲取資料(Post)">
</div>
<script type = "text/javascript">
window.onload = function(){
var vm = new Vue({
el:'#box',
data:{
msg:'Hello World!',
},
methods:{
post(){
//傳送 post 請求
this.$http.post('/try/ajax/demo_test_post.php',{name:"POST 請求",url:"http://www.runoob.com"},{emulateJSON:true}).then(function(res){
document.write(res.body);
},function(res){
console.log(res.status);
});
}
}
});
}
</script>
</body>
語法 & API
既可以全域性物件方式傳送請求,也可以在一個 vue
例項中傳送請求,使用方式如下:
// 基於全域性Vue物件使用http
Vue.http.get('/someUrl', [options]).then(successCallback, errorCallback);
Vue.http.post('/someUrl', [body], [options]).then(successCallback, errorCallback);
// 在一個Vue例項內使用$http
this.$http.get('/someUrl', [options]).then(successCallback, errorCallback);
this.$http.post('/someUrl', [body], [options]).then(successCallback, errorCallback);
七種 REST 風格的請求方式:
get(url, [options])
head(url, [options])
delete(url, [options])
jsonp(url, [options])
post(url, [body], [options])
put(url, [body], [options])
patch(url, [body], [options])
options 引數
引數 | 型別 | 描述 |
---|---|---|
url | string | 請求的目標URL |
body | Object, FormData, string | 作為請求體傳送的資料 |
headers | Object | 作為請求頭部發送的頭部物件 |
params | Object | 作為URL引數的引數物件 |
method | string | HTTP方法 (例如GET,POST,...) |
timeout | number | 請求超時(單位:毫秒) (0表示永不超時) |
before | function(request) | 在請求傳送之前修改請求的回撥函式 |
progress | function(event) | 用於處理上傳進度的回撥函式 ProgressEvent |
credentials | boolean | 是否需要出示用於跨站點請求的憑據 |
emulateHTTP | boolean | 是否需要通過設定X-HTTP-Method-Override頭部並且以傳統POST方式傳送PUT,PATCH和DELETE請求。 |
emulateJSON | boolean | 設定請求體的型別為application/x-www-form-urlencoded |
響應
1、屬性:
屬性 | 型別 | 描述 |
---|---|---|
url | string | 響應的 URL 源 |
body | Object, Blob, string | 響應體資料 |
headers | Header | 請求頭部物件 |
ok | boolean | 當 HTTP 響應碼為 200 到 299 之間的數值時該值為 true |
status | number | HTTP 響應碼 |
statusText | string | HTTP 響應狀態 |
2、方法:
方法 | 型別 | 描述 |
---|---|---|
text() | 約定值 | 以字串方式返回響應體 |
json() | 約定值 | 以格式化後的 json 物件方式返回響應體 |
blob() | 約定值 | 以二進位制 Blob 物件方式返回響應體 |
6.3 JSONP 請求
JSONP的實現原理
- 由於瀏覽器的安全性限制,不允許AJAX訪問 協議不同、域名不同、埠號不同的 資料介面,瀏覽器認為這種訪問不安全;
- 可以通過動態建立script標籤的形式,把script標籤的src屬性,指向資料介面的地址,因為script標籤不存在跨域限制,這種資料獲取方式,稱作JSONP(注意:根據JSONP的實現原理,知曉,JSONP只支援Get請求)
具體實現過程
- 先在客戶端定義一個回撥方法,預定義對資料的操作
- 再把這個回撥方法的名稱,通過URL傳參的形式,提交到伺服器的資料介面;
- 伺服器資料介面組織好要傳送給客戶端的資料,再拿著客戶端傳遞過來的回撥方法名稱,拼接出一個呼叫這個方法的字串,傳送給客戶端去解析執行
- 客戶端拿到伺服器返回的字串之後,當作Script指令碼去解析執行,這樣就能夠拿到JSONP的資料了
<body>
<div id="app">
<input type="button" value="jsonp請求" @click="jsonpInfo">
</div>
<script>
// 建立 Vue 例項,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {},
methods: {
jsonpInfo() { // 發起JSONP 請求
this.$http.jsonp('http://vue.studyit.io/api/jsonp').then(result => {
console.log(result.body)
})
}
}
});
</script>
</body>
Node.js 伺服器示例
1、app.js
// 匯入 http 內建模組
const http = require('http')
const urlModule = require('url')
// 建立一個 http 伺服器
const server = http.createServer()
// 監聽 http 伺服器的 request 請求
server.on('request', function (req, res) {
const { pathname: url, query } = urlModule.parse(req.url, true)
if (url === '/getscript') {
// 拼接一個合法的 JS 指令碼,拼接的是一個方法的呼叫
var data = {
name: 'rose',
age: 18,
gender: '女',
phone: '18674447633'
}
var scriptStr = `${query.callback}(${JSON.stringify(data)})`
// res.end 傳送給客戶端,客戶端將這個字串當前 JS 程式碼去解析執行
res.end(scriptStr)
} else {
res.end('404')
}
})
// 指定埠號並啟動伺服器監聽
server.listen(3000, function () {
console.log('server listen at http://127.0.0.1:3000')
})
執行 node app.js
執行 node 伺服器。
2、client.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<input type="button" value="get 請求" @click="getinfo">
</div>
<script src="./lib/vue-2.4.0.js"></script>
<script src="https://cdn.staticfile.org/vue-resource/1.5.1/vue-resource.min.js"></script>
<script>
var vm = new Vue({
el: '#app',
methods: {
getinfo() {
// get 請求
this.$http.get('http://vue.studyit.io/api/getlunbo').then(function (result) {
console.log(result)
})
}
}
})
</script>
</body>
</html>
7. 配置本地資料庫和資料介面 API
品牌管理案例改造
- 獲取介面:
http://www.liulongbin.top:3005/api/getprodlist
- 新增介面:
http://www.liulongbin.top:3005/api/addproduct
- 刪除介面:
http://www.liulongbin.top:3005/api/delproduct/id
API 介面
1、獲取品牌資料
- 請求方式:get
- 返回資料格式:json
- 請求引數:無
- 請求URL:
http://www.liulongbin.top:3005/api/getprodlist
- 返回資料示例
{"status":0,"message":[{"id":5,"name":"寶馬","ctime":"2020-02-08T04:32:58.000Z"},{"id":6,"name":"瑪莎拉蒂","ctime":"2020-02-08T04:33:03.000Z"},{"id":12,"name":"1","ctime":"2020-02-08T04:51:21.000Z"}]}
2、新增新品牌
- 請求方式:post
- 返回資料格式:json
- 請求引數:
{name: 品牌名}
- 請求URL:
http://www.liulongbin.top:3005/api/addproduct
- 返回資料示例
{"status":0,"message":"新增成功"}
3、刪除品牌
- 請求方式:get
- 返回資料格式:json
- 請求引數:品牌id
api/delproduct/1
- 請求URL:
http://www.liulongbin.top:3005/api/delproduct/id
- 返回資料示例
{"status":0,"message":"刪除成功"}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="./lib/bootstrap-3.3.7.css">
</head>
<body>
<div id="app">
<div class="panel panel-primary">
<div class="panel-body form-inline">
<input type="text" placeholder="品牌名" class="form-control" v-model="name" @keyup.enter="add">
<input type="button" value="新增" class="btn btn-primary" @click="add">
</div>
</div>
<table class="table table-bordered table-hover table-striped">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Ctime</th>
<th>Opration</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 src="./lib/vue-2.4.0.js"></script>
<script src="./lib/vue-resource-1.3.4.js"></script>
<script>
// 全域性配置根目錄
Vue.http.options.root = 'http://www.liulongbin.top:3005/';
// 全域性啟用 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() {
// 頁面初始化時,執行 getinfo() 函式,獲取品牌資料
this.getinfo()
},
methods: {
getinfo() {
// 獲取品牌資訊
this.$http.get('api/getprodlist').then(result => {
// 賦值給 this.list,從而實現資料的顯示
if (result.body.status === 0) {
this.list = result.body.message
}
})
},
add() {
// 新增新品牌
// 傳送 post 請求,獲取
this.$http.post('api/addproduct', { name: this.name }).then(result => {
if (result.body.status === 0) {
console.log('新增成功!')
// 重新呼叫獲取資料介面,實現頁面重新整理
this.getinfo()
// 清空輸入框
this.name = ''
} else {
alert('新增失敗!')
}
})
},
del(id) {
// 根據刪除品牌
this.$http.get("api/delproduct/" + id).then(result => {
if (result.body.status === 0) {
this.getinfo()
} else {
alert('刪除失敗!')
}
})
}
}
})
</script>
</body>
</html>
參考文章: