vue的双向绑定的应用 与案例

v-model:实现双向绑定,常用于表单元素。

  • 如果要让多个单选框成为一组,必须保证 v-model的值必须相等。
  • 当data中的数据发送变化时,对应的单选框就会被选中 选中单选框的时候,data中的数据也会跟着变化,变成单选框中value的属性值。
    实例:单选框
 <div id="app">
       选择一个你喜欢的明星:<br>
        <!-- input后面的文字 只是对input元素的解释说明,是给用户看到。 input的值由它的value属性来决定 -->
        <input type="radio" v-model="inputData" value="成龙">成龙<br>
        <input type="radio" v-model="inputData" value="吴彦祖">吴彦祖<br>
        <input type="radio" v-model="inputData" value="李小龙">李小龙<br>
    </div>
    <script src="vue.js"></script>
    <script>
        new Vue({
            el:"#app",
            data:{
            //空会转化为false
               inputData:""
            },
            methods:{

            }
        })
    </script>

复选框:在vue中复选框的时候可以分为单独使用和组合使用。

  • 单独使用: 比如 同意协议 data中绑定的数据是一个布尔值, 选中的时候,值为true,反之为false。
  • 组合使用:v-model需要和value一起使用,同时绑定的数据必须是一个数组类型。 同一组的复选框必须绑定同一个数据。
    实例:多选框
 <div id="app">
         <!-- <input type="checkbox" v-model="isChecked"> 同意协议<br>
    <p>选择的状态:{{isChecked}}</p> -->

    <p>选择您喜欢的电视剧</p>
    <input type="checkbox" v-model="checkData" value="雪中悍刀行">雪中悍刀行<br>
    <input type="checkbox" v-model="checkData" value="风起洛阳">风起洛阳<br>
    <input type="checkbox" v-model="checkData" value="小敏家">小敏家<br>
    <input type="checkbox" v-model="checkData" value="谁是凶手">谁是凶手<br>
    <input type="checkbox" v-model="checkData" value="对手">对手<br>
    <p>您选择的是:{{checkData}}</p>
    </div>
    <script src="vue.js"></script>
    <script>
        new Vue({
            el:"#app",
            data:{
                isChecked:false,
                //写到数组里面的会被默认选中
                checkData:["对手","风起洛阳"]
            },
            methods:{

            }
        })

下拉框也分为单选和多选

  • 多选的话,在select上添加一个 multipe属性 即可。
  • 多选绑定的值是一个数组。 使用 ctrl+鼠标单击 选择。
    案例:下拉框
  <div id="app">
           <!-- option中有value时,数据会优先匹配value中的值,没有value匹配的是option中的文本 -->
               <!-- 下拉框的数据绑定是绑定在select标签上的 -->
    请选择喜欢的电视剧:
       <select v-model="selectData" multiple>
           <option value="">--请选择--</option>
           <option value="雪中焊道行">雪中焊道行</option>
           <option value="谁是凶手">谁是凶手</option>
           <option value="小明家">小明家</option>
           <option value="对手">对手</option>
       </select>
       <p>{{selectData}}</p>
    </div>
    <script src="vue.js"></script>
    <script>
       new Vue({
           el:"#app",
           data:{
              selectData:"谁是凶手"
           },
           methods:{

           }
       })
    </script>

表单的修饰符 用v-model

示例:修饰符

 <div id="app">
        用户名:<input type="text" v-model="username">
     年龄:<input type="text" v-model="age">
     {{age}}
    </div>
    <script src="vue.js"></script>
   <script>
     new Vue({
         el:"#app",
         data:{
             username:"lisi",
             age:20
         },
         methods:{

         }
     })
   </script> 

vue中的key
每当数组中的数据发送变化时,我们都需要重新渲染页面:

1.直接全部重新渲染。 代码实现简单,但是效率低。

2.一一对比,找到被删除的DOM,将其删除,其他人不动。 执行效率比较高。、

vue使用的就是第二个方案,叫做虚拟DOM。 vue2.0引入的,渲染速度提高了2-4倍。
**请添加图片描述
**
key的案例: 防止删除时候数据乱掉

