08表单绑定

表单绑定

表单控件在实际开发中是非常常见的。特别是对于用户信息的提交,需要大量的表单。
Vue中使用v-model指令来实现表单元素和数据的双向绑定。

<body>

  <div id="app">
    <input type="text" v-model="massage">
    {{massage}}
  </div>

  <script src="../js/vue.js"></script>
  <script>
    const app = new Vue({
      el: "#app",
      data: {
        massage: "你好"
      }
    })
  </script>
</body>

当我们在输入框输入内容时
因为input中的v-model绑定了message ,所以会实时将输入的内容传递给message , message发生改变。
当message发生改变时,因为上面我们使用Mustache语法,将message的值插入到DOM中,所以DOM会发生响应的改变。
所以,通过v-model实现了双向的绑定。

原理

  <div id="app">
    <!-- <input type="text" v-model="massage"> -->
    <!-- <input type="text" :value="massage" @input="valueChange"> -->
    <input type="text" :value="massage" @input="massage = $event.target.value">
    {{massage}}
  </div>

  <script src="../js/vue.js"></script>
  <script>
    const app = new Vue({
      el: "#app",
      data: {
        massage: "你好"
      },
      methods: {
        valueChange(event) {
          this.massage = event.target.value;
        }
      }
    })
  </script>

</body>

v-model结合radio类型

<div id="app">
  <label for="">
    <input type="radio" id="male" value="男" v-model="sex">男
  </label>
  <label for="">
    <input type="radio" id="female" value="女" v-model="sex">女
  </label>
  <h2>{{sex}}</h2>
</div>

<body>
  <script src="../js/vue.js"></script>
  <script>
    const app = new Vue({
      el: "#app",
      data: {
        message: "你好",
        sex:'男'
      }
    })
  </script>
</body>

v-model结合checkbox类型

单个勾选框: .

v-modelI即为布尔值。
此时input的value并不影响v-model的值。

多个复选框:

多个复选框时,因为可以选中多个,所以对应的data中属性是一个数组。
当选中某一个时 ,就会将input的value添加到数组中。

<div id="app">
  <!-- 单选框 -->
  <!-- <label for="agree">
    <input type="checkbox" id="agree" v-model="isAgree">同意协议
  </label>
  <h2>{{isAgree}}</h2>
  <button :disabled="!isAgree">下一步</button> -->

  <!-- 多选框 -->
    <!-- <input type="checkbox" value="篮球" v-model="hobbies">篮球
    <input type="checkbox" value="足球" v-model="hobbies">足球
    <input type="checkbox" value="排球" v-model="hobbies">排球
    <input type="checkbox" value="手球" v-model="hobbies">手球
    <h2>{{hobbies}}</h2> -->

    <label v-for="item in originHobbies" :for="item">
      <input type="checkbox" :value="item" :id="item" v-model="hobbies">{{item}}
    </label>
  </div>

<body>
  <script src="../js/vue.js"></script>
  <script>
    const app = new Vue({
      el: "#app",
      data: {
        message: "你好",
        isAgree: false,//单选框
        hobbies:[],//多选框 
        originHobbies:['篮球','足球','乒乓球','台球','高尔夫球']
          //也可以通过值绑定来从服务器获取值
      }
    })
  </script>
</body>

v-model结合select

单选:只能选中一个值。

v-model绑定的是一个值。
当我们选中option中的一个时,会将它对应的value赋值到mySelect中

多选:可以选中多个值。

v-model绑定的是一个数组。
当选中多个值时,就会将选中的option对应的value添加到数组mySelects中

<body>

  <div id="app">
    <!-- 1、选择一个 -->
    <select name="abc" id=""  v-model="fruit">
      <option value="苹果">苹果</option>
      <option value="香蕉">香蕉</option>
      <option value="榴莲">榴莲</option>
      <option value="西瓜">西瓜</option>
    </select>
    <h2>{{fruit}}</h2>

    <!-- 2、选择多个 -->
    <select name="abc" id=""  v-model="fruits" multiple>
      <option value="苹果">苹果</option>
      <option value="香蕉">香蕉</option>
      <option value="榴莲">榴莲</option>
      <option value="西瓜">西瓜</option>
    </select>
    <h2>{{fruits}}</h2>
  </div>

    <script src="../js/vue.js"></script>
    <script>
      const app = new Vue({
        el: "#app", 
        data: {
          message: "你好",
          fruit:"香蕉",
          fruits:[]
        }
      })
    </script>

