国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

前端主流框架vue學習筆記第二篇

2019-11-19 15:58:48
字體:
來源:轉載
供稿:網友

上篇,在本篇中,我們將要實現如下,功能,編輯和查詢,我們當前的todolist程序,和線上其它的demo程序不同,我們會對其進行增刪改查的基本操作,之后進行進一步的完善,按照常規的系統使用經驗,一般我們新增和編輯都是在模態框中處理,這里我們不會去構建復雜的模態框,只用一個簡單的div層來代替,后期接下來的文章中我們會重復造輪子,構建我們自己的輕量級框架(UI庫)。

首先,我們對我們的頁面結構進行一下簡單的調整,加入bootstrap只是為了讓頁面不那么赤裸裸,對其它不會有任何影響

<!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>demo1</title> <script src="https://cdn.bootcss.com/vue/2.4.1/vue.js"></script> <link  rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="stylesheet"></head><body class="container"> <div id="app" class='row'> <div class="col-md-6">  <table class="table table-bordered">  <tr>   <th>title</th>   <th>desc</th>   <th></th>  </tr>  <tr v-for="(todoItem,index) in todolist">   <td>{{todoItem.title}}</td>   <td>{{todoItem.desc}}</td>   <td><input type="button" value="remove" @click="remove(index)" class="btn btn-danger" /></td>  </tr>  </table> </div> <div class="col-md-6">  <div class="form-inline">  <label for="title" class="control-label col-md-4">title:</label>  <input type="text" v-model="title" class="form-control col-md-8">  </div>  <div class="form-inline">  <label for="desc" class="control-label col-md-4">desc</label>  <input type="text" v-model="desc" class="form-control col-md-8">  </div>  <div class="form-inline">  <input type="button" value="OK" v-on:click="addItem()" class="btn btn-primary offset-md-10" />  </div> </div> </div> <script> var TodoItem = function (title, desc) {  this.title = title;  this.desc = desc; } new Vue({  el: '#app',  data: {  todolist: [],  title: '',  desc: ''  },  methods: {  addItem: function () {   this.todolist.push(new TodoItem(this.title, this.desc))   this.title = this.desc = '';  },  remove: function (index) {   this.todolist.splice(index, 1);  }  } }) </script></body></html>

js沒有任何變化,只是引入了bootstrap4之后,對html結構進行了微調整,由于我們需要增加編輯操作,我們把增加編輯操作歸納為以下幾個步驟:

1、增加編輯按鈕;

2、點擊編輯按鈕綁定所對應todoitem到表單進行編輯

3、點擊表單中OK按鈕,對編輯結果進行應用。

注意:這里需要區分,在點擊OK按鈕時,進行的是新增操作還是編輯操作,我們對我們數據結構加入自增ID來標示,如果編輯項目有ID,則為保存編輯操作,如果不存在ID則為新增保存操作,對我們的數據結構進行以下微調,由于新增了ID項目,那么在data屬性中也要增加ID屬性,這樣每次新增屬性都要直接修改data屬性,這就是變化點,下面我們對變化點進行簡單封裝,修改代碼如下:

data: {  todolist: [],  todoItem:{   id:'',   title:'',   desc:''  }  },

另外我們需要實現自增ID,這里采用最直接的方式,全局ID,使其自增即可,對TodoItem進行簡單的閉包處理:

var TodoItem = (function () {  var id = 1;  return function (title, desc) {  this.title = title;  this.desc = desc;  this.id = id++;  } })();

為了適應新數據結構的變化,則其它修改部分整體貼出來,變化部分見黃色:

