1. 程式人生 > 實用技巧 >02、JS高階函式、v-model表單的雙向繫結

02、JS高階函式、v-model表單的雙向繫結

目錄

JavaScript高階函式的使用

JS中的for迴圈

/* 普通的for迴圈 */
for (let i = 0; i < this.books.length; i++) {
    total += this.books[i].count * this.books[i].price;
}
/* let i in this.books i是索引 */
for (let i in this.books) {
    total += this.books[i].count * this.books[i].price;
}
/* let item of this.books item是陣列的元素 */
for (let item of this.books) {
    total += item.price * item.count;
}

JS中與陣列有關的高階函式

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<script>

  /* filter/map/reduce
  * filter中的回撥函式必須返回一個boolean值,當返回true時函式內部會自動將這次回撥的n加入到新的陣列中,當返回false時函式內部會過濾掉這次n
  * map的回撥函式用來處理元素,而filter的回撥函式是用來過濾元素,返回原陣列中的某些元素
  * reduce的回撥函式用來對陣列進行彙總
  *  */

  //1、filter函式的使用
  const nums = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100];
  let newArray = nums.filter(function (n) {
    return n % 20 === 0;
  });
  console.log(newArray);
  /* [20, 40, 60, 80, 100] */

  //2、map函式的使用
  let newArray2 = newArray.map(function (n) {
    return n * 2;
  });
  console.log(newArray2);
  /* [40, 80, 120, 160, 200] */

  //3、reduce函式的使用,兩個引數,第二個引數為初始化值
  let total = newArray2.reduce(function (preValue, currValue) {
    /* preValue是上一次返回的值 */
    return preValue + currValue;
  }, 0);
  console.log(total);
  /* 600 */

  /* 4、鏈式程式設計 */
  let number = nums.filter(function (n) {
    return n > 80;
  }).map(function (n) {
    return n / 2;
  }).reduce(function (preValue, currValue) {
    return preValue + currValue;
  }, 0);
  console.log(number);
  /* 95 */

  /* 5、箭頭函式 */
  let sum = nums.filter((n) => n > 80).map((n) => n / 2).reduce((preValue, currValue) => preValue + currValue, 0);
  console.log(sum);
</script>
</body>
</html>

改進for迴圈計算總價格

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
  <div id="app">
    總價格:{{totalPrice}}
  </div>

  <script src="../js/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        books: [
          {id: '01', name: 'JVM虛擬機器規範', price: 66, count: 1},
          {id: '02', name: '阿里巴巴程式設計手冊', price: 33, count: 2},
          {id: '03', name: '演算法導論', price: 101, count: 3},
          {id: '04', name: '多執行緒詳解', price: 88, count: 4}
        ]
      },
      computed: {
        totalPrice: function () {
          return this.books.reduce((preValue, currValue) => preValue + currValue.count * currValue.price, 0);
        }
      }
    })
  </script>
</body>
</html>

v-model表單輸入繫結

Vue中使用v-model指令實現表單元素和資料的雙向繫結。

v-model的基本使用

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>v-model</title>
</head>
<body>
  <div id="app">
    <label for="name"></label>
    <input type="text" placeholder="edit me" v-model="message" id="name">
    message is : {{message}}
  </div>
  <script src="../js/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        message: 'Hello Vue.js.',
      }
    });
  </script>
</body>
</html>

v-model的原理

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>v-model</title>
</head>
<body>
  <div id="app">
    <label for="name"></label>
    <!-- v-bind:value:單向繫結,v-on:input: 監聽輸入事件 -->
    <!--<input type="text" id="name" placeholder="edit me" v-bind:value="message" v-on:input="valueChange">-->
    <input type="text" id="name" placeholder="edit me" v-bind:value="message" v-on:input="message = $event.target.value">
    message is : {{message}}
  </div>
  <script src="../js/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        message: 'Hello Vue',
      },
      methods: {
        valueChange(event) {
          this.message = event.target.value;
        }
      }
    });
  </script>
</body>
</html>

