Learning three: v-on, v-if, v-for

v-on,v-if,v-for

1 v-on

1.1 parameter

If you do not need to pass parameters to v-on binding methods, you can leave the parameters blank

When parentheses are omitted, the bound method can receive the event of the page as a parameter

<div id="app">
  <h1 @click="test1">123</h1>
    <!--You can't get it without omitting the small and wide sizes event Parametric-->
      <h1 @click="test1()">123</h1> 
</div>
</body>
<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      message: 'Hello'
    },
    methods: {
      test1(event) {
        console.log(event);
        console.log(1);
      }
    }
  })
</script>

How to manually pass in the event parameter?

  <h1 @click="test1(123,$event)">222</h1>

1.2 modifiers

@click.stop modifier prevents bubbling

<body>
<div id="app">
  <h1 @click="test1">111
    <button @click.stop="test2">222</button>
  </h1>
</div>
</body>
<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      message: 'Hello'
    },
    methods: {
      test1() {
        console.log(1);
      },
      test2() {
        console.log(2);
      }
    }
  })
</script>

@click.prevent to block the default event of an element, such as the following default submit button

  <form action="baidu">
    <button type="submit" @click.prevent="test3">Button</button>
  </form>

@keyup.enter @keyup listens for all key cap lifting events, plus enter only listens for carriage return events

<!--  Monitor keyboard click-->
  <input type="text" @keyup.enter="test3">

native listening to component events

@click.once is triggered only after the first click

2 v-if else et al

One function of v-if is to control whether elements are displayed

<body>
<div id="app">
  <h2 v-if="isShow">
    <p>{{message}}</p>
    <p>{{message}}</p>
    <p>{{message}}</p>
  </h2>
  <h1 v-else>isShow by false Show me</h1>
</div>
</body>
<script src="../js/vue.js"></script>
<script>
  const app=new Vue({
    el:'#app',
    data:{
      message:'Hello',
      isShow:true
    }
  })
</script>

If the logic is complex, it is better to implement it in methods or calculation attributes.

2.1 cases

Requirement: click the button, the previous login box changes from user name login to email login

<body>
<div id="app">
  <div v-if="btnFlag">User name login:<input type="text" placeHolder="User name login"></div>
  <div v-else>Email login:<input type="text" placeHolder="Mailbox login"></div>
  <button @click="btnFlag=!btnFlag">Point I switch</button>
</div>
</body>
<script src="../js/vue.js"></script>
<script>
  const app=new Vue({
    el:'#app',
    data:{
      btnFlag:true
    },

  })
</script>

There is a small problem in this case. When we input data in the input box and click switch, the input value will not change. It's reasonable to say that these two inputs are not the same input. What's the matter?

The label of vue will be put into memory first, which is generally called virtual dom. When rendering DOM, the existing elements will be reused as much as possible instead of creating a new one. When vue finds that the original input element is no longer used, it is used as input in else.

Solution: add key to the corresponding input

  <div v-if="btnFlag">User name login:<input type="text" key="1" placeHolder="User name login"></div>
  <div v-else>Email login:<input type="text" key="2" placeHolder="Mailbox login"></div>

2.2 v-show

Decide whether to display the element

V-show and v-if don't show the elements have different effects. The elements that don't show in v-if don't show in DOM at all. The elements that v-show does not display only add the display: none inline elements, but the elements still exist in the dom. If the show and hide elements switch frequently, use v-show.

3 v-for

3.1 traversal object

<div id="app">
  <ul>
    <li v-for="(value,key) in info">{{value}}=>{{key}}</li>
  </ul>
</div>
</body>
<script src="../js/vue.js"></script>
<script>
  const app=new Vue({
    el:'#app',
    data:{
      info:{
        name:'aaa',
        age:'19',
        height:199
      }
    }
  })
</script>

When v-for is used, it is recommended to bind a key. Why? If the key is bound, vue will be more efficient in adding and deleting li.

Under normal circumstances, insert Li: for example, if five li contents are abcde and an f is inserted between BCS, then he will replace the original c with f, and then replace them in turn, which is inefficient. After using the key, he will compare the differences between the two before modifying and replacing them.

Note that the binding key needs to be able to correspond to the content one by one (so do not bind the index, because the change of the order of the number of elements will affect the index)

But key cannot have duplicate. info in the following example is the object.

  <li v-for="(value,key) in info" :key="key">{{value}}=>{{key}}</li>

3.2 which array methods are responsive

push, pop() to delete the last element, shift (to delete the first element), unshift to add several elements before the array

splice(start, num… ele) after the start, Num elements are replaced with ele, and ele is deleted without any input.

reverse array inversion

Note: array changes using array subscripts are not responsive.

The set method of vue can be used

<div id="app">
  <ul>
    <li v-for="item in message">{{item}}</li>
  </ul>
  <button @click="change">change</button>