<div id="app">
        <from>
            <p>书名:<input type="text" v-model="bookName"></p>
            <p><input type="submit" value="添加" @click.prevent="add"></p>
        </from>
        <ul>
            <li v-for="(item,index) in books" v-bind:key="item.id"><input type="checkbox" > {{item.name}} <button @click="del(index)">删除</button></li>
        </ul>

    </div>
    <script src="vue.js"></script>
    <script>
        //创建Vue实例,得到 ViewModel
        new Vue({
            el: "#app",
            data: {
                id: 4,
                bookName: "",
                books: [
                    { id: 1, name: "明克街13号" },
                    { id: 2, name: "我的云养女友" },
                    { id: 3, name: "星门" }
                ]
            },
            methods: {
                 //点击 添加
                 add(){
                     let book = {id:this.id,name:this.bookName};
                     //添加books中
                     this.books.push(book);
                     this.bookName="";
                 },
                 del(i){
                     //实现删除功能
                     this.books.splice(i,1);
                 }
            }
   
        })

选项卡案例
css样式

<style>
    * {
        padding: 0;
        margin: 0;
    }

    ul {
        list-style: none;
    }

    #app {
        width: 480px;
        margin: 20px auto;
        border: 1px solid cornflowerblue;
    }

    ul {
        width: 100%;
        overflow: hidden;
    }

    ul li {
        float: left;
        width: 160px;
        height: 60px;
        line-height: 60px;
        text-align: center;
        background-color: #cccccc;
    }

    ul li a {
        text-decoration: none;
        color: black;
    }

    p {
        height: 200px;
        text-align: center;
        line-height: 200px;
        background-color: #fff;
    }


    li.active {
        background-color: cornflowerblue;
    }

    /* 有这个类名的p标签,显示 */
    p.active {
        display: block;
    }

    img {
        width: 100%;
    }
</style>

body部分

<div id="app">
        <ul>
            <!-- 使用v-for遍历生成 li标签 -->
            <!-- :class中可以写三元(index==cur?'active':''),也可以写方法 -->
          <li :class="isActive(index)" v-for="(item,index) in list" :key="item.id" @click="toggle(index)">
              <!-- item表示循环的当前元素, 使用插值显示在页面上-->
              <a href="#">{{item.name}}</a>
          </li>

        </ul>
        //为真则显示图片 为假则隐藏
        <p v-show="index==cur" v-for="(item,index) in list" :key="item.id">
            <img :src="item.img" alt="">
        </p>

    </div>

script代码

 <!-- 
    1.将所有的图片都隐藏
    2.默认第一个按钮有激活的样式
    3.点击哪一个按钮,给哪一个按钮添加激活样式
   -->
    <script src="vue.js"></script>
    <script>
        new Vue({
            el: "#app",
            data: {
                //显示的元素的索引
                cur:0,
                list: [{
                    id: 1,
                    name: "鞠婧祎",
                    img: "./img/1.jpg"
                }, {
                    id: 2,
                    name: "李沁",
                    img: "./img/2.jpg"
                }, {
                    id: 3,
                    name: "易烊千玺",
                    img: "./img/3.jpg"
                }]
            },
            methods: {
                //判断小li是否激活
                 isActive(index){
                     
                     return index==this.cur?"active":"";
                 },


                //  点击li标签改变cur的值,实现切换效果
                // index是接受上面 @click中方法传递过来的index。
                toggle(index){
                    this.cur = index;
                }

            }

        })
    </script>

案例:待办事项
实现功能
1.用户输入待办事项,回车后添加到“正在进行”,并清空文本框 √
2.在“正在进行”列表中单击列表项,添加到 已完成 列表 √
3.在“已经完成”列表中单击列表项,添加到 正在进行 列表 √
4.在响应列表项中点击 删除 删除 该项目。
css部分

body {
  margin: 0;
  padding: 0;
  font-size: 16px;
  background: #CDCDCD;
}

header {
  height: 50px;
  background: #333;
  background: rgba(47, 47, 47, 0.98);
}

section {
  margin: 0 auto;
}

label {
  float: left;
  width: 100px;
  line-height: 50px;
  color: #DDD;
  font-size: 24px;
  cursor: pointer;
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}

header input {
  float: right;
  width: 60%;
  height: 24px;
  margin-top: 12px;
  text-indent: 10px;
  border-radius: 5px;
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.24), 0 1px 6px rgba(0, 0, 0, 0.45) inset;
  border: none
}

input:focus {
  outline-width: 0
}

h2 {
  position: relative;
}

span {
  position: absolute;
  top: 2px;
  right: 5px;
  display: inline-block;
  padding: 0 5px;
  height: 20px;
  border-radius: 20px;
  background: #E6E6FA;
  line-height: 22px;
  text-align: center;
  color: #666;
  font-size: 14px;
}

