Book List Case

1. Book List

  • static list effect
  • Template effect based on data
  • Handle action buttons for each row (disables default behavior)

1. Static data provided

  • The data is stored in the data attribute in vue
 var vm = new Vue({
      el: '#app',
      data: {
        books: [{
          id: 1,
          name: 'Three Kingdoms',
          date: ''
        },{
          id: 2,
          name: 'Water Margin',
          date: ''
        },{
          id: 3,
          name: 'A Dream of Red Mansions',
          date: ''
        },{
          id: 4,
          name: 'Journey to the West',
          date: ''
        }]
      }
    }); 
copy

2. Render the provided data to the page

  • Use v-for loop to traverse books to render each item of data into the corresponding data
 <tbody>
    <tr :key='item.id' v-for='item in books'>
       <!-- corresponding id render on the page -->
       <td>{{item.id}}</td>
        <!-- corresponding name render on the page -->
       <td>{{item.name}}</td>
       <td>{{item.date}}</td>
       <td>
         <!-- Prevent a Default jump for labels -->
         <a href="" @click.prevent>Revise</a>
         <span>|</span>
          <a href="" @click.prevent>delete</a>
       </td>
     </tr>
</tbody>
copy

2. Add books

  • Implement the static effect of the form
  • Add book form field data binding
  • Add button event binding
  • Implement adding business logic
<div>
  <h1>library management</h1>
  <div class="book">
       <div>
         <label for="id">
           Numbering:
         </label>
          <!-- 3.1,Get the input in the input box through two-way binding id  -->
         <input type="text" id="id" v-model='id'>
         <label for="name">
           name:
         </label>
           <!-- 3.2,Get the input in the input box through two-way binding name  -->
         <input type="text" id="name" v-model='name'>
            <!-- 3.3,Add click event to button  -->
         <button @click='handle'>submit</button>
       </div>
  </div>
</div>
  <script type="text/javascript">
    /*
      Book Management - Add Books
    */
   
      methods: {
        handle: function(){
          // 3.4 Define a new object book to store and get the id and name of the book in the input box 
          var book = {};
          book.id = this.id;
          book.name = this.name;
          book.date = '';
         // 3.5 Put the book into books through the array mutation method push
          this.books.push(book);
          //3.6 Clear the input box
          this.id = '';
          this.name = '';
        }
      }
   
  </script>
copy

3. Modify the book - on

  • When the edit button is clicked, the list of books to be modified is obtained
    • 4.1 To add a click event to the modification button, you need to pass the id of the current book so that you know which book you need to modify
  • Fill in the list of books to be modified into the form
    • 4.2 Find out the detailed information of the corresponding book in books according to the passed id
    • 4.3 Fill the form with the obtained information
​
              <!--- 
                4.1  To add a click event to the modify button, you need to change the current book's id pass the past 
                That way you know which book you need to revise
                --->  
              <a href="" @click.prevent='toEdit(item.id)'>Revise</a>
              
 <script type="text/javascript">
    /*
      Book Management - Add Books
    */
    
        toEdit: function(id){
          console.log(id)
          //4.2 Find out the detailed information of the corresponding book in books according to the passed id
          var book = this.books.filter(function(item){
            return item.id == id;
          });
          console.log(book)
          //4.3 Fill the form with the obtained information
          // this.id and this.name are bound to the form through two-way binding and the view is automatically updated once the data changes
          this.id = book[0].id;
          this.name = book[0].name;
        }
      
    
  </script>
copy

4. Modify the book - next

  • 5.1 Define an identifier, mainly to control the id of the currently edited book in the editing state cannot be modified, that is, in the editing state, the input box currently controlling the number of the book is disabled
  • 5.2 Binding the disabled attribute flag to the book number through the attribute is true, it is disabled
  • 5.3 The default value of flag is false and it is in editing state. To change the flag to true, the current form is disabled.
  • 5.4 Reuse adding method When the user clicks submit, the logic in the handle is still executed. If the flag is true, the form is in an uninputable state. At this time, the user edits the data.
​
              <!-- 5.2 Binding via property binding disabled properties of  flag for true is disabled      -->
            <input type="text" id="id" v-model='id' :disabled="flag">
            