</div>
</body>
<script src="../js/vue.js"></script>
<script>
  const app=new Vue({
    el:'#app',
    data:{
      message:["aaa","bbb",'ccc','ddd']
    },
    methods:{
      change(){
        Vue.set(this.message,0,"eee")
      }
    }
  })
</script>

4 cases

  • Plus and minus can change the number of books

  • The total price is the sum of book price * quantity

  • Remove will delete an entire row

  • Show shopping cart empty after deleting all

4.1 self written

I wrote as follows:

  <style>
    * {
      padding: 0;
      margin: 0;
      user-select: none;
    }

    #app {
      width: 700px;
      margin: 50px auto;
    }

    table {
      width: 700px;
      border-collapse: collapse;
      margin: auto;
    }

    td {
      border: 1px solid #C6C6C6;
      line-height: 50px;
      padding: 0 15px;
    }

    .center {
      text-align: center;
    }

    .header td {
      background: #F6F6F6;
    }

    td button {
      border: 1px solid grey;
      padding: 0 5px;
      border-radius: 1px;
      outline: none;
    }

    .qBtn  {
      font-size: 12px;
      margin: 2px;
      border-radius: 3px;
      outline: none;
      background: #fff;
      box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
    }
  </style>
</head>
<body>
<div id="app">
  <table>
    <tr class="header">
      <td></td>
      <td>Titles of books</td>
      <td>Publication date</td>
      <td>Price</td>
      <td class="center">Purchase quantity</td>
      <td class="center">operation</td>
    </tr>
    <tr v-for="(book,index) in books">
      <td class="center">{{index+1}}</td>
      <td><{{book.name}}></td>
      <td>{{book.data}}</td>
      <td>¥{{book.price}}</td>
      <td class="center">
        <button class="qBtn" @click="minusBook(index)">-</button>
        {{book.quantity}}
        <button class="qBtn" @click="addBook(index)">+</button>
      </td>
      <td class="center">
        <button @click="delBook(index)">remove</button>
      </td>
    </tr>
  </table>
  <h4 v-show="books.length===0">Shopping cart is empty</h4>
  //Total price: ¥ {{totalprice}. 00
</div>
</body>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      books: [
        {name: "Introduction to algorithm", data: "2006-9", price: 85, quantity: 1},
        {name: "UNIX Programming technology", data: "2006-2", price: 59, quantity: 1},
        {name: "Programming Pearls", data: "2008-10", price: 39, quantity: 1},
        {name: "Code Complete", data: "2006-3", price: 128, quantity: 1},
      ]
    },
    methods: {
      minusBook(index){
        if (this.books[index].quantity>0){
          this.books[index].quantity--;
        }
      },
      addBook(index){
        this.books[index].quantity++;
      },
      delBook(index){
        this.books.splice(index,1);
      }
    },
    computed: {
      totalPrice() {
        if (this.books.length===0){
          return 0
        }else if (this.books.length===1){
          return this.books[0].price*this.books[0].quantity;
        }else {
          return this.books.reduce(function (pre, cur,ind) {
            if (ind===1){pre=pre.price*pre.quantity}
            return cur.price*cur.quantity+pre;
          });
        }
      },
      isEmpty(){
          return this.books.length===0;
      }
    }
  })
</script>

4.2 comparative summary

By comparing what the teacher wrote

The summary is as follows:

  • About the table style, highlight a relatively good-looking
table {
  border: 1px solid #e9e9e9;
  /*Frame folding*/
  border-collapse: collapse;
  border-spacing: 0;
}
th, td {
  padding: 8px 16px;
  border: 1px solid #e9e9e9;
  text-align: left;
}
th {
  background: #f7f7f7;
  color: #5c6b77;
  font-weight: 600;
}
  • About filters

    Keep two decimal places for prices in the table use num.isFixed(2) to keep two decimal places

    It is better to use the filter with vue, and the filter is one of the option s

Filter, which is used by the | symbol. The things before | will be passed to the filter as parameters, and the result of return will be displayed on the page

<td>{{book.price|showPrice}}</td>  
filters: {
      showPrice(price) {
        return '¥' + price.toFixed(2);
      }
  • About decrease button cannot be less than zero

My approach is to judge in method

It's ok

<button @click="decrement(index)" :disabled="book.quantity <=1">-</button>

If the disabled attribute of button is true, the button cannot interact

  • On the calculation of total price
computed:{
      totalPrice(){
        let totalPrice=0;
        for (let i=0;i<this.books.length;i++){
            totalPrice+=this.books[i].price*this.books[i].quantity
        }
        return totalPrice;
      }
    }

Normal traversal is good. reduce will only return the traversal elements when the array length is 1. The calculated totalPrice can use the above filter to add ¥ symbols and retain two decimal places.

Published 4 original articles, won praise 0, visited 90
Private letter follow

Tags: Vue Programming Unix less

Posted on Sat, 08 Feb 2020 04:15:01 -0800 by onedumbcoder