<!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>demo1</title> <script src="https://cdn.bootcss.com/vue/2.4.1/vue.js"></script> <link  rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="stylesheet"></head><body class="container"> <div id="app" class='row'> <div class="col-md-6">  <table class="table table-bordered">  <tr>   <th></th>   <th>title</th>   <th>desc</th>   <th></th>  </tr>  <tr v-for="(todoItem,index) in todolist">   <th>{{todoItem.id}}</th>   <td>{{todoItem.title}}</td>   <td>{{todoItem.desc}}</td>   <td><input type="button" value="remove" @click="remove(index)" class="btn btn-danger" /></td>  </tr>  </table> </div> <div class="col-md-6">  <div class="form-inline">  <label for="title" class="control-label col-md-4">title:</label>  <input type="hidden" v-bind:value="todoItem.id" />  <input type="text" v-model="todoItem.title" class="form-control col-md-8">  </div>  <div class="form-inline">  <label for="desc" class="control-label col-md-4">desc</label>  <input type="text" v-model="todoItem.desc" class="form-control col-md-8">  </div>  <div class="form-inline">  <input type="button" value="OK" v-on:click="addItem()" class="btn btn-primary offset-md-10" />  </div> </div> </div> <script> var TodoItem = (function () {  var id = 1;  return function (title, desc) {  this.title = title;  this.desc = desc;  this.id = id++;  } })(); new Vue({  el: '#app',  data: {  todolist: [],  todoItem: {   id: '',   title: '',   desc: ''  }  },  methods: {  addItem: function () {   // this.todolist.push(new TodoItem(this.title, this.desc))   this.todolist.push(   new TodoItem(    this.todoItem.title,    this.todoItem.desc   )   );   this.todoItem={};  },  remove: function (index) {   this.todolist.splice(index, 1);  }  } }) </script></body></html>

刷新頁面,測試效果如下:

自增ID已經完成,那么添加編輯時綁定,按照上面的步驟,先添加編輯按鈕,在刪除按鈕后添加編輯按鈕,并在methods對象中增加對應的回調函數,對edit操作進行響應,函數中主要實現對todoItem對象進行綁定操作,具體代碼修改如下:

<table class="table table-bordered">  <tr>   <th></th>   <th>title</th>   <th>desc</th>   <th></th>  </tr>  <tr v-for="(todoItem,index) in todolist">   <th>{{todoItem.id}}</th>   <td>{{todoItem.title}}</td>   <td>{{todoItem.desc}}</td>   <td>   <input type="button" value="remove" @click="remove(index)" class="btn btn-danger" />   <input type="button" value="edit" @click="edit(todoItem.id)" class="btn btn-info" />   </td>  </tr>  </table>
methods: {    edit: function (id) {     //找到id值等于所傳參數的todoitem     var obj = this.todolist.filter(v => v.id === id)[0];     //對數據進行綁定,則數據會響應到表單上     this.todoItem = obj;    },   ...省略其它}

這樣有沒有問題呢?我們運行看一下效果:

從運行結果上看,我們點擊edit操作,的確完成了綁定,但是在我們修改編輯,還沒有點擊OK按鈕的情況下,表單中的變化已經提現到了列表中,這就不符合正常邏輯了,為什么會有這樣的情況呢,原因就在于this.todoItem=obj;這句代碼就是所謂的引用賦值,所以todoitem和obj指向的是同一個地址,則對this.todoItem的修改,會直接反應到obj上,也就是todoList中的這個元素上,所以在列表中會直接提現出來,避免這種情況的發生的方法,只要避免飲用賦值即可,所以對上述代碼進行如下修改:

//找到id值等于所傳參數的todoitem   var obj = this.todolist.filter(v => v.id === id)[0];   //對數據進行綁定,則數據會響應到表單上   this.todoItem = {   id:obj.id,   title:obj.title,   desc:obj.desc   };

刷新運行,發生程序按照預期運行了,接下來,增加更新保存操作,修改OK按鈕的事件綁定方式為save,并通過id判斷新增還是修改操作:

<div class="col-md-6">  <div class="form-inline">  <label for="title" class="control-label col-md-4">title:</label>  <input type="hidden" v-bind:value="todoItem.id" />  <input type="text" v-model="todoItem.title" class="form-control col-md-8">  </div>  <div class="form-inline">  <label for="desc" class="control-label col-md-4">desc</label>  <input type="text" v-model="todoItem.desc" class="form-control col-md-8">  </div>  <div class="form-inline">  <input type="button" value="OK" v-on:click="save()" class="btn btn-primary offset-md-10" />  </div> </div>
methods: {  edit: function (id) {   //找到id值等于所傳參數的todoitem   var obj = this.todolist.filter(v => v.id === id)[0];   //對數據進行綁定,則數據會響應到表單上   this.todoItem = {   id: obj.id,   title: obj.title,   desc: obj.desc   };  },  save: function () {   if (this.todoItem.id) {   //編輯保存   var obj = this.todolist.filter(v => v.id === this.todoItem.id)[0];   obj.title = this.todoItem.title;   obj.desc = this.todoItem.desc;   } else {   //新增保存   this.todolist.push(    new TodoItem(    this.todoItem.title,    this.todoItem.desc    )   );   }   //重置表單 這部分筆誤,在實際代碼中已修改,但是貼上來的代碼沒有做修改,具體見最下面代碼,錯誤原因見下方回復   this.todoItem = {};  },    remove: function (index) {   this.todolist.splice(index, 1);  }  }

代碼比較簡單,這里就不再贅述,可以看一下運行效果:

為了逼格更高一點,這里我再介紹一個指令,其實上面已經使用了,v-bind ,這個指令和v-on是類似的,兩者的區別在于后面的參數不同,一般v-bind用來傳遞屬性參數,一般使用縮寫形式:attr,可以綁定自定義屬性,上面代碼中我們對Id值的綁定已經使用了v-bind:value="todoItem.id",這里相當于angular中ng-bind。基于對v-bind的了解,我們可以推理,給v-bind添加disable的屬性,使OK按鈕只有再title不為空的前提下再可用。

<div class="form-inline">  <input type="button" value="OK" v-on:click="save()" class="btn btn-primary offset-md-10" :disabled='!todoItem.title'/>  </div>

刷新運行:

上面代碼能很好的運行,但是現在如果我需要修改一下驗證規則,在title和desc都不為空的情況下,才使用OK按鈕可用,如何做?你當然會說,很簡單,直接加入一個&&條件不就行了,但是問題在于,現在我的模型比較小,屬性比較少,如果我存在一個大量屬性的對象,做類似的驗證,這樣來修改代碼就是一個坑了,說到這里,其實已經可以想到,既然驗證規則再變,那么可以考慮作為一個變化點封裝起來,最直觀的方式,是封裝為一個方法,但是vue提供了更好的方式:computed,計算屬性,這個計算屬性應該是來自于knockout的概念,有興趣的可以看一下knockout中計算屬性,修改代碼如下:

new Vue({  el: '#app',  data: {  todolist: [],  todoItem: {   id: '',   title: '',   desc: ''  }  },  computed:{  canSave:function(){   return !this.todoItem.title || !this.todoItem.desc;  }  },  ...省略其它  } })

可以看到computed屬性是以方法的方式來定義的,這里是最簡單方式,只讀的方式,當然還可以通過get set方式進行讀寫控制,我們后期的代碼中可能會見到,如果捉急,可以去查看官方文檔。在computed使用的時候,和方法調用截然不同,而是和data屬性中代理的模式一樣,如果你使用過knockout,那么你對這種用法就見怪不怪了,html部分修改如下:

<div class="form-inline">  <input type="button" value="OK" v-on:click="save()" class="btn btn-primary offset-md-10" :disabled='canSave'/>  </div>

刷新頁面,運行效果如圖:

ok,編輯這部分內容就到這里吧,在沒有后端接口的前提下,保存操作都是模擬的,接下來對我們的查詢進行一下簡單的介紹,這里查詢,由于沒有后端接口,咱們只做最簡單的演示,對代碼做如下處理:

1、增加查詢輸入框,keyword,添加查詢按鈕

2、點擊查詢操作,預期結果:根據輸入的查詢關鍵字,過濾列表

按照上面思路對我們代碼進行修改:

<div class="row toolbar"> <div class="col-md-8">  keyword:  <input type="text" v-model="keyword" />  <input type="button" @click="query()" value="search" /> </div> </div>

data中增加keyword屬性,以實現對輸入框的綁定,在methods中添加query方法:

//全局變量,用來緩存所有數據 var list = []; data: {  todolist: [],  todoItem: {   id: '',   title: '',   desc: ''  },  keyword:''  },
query: function () {   //過濾title中不包含keyword的數據   //這里必須通過list全局變量過濾,而不能通過this.todolist,因為需要給this.todolist賦值,賦值后無法還原原來的列表。   this.todolist = list.filter(v => v.title.indexOf(this.keyword) !== -1);  }

刷新頁面運行效果如圖:

代碼部分注釋中已經寫的很清楚了,有疑問可提價comment。本章就到這里,文章有點水,在(三)中會加入添加服務端支持,并使用axios和服務端rest接口進行交互敬請期待,準備睡覺。

<!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>demo1</title> <script src="https://cdn.bootcss.com/vue/2.4.1/vue.js"></script> <link  rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="stylesheet"></head><body class="container"> <div id="app"> <div class="row toolbar">  <div class="col-md-8">  keyword:  <input type="text" v-model="keyword" />  <input type="button" @click="query()" value="search" />  </div> </div> <div class='row'>  <div class="col-md-6">  <table class="table table-bordered">   <tr>   <th></th>   <th>title</th>   <th>desc</th>   <th></th>   </tr>   <tr v-for="(todoItem,index) in todolist">   <th>{{todoItem.id}}</th>   <td>{{todoItem.title}}</td>   <td>{{todoItem.desc}}</td>   <td>    <input type="button" value="remove" @click="remove(index)" class="btn btn-danger" />    <input type="button" value="edit" @click="edit(todoItem.id)" class="btn btn-info" />   </td>   </tr>  </table>  </div>  <div class="col-md-6">  <div class="form-inline">   <label for="title" class="control-label col-md-4">title:</label>   <input type="hidden" v-bind:value="todoItem.id" />   <input type="text" v-model="todoItem.title" class="form-control col-md-8">  </div>  <div class="form-inline">   <label for="desc" class="control-label col-md-4">desc</label>   <input type="text" v-model="todoItem.desc" class="form-control col-md-8">  </div>  <div class="form-inline">   <input type="button" value="OK" v-on:click="save()" class="btn btn-primary offset-md-10" :disabled='canSave' />  </div>  </div> </div> </div> <script> var list=[]; var TodoItem = (function () {  var id = 1;  return function (title, desc) {  this.title = title;  this.desc = desc;  this.id = id++;  } })(); new Vue({  el: '#app',  data: {  todolist: [],  todoItem: {   id: '',   title: '',   desc: ''  },  keyword: ''  }, computed: {  canSave: function () {   return !this.todoItem.title || !this.todoItem.desc;  }  },  methods: {  query: function () {   //過濾title中不包含keyword的數據   //這里必須通過list全局變量過濾,而不能通過this.todolist,因為需要給this.todolist賦值,賦值后無法還原原來的列表。   this.todolist = list.filter(v => v.title.indexOf(this.keyword) !== -1);  },  edit: function (id) {   //找到id值等于所傳參數的todoitem   var obj = this.todolist.filter(v => v.id === id)[0];   //對數據進行綁定,則數據會響應到表單上   this.todoItem = {   id: obj.id,   title: obj.title,   desc: obj.desc   };  },  save: function () {   if (this.todoItem.id) {   //編輯保存   var obj = this.todolist.filter(v => v.id === this.todoItem.id)[0];   obj.title = this.todoItem.title;   obj.desc = this.todoItem.desc;   } else {   //新增保存   this.todolist.push(    new TodoItem(    this.todoItem.title,    this.todoItem.desc    )   );   }   //重置表單   this.todoItem = { title: '', desc: '' };  },  remove: function (index) {   this.todolist.splice(index, 1);  }  } }) </script></body></html>

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 原阳县| 江华| 常德市| 罗源县| 大洼县| 阿拉善左旗| 丹凤县| 富阳市| 棋牌| 淮安市| 登封市| 兴仁县| 南涧| 景洪市| 河西区| 依兰县| 南岸区| 文安县| 三明市| 泾川县| 丰城市| 当雄县| 河曲县| 太湖县| 塘沽区| 吉木萨尔县| 靖宇县| 昭觉县| 桃园市| 八宿县| 鄯善县| 舒城县| 建水县| 定襄县| 日照市| 沂源县| 抚宁县| 松原市| 武平县| 嘉义市| 聂荣县|