ol,
ul {
  padding: 0;
  list-style: none;
}

li input {
  position: absolute;
  top: 2px;
  left: 10px;
  width: 22px;
  height: 22px;
  cursor: pointer;
}

p {
  margin: 0;
}

li p input {
  top: 3px;
  left: 40px;
  width: 70%;
  height: 20px;
  line-height: 14px;
  text-indent: 5px;
  font-size: 14px;
}

li {
  height: 32px;
  line-height: 32px;
  background: #fff;
  position: relative;
  margin-bottom: 10px;
  padding: 0 45px;
  border-radius: 3px;
  border-left: 5px solid #629A9C;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07);
}

ol li {
  cursor: move;
}

ul li {
  border-left: 5px solid #999;
  opacity: 0.5;
}

li a {
  position: absolute;
  top: 2px;
  right: 5px;
  display: inline-block;
  width: 14px;
  height: 12px;
  border-radius: 14px;
  border: 6px double #FFF;
  background: #CCC;
  line-height: 14px;
  text-align: center;
  color: #FFF;
  font-weight: bold;
  font-size: 14px;
  cursor: pointer;
}

li button{
  position: absolute;
  right: 10px;
  top: 50%;
  transform: translateY(-50%);
}

footer {
  color: #666;
  font-size: 14px;
  text-align: center;
}

@media screen and (max-device-width: 620px) {
  section {
     width: 96%;
     padding: 0 2%;
  }
}

@media screen and (min-width: 620px) {
  section {
     width: 600px;
     padding: 0 10px;
  }
}

div部分

<div id="app">
    <header>
      <section>
        <label for="title">ToDoList</label>
        <input type="text" v-model="thing" placeholder="添加ToDo" required="required" autocomplete="off"
          @keydown.13="add" />
      </section>
    </header>
    <section>
      <h2>正在进行 <span>{{ongoing.length}}</span></h2>
      <ol id="todolist" class="demo-box">
        <li v-for="(item,index) in ongoing" :key="item.id">
          <input type="checkbox" @click="addToDone(index)">
          {{item.title}}
          <button @click="delGoing(index)">删除</button>
        </li>
      </ol>
      <h2>已经完成 <span>{{done.length}}</span></h2>
      <ul id="donelist">
        <li v-for="(item,index) in done " :key="item.id">
          <input type="checkbox" checked @click="addToGoing(index)">
          {{item.title}}
          <button @click="delDone(index)">删除</button>
        </li>
      </ul>
    </section>
  </div>
  <footer>
    Copyright &copy; 2021 todolist.cn
  </footer>

js代码

<script>
    //创建Vue实例,得到 ViewModel
    var vm = new Vue({
      el: '#app',
      data: {
        id: 4,
        //存储用户输入的信息
        thing: "",
        //正在进行 列表
        ongoing: [{
          id: 1,
          title: "吃饭"
        }, {
          id: 2,
          title: "睡觉"
        }],
        //已经完成 列表
        done: [{
          id: 3,
          title: "打豆豆"
        }]
      },
      methods: {
        //添加到待办事项
        add() {
          //组装一个对象,将对象添加到ongoing数组中。
          let obj = {
            id: this.id,
            title: this.thing
          };
          //新的对象产生,id自增,防止id重复。
          this.id++;
          this.ongoing.push(obj);
          //将thing的值设置为空,则输入框自动清空
          this.thing = "";
        },
        //添加到已经完成
        addToDone(index) {
          //将点击的数据 从ongoing 删除,添加到 Done中
          //splice(index,1)从index开始,删除一个元素。 splice会返回被删除的元素组成的数组。
          this.done.push(this.ongoing.splice(index,1)[0]);
        },
        //添加到 正在进行
        addToGoing(index){
          this.ongoing.push(this.done.splice(index,1)[0]);
        },
        //从正在进行中删除
        delGoing(index){
          this.ongoing.splice(index,1);
        },
        //从已经完成中删除
        delDone(index){
          this.done.splice(index,1);
        }
      }
    });
  </script>

案例:模态框
需求:
点击点赞 弹出登录页面
css部分

<style>
        #model-box {
            position: fixed;
            left: 0;
            top: 0;
            right: 0;
            bottom: 0;
            background-color: rgba(0, 0, 0, .2);
            display: flex;
            justify-content: center;
            align-items: center;
        }

        #center {
            width: 300px;
            height: 150px;
            background-color: aliceblue;
            display: flex;
            flex-direction: column;
            justify-content: space-evenly;
        }

        #center div {
            text-align: center;
        }
    </style>