</body>

v-model的修饰符

lazy修饰符:

默认情况下, v- model默认是在input事件中同步输入框的数据的。
也就是说, 一旦有数据发生改变对应的data中的数据就会自动发生
改变。
lazy修饰符可以让数据在失去焦点或者回车时才会更新:

number修饰符:

默认情况下,在输入框中无论我们输入的是字母还是数字,都会被
当做字符串类型进行处理。
但是如果我们希望处理的是数字类型,那么最好直接将内容当做数
字处理。
number修饰符可以让在输入框中输入的内容自动转成数字类型:

trim修饰符:

如果输入的内容首尾有很多空格,通常我们希望将其去除
trim修饰符可以过滤内容左右两边的空格

<div id="app">
  <!-- 1.修饰符:lazy -->
  <input type="text" v-model.lazy="message">
  <h2>{{message}}</h2>

  <!-- 2.修饰符:number -->
  <input type="number" v-model.number="age">
  <h2>{{typeof age}}</h2>

  <!-- 3.修饰符:trim -->
  <input type="text" v-model.trim="name">
  <h2>{{name}}</h2>
</div>

<body> 
  <script src="../js/vue.js"></script>
  <script>
    const app = new Vue({
      el: "#app",
      data: {
        message: "你好",
        age:12,
        name:''
      }
    })
  </script>
</body>

综合-书籍购物车案例

  • HTML
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="./style.css">

</head>

<body>

  <div id="app">
    <div v-if="books.length">
      <table>
        <thead>
          <tr>
            <th></th>
            <th>书籍名称</th>
            <th> 出版日期</th>
            <th> 价格</th>
            <th> 购买数量</th>
            <th> 操作</th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="(item,index) in books">
            <td>{{item.id}}</td>
            <td>{{item.name}}</td>
            <td>{{item.date}}</td>
            <td>{{item.price | showPrice}}</td>
            <td>
              <button @click="decrement(index)" v-bind:disabled="item.count <= 1">-</button>
              {{item.count}}
              <button @click="increment(index)">+</button>
            </td>
            <td><button @click="removeHandler(index)">移除</button></td>
          </tr>
        </tbody>
      </table>
      <h2>
        总价格: {{totalPrice | showPrice}}
      </h2>
    </div>
    <div v-else>
      <h1>购物车为空</h1>
    </div>
  </div>
  <script src="../js/vue.js"></script>
  <script src="./main.js"></script>
</body>

</html>

  • CSS
table{
  border: 1px solid #000;
  border-collapse: collapse;
  border-spacing: 0;
}
th,td{
  padding: 8px 16px;
  border: 1px solid #000;
  text-align: left;
}

th{
  background-color: #f7f7f7;
  color: #5c6b77;
  font-weight: 600;
}

  • JS
const app = new Vue({
  el: "#app",
  data: {
    books: [{
        id: 1,
        name: '《算法导论》',
        date: "2006-9",
        price: 85.00,
        count: 1
      },
      {
        id: 2,
        name: '《算法导论》',
        date: "2006-9",
        price: 85.00,
        count: 1
      },
      {
        id: 3,
        name: '《算法导论》',
        date: "2006-9",
        price: 85.00,
        count: 1
      },
      {
        id: 4,
        name: '《算法导论》',
        date: "2006-9",
        price: 85.00,
        count: 1
      }
    ]
  },
  methods: {
    // getFinalPrice(price){
    //   return '¥'+price.toFixed(2) //toFixed(2)保留两位小数
    // }
    increment(index) {
      this.books[index].count++
    },
    decrement(index) {
      this.books[index].count--
    },
    removeHandler(index) {
      this.books.splice(index, 1)
    }
  },
  filters: { //过滤器
    showPrice(price) {
      return '¥' + price.toFixed(2)
    }
  },
  computed: {
    totalPrice() {
      let totalPrice = 0;
      for (let i = 0; i < this.books.length; i++) {
        totalPrice += this.books[i].price * this.books[i].count;
      }
      return totalPrice;
    }
  }
})

posted @ 2021-11-08 22:49  天亮說晚安  阅读(60)  评论(0)    收藏  举报