<script type="text/javascript">
        /*Book Management - Add Books*/
        var vm = new Vue({
            el: '#app',
            data: {
                // 5.1 Define an identifier, mainly to control the id of the currently edited book in the editing state cannot be modified 
                // That is, in the editing state, the input box that currently controls the book number is disabled 
                flag: false,
                id: '',
                name: '',
              
            },
            methods: {
                handle: function() {
                   /*
                     5.4  Reuse add method When the user clicks submit, the logic in the handle is still executed
                         If the flag is true, that is, the form is in a non-input state, and the user edits the data data executed at this time.    
                   */ 
                    if (this.flag) {
                        // edit book
                        // 5.5 Update the corresponding data in the array according to the current ID
                        this.books.some((item) => {
                            if (item.id == this.id) {
                                // This in the arrow function points to the this of the parent scope 
                                item.name = this.name;
                                // After completing the update operation, the loop needs to be terminated
                                return true;
                            }
                        });
                        // 5.6 After editing the data, the form should be in a state that can be entered
                        this.flag = false;
                    //  5.7 If the flag is false and the form is in the input state, the user added data executed at this time
                    } else { 
                        var book = {};
                        book.id = this.id;
                        book.name = this.name;
                        book.date = '';
                        this.books.push(book);
                        // clear form
                        this.id = '';
                        this.name = '';
                    }
                    // clear form
                    this.id = '';
                    this.name = '';
                },
                toEdit: function(id) {
                     /*
                     5.3  flag The default value is false. It is in the editing state. To change the flag to true, the current form is disabled. 
                     */ 
                    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>
copy

5. Delete Books

  • 6.1 Add an event to the delete button and pass the id of the book that needs to be deleted currently
  • 6.2 Find the index of an element from an array based on its id
  • 6.3 Deleting array elements by index
  <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)'>Revise</a>
              <span>|</span>
               <!--  6.1 Add an event to the delete button to delete the current book id pass over  --> 
              <a href="" @click.prevent='deleteBook(item.id)'>delete</a>
            </td>
          </tr>
</tbody>
  <script type="text/javascript">
    /*
      Book Management - Add Books
    */
    var vm = new Vue({
      methods: {
        deleteBook: function(id){
          // delete book
          // 6.2 Find the index of an element from an array based on its id
          // var index = this.books.findIndex(function(item){
          //   return item.id == id;
          // });
          // 6.3 Deleting array elements by index
          // this.books.splice(index, 1);
          // -------------------------
         // Method 2: delete through the filter method
        
          //6.4 Filter out the id according to the filter method, not the id of the book to be deleted 
         //Because filter is a replacement array and will not modify the original data, it is necessary to assign the id of the book that is not to be deleted to books 
          this.books = this.books.filter(function(item){
            return item.id != id;
          });
        }
      }
    });
  </script>
copy

6. Common feature application scenarios

1 filter (formatted date)

  • Vue.filter defines a global filter
 <tr :key='item.id' v-for='item in books'>
            <td>{{item.id}}</td>
            <td>{{item.name}}</td>
            <!-- 1.3  call filter -->
            <td>{{item.date | format('yyyy-MM-dd hh:mm:ss')}}</td>
            <td>
              <a href="" @click.prevent='toEdit(item.id)'>Revise</a>
              <span>|</span>
              <a href="" @click.prevent='deleteBook(item.id)'>delete</a>
            </td>
</tr>
​
<script>
        //1.1 Vue.filter defines a global 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, //month 
                  "d": date.getDate(), //day 
                  "h": date.getHours(), //Hour 
                  "m": date.getMinutes(), //Minute 
                  "s": date.getSeconds(), //Second 
                  "q": Math.floor((date.getMonth() + 3) / 3), //quarter 
                  "S": date.getMilliseconds() //millisecond 
                };
                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 The provided data contains a timestamp in milliseconds
   [{
          id: 1,
          name: 'Three Kingdoms',
          date: 2525609975000
        },{
          id: 2,
          name: 'Water Margin',
          date: 2525609975000
        },{
          id: 3,
          name: 'A Dream of Red Mansions',
          date: 2525609975000
        },{
          id: 4,
          name: 'Journey to the West',
          date: 2525609975000
        }];
</script>
copy

2 Custom instructions (get form focus)

  • Make the form automatically get focus
  • Customization via Vue.directive
<!-- 2.2  pass v-custom attribute name call custom command -->
<input type="text" id="id" v-model='id' :disabled="flag" v-focus>
​
<script>
    //2.1 Customize through Vue.directive
    Vue.directive('focus', {
      inserted: function (el) {
        el.focus();
      }
    });
​
</script>
copy

3 Calculated properties (counting the number of books)

  • Calculate the total number of books by calculating a property
    • The total number of books is to calculate the length of the array
 <div class="total">
        <span>Total Books:</span>
        <!-- 3.2 display on the page -->
        <span>{{total}}</span>
</div>
​
  <script type="text/javascript">
    /*
      Difference between computed properties and methods: computed properties are cached based on dependencies, while methods are not cached
    */
    var vm = new Vue({
      data: {
        flag: false,
        submitFlag: false,
        id: '',
        name: '',
        books: []
      },
      computed: {
        total: function(){
          // 3.1 Calculate the total number of books
          return this.books.length;
        }
      },
    });
  </script>
​
copy

4 Listener (verifies book existence)

 watch: {
                name: function (val) {
                    var flag = this.books.some(function (item) {
                        return item.name == val;
                    });
                    if (flag) {
                        // Disable button if book title exists
                        this.submitFlag = true;
                    } else {
                        this.submitFlag = false;
​
                    }
                }
            },
copy

5 Life Cycle (Book Data Processing)

mounted: function () {
                // When the lifecycle hook function is triggered, the template is already available
                // Generally, it is used to obtain background data at this time, and then fill the data into the template
                var data = [{
                    id: 1,
                    name: 'Three Kingdoms',
                    date: new Date()
                }, {
                    id: 2,
                    name: 'Water Margin',
                    date: new Date()
                }, {
                    id: 3,
                    name: 'A Dream of Red Mansions',
                    date: new Date()
                }, {
                    id: 4,
                    name: 'Journey to the West',
                    date: 343534647586
                }];
                this.books = data;
            }
copy

Posted by newbiehacker on Tue, 10 May 2022 05:41:44 +0300