div部分

 <div id="app">
        <button @click="like">点赞</button>
            <!-- .self:事件必须准确在自身触发才会执行事件处理函数。 -->
        <div id="model-box" v-show="isShow" @click.self="hideModel">
            <div id="center">
                <div>
                    用户名<input type="text">
                </div>
                   <!-- 可以在键盘事件中,使用按键修饰符, .按钮对应的code码 -->
                <div>
                    密&nbsp;&nbsp;&nbsp;码<input type="password" @keydown="login">
                </div>
                <div>
                    <button>登录</button>
                </div>
            </div>
        </div>
    </div>

js部分

 <script src="./vue.js"></script>
    <script>
        new Vue({ 
            el: "#app",
            data: {
                isShow:false
            },
            // 方法
            methods: {
                like() {
                    //将isShow的值变为true,则模态框就会显示
                    this.isShow = true;
                },
                hideModel() {
                    //点击登录窗口以外的区域,隐藏 模态框
                    this.isShow = false;
                },
                login(event) {
                    console.log(event.keyCode);
                    alert("登录")
                }
            }
        })
    </script>

简单购物车的实现
css部分

  <style>
        tr td {
            width: 90px;
            height: 30px;
            border: 1px solid gray;
            text-align: center;

        }

        tr td a {
            text-decoration: none;
            text-align: center;
            display: flex;
            width: 20px;
            height: 20px;
            background-color: rgba(0, 0, 0, 0.2);
            justify-content: space-evenly;

        }

        .five {
            display: flex;
            justify-content: space-evenly;
            align-items: center;
        }

        .sum {
            width: 160px;
            height: 30px;
            background-color: grey;
            display: flex;
            color: #fff;
            text-align: center;

        }

        .center {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            font-size: 48px;
        }
    </style>

body部分

  <div id="app">
        <table v-show="isShow">
            <tr>
                <td></td>
                <td>书籍名称</td>
                <td>出版日期</td>
                <td>价格</td>
                <td>购买数量</td>
                <td>小计</td>
                <td>操作</td>
            </tr>
            <tr v-for="(item,index) in datas" :key="item.id">
                <td>{{item.id}}</td>
                <td>{{item.name}}</td>
                <td>{{item.time}}</td>
                <td>${{item.price}}</td>
                <td class="five"><a href="#" @click="cut_down(index)">-</a>{{item.total}}<a href="#"
                        @click="add_a(index)">+</a></td>
                <td>${{item.sum}}</td>
                <td><button @click="del(index)">删除</button></td>
            </tr>

        </table>

        <div class="sum" v-show="isShow">
            总和:&nbsp;&nbsp;<i>{{isSum}}</i>
        </div>
        <div class="center">{{msg}}</div>
    </div>

js部分

 <script src="vue.js"></script>
    <script>
        new Vue({
            el: "#app",

            data: {
                msg: "",
                isShow: "false",
                datas: [{
                    id: 1,
                    name: "算法",
                    time: "2006-9",
                    price: "85.00",
                    sum: 85.00,
                    total: 1
                }, {
                    id: 2,
                    name: "unix",
                    time: "2020-9",
                    price: "59.00",
                    sum: 59.00,
                    total: 1
                }, {
                    id: 3,
                    name: "编程",
                    time: "2016-9",
                    price: "39.00",
                    sum: 39.00,
                    total: 1
                }]
            },
            methods: {
                //减
                cut_down(index) {
                    if (this.datas[index].total != 1) {
                        this.datas[index].total -= 1;
                        this.datas[index].sum = (this.datas[index].total) * this.datas[index].price
                    } else {
                        alert("不能再减少了")
                    }

                },
                //增加
                add_a(index) {
                    this.datas[index].total += 1;
                    this.datas[index].sum = (this.datas[index].total) * this.datas[index].price
                },

                del(index) {
                    this.datas.splice(index, 1);
                }
            },
            //计算属性
            computed: {
                isSum() {
                    let issum = 0;
                    for (var i = 0; i < this.datas.length; i++) {
                        issum += this.datas[i].sum;
                    }
                    if (this.datas.length < 1) {
                        this.isShow = false;
                        this.msg = "你的购物车为空"

                    }

                    return issum
                }

            }

        })
    </script>
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值