你可以用 v-model 指令在表單 <input><textarea><select> 元素上建立雙向資料繫結。

v-model和radio的結合---單選框

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>v-model</title>
</head>
<body>
  <div id="app">
    <!-- 當v-model繫結的是同一個資料時,可以沒有name屬性 -->
    <label for="male"></label>
    <input type="radio" id="male" v-model="gender" value="男">男
    
    <label for="female"></label>
    <input type="radio" id="female" v-model="gender" value="女">女
    
    <br />
    <span>你選擇了{{gender}}</span>
  </div>
  <script src="../js/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        gender: '男', /* 預設選中 */
      }
    });
  </script>
</body>
</html>

v-model和checkbox的結合---多選框

  • 單個複選框:boolean
  • 多個複選框:陣列型別
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>v-model</title>
</head>
<body>
<div id="app">
  <label for="checkbox"></label>
  <input type="checkbox" id="checkbox" v-model="checked">I accept.
  
  <br/>
  <span v-if="checked">您選擇了同意協議</span>
  <span v-else>您沒有同意協議</span>
  <br/>
  <button v-bind:disabled="!checked">下一步</button>
</div>
<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      checked: false,
    }
  });
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>v-model</title>
</head>
<body>
<div id="app">
  <!-- 一個label繫結一個input -->
  <label for="basketball">籃球</label>
  <input type="checkbox" id="basketball" value="basketball" v-model="hobbies">
  <label for="football">足球</label>
  <input type="checkbox" id="football" value="football" v-model="hobbies">
  <label for="music">音樂</label>
  <input type="checkbox" id="music" value="music" v-model="hobbies">
  <label for="film">電影</label>
  <input type="checkbox" id="film" value="film" v-model="hobbies">
  <br />
  <span>您的愛好是:{{hobbies}}</span>
</div>
<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      hobbies: []
    }
  })
</script>
</body>
</html>

v-model結合select標籤

  • 單選:一個值(省市區)
  • 多選:愛好
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>v-model</title>
</head>
<body>
<div id="app">
  <select v-model="selected">
    <option disabled>請選擇</option>
    <option value="A" >A</option>
    <option value="B">B</option>
    <option value="C">C</option>
  </select>
  <span>你選擇了{{selected}}</span>
</div>

<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      selected: 'A' /* 預設選中 */
    }
  })
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>v-model</title>
</head>
<body>
<div id="app">
  <!-- 在選擇時需要按住ctrl鍵 -->
  <select multiple v-model="selected">
    <option disabled>請選擇</option>
    <option value="A">A</option>
    <option value="B">B</option>
    <option value="C">C</option>
  </select>
  <span>你選擇的是:{{selected}}</span>
</div>
<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      selected: []
    }
  });
</script>
</body>
</html>

修飾符

.lazy

在預設情況下,v-model 在每次 input 事件觸發後將輸入框的值與資料進行同步 。你可以新增 lazy 修飾符,從而轉為在 change 事件之後進行同步:

<!-- 在“change”時而非“input”時更新 -->
<input v-model.lazy="msg">

.number

如果想自動將使用者的輸入值轉為數值型別,可以給 v-model 新增 number 修飾符:

<input v-model.number="age" type="number">

.trim

如果要自動過濾使用者輸入的首尾空白字元,可以給 v-model 新增 trim 修飾符:

<input v-model.trim="msg">
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>v-model</title>
</head>
<body>
<div id="app">
  <!-- 1、.lazy修飾符 -->
  <label for="name">使用者名稱:</label>
  <input type="text" id="name" v-model.lazy="message">
  <span>message is {{message}}</span>
  <br />

  <!-- 2、.number修飾符 -->
  <label for="age">年齡:</label>
  <input type="number" id="age" v-model.number="age">
  <span>{{typeof age}}</span>
  <br />

  <label for="password">密碼:</label>
  <input type="text" id="password" v-model.trim="password">
  <span>{{password}}</span>
</div>
<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue.js.',
      age: 12,
      password: ''
    }
  });
</script>
</body>
</html>