Vue基础技能【三、购物车案例、表单相关、生命周期、学生信息系统案例】

1、Vue实现购物车

  • 核心:

    • 每个列表先需要添加一个check属性,用于选中。 注意使用 $set进行添加,不然不会响应
    • watch监听数组的变化
    • 注意不要使用 computed对数组进行加工。
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>原生JS实现购物车功能</title>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    </head>
    <body>
        <table align="center" width="600" border="1" id="app">
                
            <thead>
                <tr>
                    <td>全选 <input type="checkbox" :checked="isallCheck" @click="allcheck" ></td>
                    <td>名称</td>
                    <td>价格</td>
                    <td>数量</td>
                    <td>小计</td>
                    <td>操作</td>
                </tr>
            </thead>
            <tbody>
                <tr v-for="(item,index) in arr" :key="index">
                    <td>
                        <input type="checkbox" @click="rowCheck(item,$event)" :checked="item.check" >
                    </td>
                    <td>{{item.title}}</td>
                    <td>{{item.price}}</td>
                    <td>
                        <button @click="reduce(item)">-</button>
                        <input type="text" style="width:40px;text-align:center;" :value="item.nums">
                        <button @click="add(item)">+</button>
                    </td>
                    <td>
                        {{ item.price * item.nums }}
                    </td>
                    <td>
                        <button @click="del(index)">删除</button>
                    </td>
                </tr>
            </tbody>
            <tfoot>
                <tr>
                    <td>
                        全选 <input type="checkbox" :checked="isallCheck" @click="allcheck">
                    </td>
                    <td colspan="5" style="text-align: right;"><span>{{allnum}} </span> 件商品,共计 <span>{{ allprice.toFixed(2) }}</span><button>立即结算</button>
                    </td>
                </tr>
               
            </tfoot>
        </table>
    </body>
    <script>
        let vm =  new Vue({
            el:"#app",
            data :{
                allnum:0,
                allprice:0,
                isallCheck:false,
                arr:[
                    {
                        title:"苹果6",
                        price:2000,
                        nums:1
                    },
                    {
                        title:"华为p30",
                        price:4000,
                        nums:1
                    },
                    {
                        title:"vivo X9",
                        price:3000,
                        nums:1
                    },
                    {
                        title:"oppro R9",
                        price:3000,
                        nums:1
                    }
                ]
            },
            created:function(){
                console.log("自己执行啊");
                
            },
            watch:{
                arr:{
                    deep:true,
                    handler(){
                       // 判断是否全选,如果list中每一个都是true那么就全选
                       let state = true;  // 全选状态
                       let allnum = 0;
                       let allprice  =0 ;
    
                       this.arr.map(val=>{
                           if(!val.check){  // 没有选中
                               state = false;
                           }else{  // 选中
                             allnum++;
                             allprice += (val.nums*val.price)
                           }
                       })
                       if(!this.arr.length){
                           state = false;
                       }
                       this.isallCheck = state;
                       this.allnum = allnum;
                       this.allprice = allprice;
                    }
                }
            },
            methods:{
                add(row){ // 添加
                    row.nums++
                    row.check = true;
                },
                reduce(row){ // 减少
                    if(row.nums==1){
                        return;
                    }
                    row.nums--;
                    row.check = true;
                },
                allcheck(ev){ // 全选
                    this.isallCheck = ev.target.checked
                    this.arr = this.arr.map(val=>{
                        val.check = ev.target.checked; 
                        return val;
                    });
                },
                rowCheck(row,ev){ // 单选
                    row.check = ev.target.checked;
                },
                del(idx){
                    this.arr.splice(idx,1)
                }
            }
        })  
        // 直接修改data中的数组
        vm.arr = vm.arr.map(val=>{
            vm.$set(val,'check',false)
            return val;
        })
          
        // 希望页面已进入 data中的arr中的每个都加上一个check属性。而不是依赖于计算属性实现。
    
        //  let newarr = arr.map(function(val,key){  return val+1 })
        // 遍历 arr每个数据都加1,返回一个新数组
    </script>
    </html>
    
    

2、表单知识

2.1、核心指令 v-model

  • 所有控件添加上 v-model指令绑定一个变量

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    </head>
    <body>
        <div id="app">
            <!-- <input type="text" @keyup="change">{{nums}} -->
    
            <input type="text" v-model="nums" >{{nums}}
    
        </div>
    </body>
    <script>
        // new Vue({
        //     el:"#app",
        //     data:{
        //         nums:200
        //     },
        //     methods:{
        //         change(ev){
        //             console.log(ev.target.value);
        //             this.nums = ev.target.value
        //         }
        //     }
        // })
    
    
        new Vue({
            el:"#app",
            data:{
                nums:200
            }
        })
    
    
        // 表单   双向数据绑定!!!
        // 核心指令   v-model
    
    </script>
    </html>
    
  • 不同的控件绑定稍微有所不同

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    </head>
    <body>
        <div id="app">
            姓名: <input type="text" v-model="xm" >{{xm}}    <br>
            性别: 
                <label for=""><input type="radio" v-model="sex" value="1"></label>
                <label for=""><input type="radio" v-model="sex" value="0"></label>
                {{sex}}
                <br>
            爱好: 
                <label for=""><input v-model="ah" value="lq" type="checkbox">篮球</label>
                <label for=""><input v-model="ah"  value="zq" type="checkbox">足球</label>
                <label for=""><input v-model="ah" value="ymq" type="checkbox">羽毛球</label>
                <label for=""><input v-model="ah" value="pq" type="checkbox">皮球</label>
                {{ah}}
                <br>
            是否成年:<input type="checkbox" v-model="cn">{{cn}}
                <br>
            家乡: 
                <select v-model="jx">
                    <option value="0">请选择</option>
                    <option value="bj">北京</option>
                    <option value="nj">南京</option>
                    <option value="tj">天津</option>
                    <option value="hf">合肥</option>
                </select>
                {{jx}}
                <br>
            想去的地方:
                <select v-model="ly"  multiple   size="5">
                    <option value="dj">东京</option>
                    <option value="ny">纽约</option>
                    <option value="ld">伦敦</option>
                    <option value="ylk">伊拉克</option>
                </select>
                {{ly}}
                 <br>
            想说的话:
                <textarea v-model="text"  cols="30" rows="5"></textarea>{{text}}
                <br>
              <button>提交</button>  
        </div>
    </body>
    <script>
        new Vue({
            el:"#app",
            data:{
                xm:"张飞",
                sex:"1",
                ah:['ymq','lq'],
                cn:false,
                jx:"tj",
                ly:['ny','ylk'],
                text:""
            }
        })
     // 表单   双向数据绑定!!!
        // 核心指令   v-model
    
    
        // 文本框、密码框、多行文本输入框      v-model 的变量 直接和 控件的value进行绑定,不需要描述value
        // 单选框     同一组单选  v-model绑定相同变量  该变量是个具体的值    且每个单选项需要指定value值,  value值和v-model绑定的变量值相同的话,该控件被选中
        // 多选框 多选    同一组多选  v-model绑定相同变量  该变量数个数组      且每个多选项需要指定value值,  value值和v-model绑定的数组变量值里面的值相同的话,该控件被选中
        // 多选框 勾中    v-model绑定一个布尔变量     无需指定value, 自动获取true或者false
        // 下拉框:
            // 单选         v-model 绑定一个变量     如果option有value,那么v-model绑定的变量将获取value的值,如果没有value那么将获取option标签之间的文本。    
            // 多选         v-model 绑定一个数组变量  如果数组中有值,那么对应的option将会被选中,如果没有值,将会去对应的option的value或者标签之间的内容    
    
        // 注意: 单选  和  多选  需要每个控件项都需要有对应的value
    </script>
    </html>
    

2.2、表单修饰符

  • 修饰符,帮助我们对绑定的数据进行一些处理。 将字符串变成数字,去除两端的空格等等

  • 使用:

    <input type="text" v-model.修饰符="变量" />
    
  • 那些修饰符?

    • number v-model.number = “变量” 将字符串变成数字

    • trim v-model.trim=“变量” 去除两端的空格

    • lazy v-model.lazy=“变量” 在“change”时触发更新 而非“input”时更新

3、生命周期

3.1、又称生命周期钩子

3.2、掌握内容

  • 有哪些阶段

  • 该阶段有哪些函数

  • 该阶段我们能获取到Vue实例里面什么东西

  • 该阶段我们在工作用一般干什么

3.3、四个阶段

  • 创建阶段

    • 创建之前: beforeCreate 一进入就要做得事情, 但是这里无法获取data,也没有挂载
    • 创建之后:created 数据请求 可以访问data了,也没挂载
  • 挂载阶段

    • 挂载之前:beforeMount 挂载之前要做的事 可以访问data,没挂载成功了
    • 挂载之后:mounted 去初始化一些外部插件 可以访问data,挂载成功了
  • 更新阶段

    • 更新之前:beforeUpdate 判断是否要更新 刷新判断 可以访问data,挂载成功
    • 更新之后:updated 更新之后要做的事情 可以访问data,挂载成功的
  • 消亡阶段

    • 消亡之前:beforeDestroy 判断是否保存 可以访问data,挂载成功

    • 消亡之后: destroyed 清楚变量、定时器、 等等

3.4、生命周期图

在这里插入图片描述

4、学生信息案例

4.1、 技术点内容

  • 本地存储
  • 跨页面之间传值
  • 增删改查
  • Vue绑定数据
  • Vue数据渲染

4.2、代码

  • 添加页面

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <title>添加</title>
        <link href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" rel="stylesheet">
        <style>
            .form-control{
                width: 75%;
            }
        </style>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    </head>
    
    <body>
        <div class="container" id="app">
            <h3 class="text-center "><a class="btn btn-success pull-left" href="javascript:history.go(-1);">&lt;返回</a>  添加学生记录</h3>
            <hr>
            <div class="row">
                <div class="col-md-6 col-md-offset-3">
                    <form class="form-horizontal">
                        <div class="form-group">
                            <label for="" class="col-md-3 control-label">姓名</label>
                            <input type="text" v-model.trim="userInfo.username" class="col-md-9 form-control ">
                        </div>
                        <div class="form-group">
                            <label for="" class="col-md-3 control-label">密码</label>
                            <input type="password" v-model.trim="userInfo.password" class="col-md-9 form-control ">
                        </div>
                        <div class="form-group">
                            <label for="" class="col-md-3 control-label">性别</label>
                            <div class="radio">
                                <label>
                                    <input type="radio" v-model.number="userInfo.sex" value="1" ></label>
                                <label>
                                    <input type="radio" v-model.number="userInfo.sex"  value="0" ></label>
                            </div>
                        </div>
                        <div class="form-group">
                            <label for="" class="col-md-3 control-label">爱好</label>
                            <div class="checkbox">
                                <label><input type="checkbox" v-model="userInfo.ah" value="篮球">篮球</label>
                                <label><input type="checkbox"  v-model="userInfo.ah" value="足球">足球</label>
                                <label><input type="checkbox"  v-model="userInfo.ah" value="羽毛球">羽毛球</label>
                                <label><input type="checkbox"  v-model="userInfo.ah" value="排球">排球</label>
                            </div>
                        </div>
                        <div class="form-group">
                            <label for="" class="col-md-3 control-label">是否成年</label>
                            <div class="checkbox">
                                <label><input type="checkbox" v-model="userInfo.isdr" >成年请勾选</label>
                            </div>
                        </div>
                        <div class="form-group">
                            <label for="" class="col-md-3 control-label">家乡</label>
                            <select class="col-md-9 form-control " v-model="userInfo.from">
                                <option value="0">---请选择---</option>
                                <option>北京</option>
                                <option>天津</option>
                                <option>南京</option>
                            </select>
                        </div>
                        <div class="form-group">
                                <label for="" class="col-md-3 control-label">想去的城市</label>
                                <select v-model="userInfo.city" multiple class="col-md-9 form-control ">
                                    <option >东京</option>
                                    <option >纽约</option>
                                    <option >伦敦</option>
                                    <option>伊拉克</option>
                                </select>
                            </div>
                        <div class="form-group">
                            <label for="" class="col-md-3 control-label">个性签名</label>
                            <textarea v-model="userInfo.desc" class="form-control" rows="3"></textarea>
                        </div>
                        <button type="submit" @click.prevent="add" class="btn btn-primary col-md-offset-3" >添加</button>
                    </form>
                </div>
            </div>
        </div>
    </body>
    <script>
        new Vue({
            el:"#app",
            data:{
                userInfo:{
                    username:"",
                    password:"",
                    sex:1,
                    ah:[],
                    isdr:false,
                    from:0,
                    city:[],
                    desc:""
                }
            },
            methods:{
                add(){
                    if(!this.userInfo.username || !this.userInfo.password){
                       alert("至少输入姓名和密码");
                       return; 
                    }
                    let data = localStorage.getItem("studentData");
                    if(data){ // 不是第一次
                        console.log(data);
                        data = JSON.parse(data);  // 原来的数据
                        data.push(this.userInfo);
                    }else{  //第一次
                        data = [this.userInfo];
                    }
                    localStorage.setItem('studentData',JSON.stringify(data));
                    // window.location.reload();
                    window.location.href = "list.html"
                }
            }
        })
    
    </script>
    </html>
    
  • 列表页面

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>学生信息记录</title>
        <link href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" rel="stylesheet">
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    </head>
    <body>
        <div class="container" id="app">
            <h3 class="text-center">学生信息记录  <a href="add.html" class="btn btn-success pull-right">添加记录</a></h3>
           <hr>
           <br>
            <table class="table table-bordered">
                <thead>
                    <th>姓名</th>
                    <th>密码</th>
                    <th>性别</th>
                    <th>是否成年</th>
                    <th>爱好</th>
                    <th>家乡</th>
                    <th>操作</th>
                </thead>
                <tbody>
                    <template v-if="list.length">
                        <tr  v-for="(item,index) in list">
                            <td>{{item.username}}</td>
                            <td>{{item.password}}</td>
                            <td>{{ item.sex ? '男':'女' }}</td>
                            <td>{{ item.isdr ? "成年" : "小孩" }}</td>
                            <td>{{ item.ah.join(",") }}</td>
                            <td>{{ item.from ? item.from : '来自远方' }}</td>
                            <td>
                                <button @click="go(index,'info')" class="btn-success">查看</button>
                                <button @click="go(index,'edit')"  class="btn-primary">修改</button>
                                <button @click="del(index)" class="btn-danger">删除</button>
                            </td>
                        </tr>
                    </template>
                    <template v-else>
                        <tr>
                            <td colspan="7" class="text-center">没有数据</td>
                        </tr>
                    </template>
                </tbody>
            </table>
        </div>
    </body>
    <script>
        new Vue({
            el:"#app",
            data:{
                list:[]
            },
            created(){
                if(localStorage.getItem("studentData")){
                    this.list = JSON.parse( localStorage.getItem("studentData") );
                }
            },
            methods:{
                del(idx){// 删除
                    if(!window.confirm("是否要删除")){
                        return;
                    }
                    this.list.splice(idx,1);  // 删除页面
                    let localList = JSON.parse( localStorage.getItem("studentData") );
                    localList.splice(idx,1); // 删除本地
                    localStorage.setItem("studentData",JSON.stringify(localList)); // 放回去
                }, 
                go(idx,str){ // 查看
                    location.href = str+".html?id="+idx;
                }
            }
        })
    </script>
    </html>
    
  • 删除功能

    • 见列表页面
  • 修改功能(添加逻辑一致)

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <title>修改</title>
        <link href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" rel="stylesheet">
        <style>
            .form-control{
                width: 75%;
            }
        </style>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    </head>
    
    <body>
        <div class="container" id="app">
            <h3 class="text-center "><a class="btn btn-success pull-left" href="javascript:history.go(-1);">&lt;返回</a> 修改学生记录</h3>
            <hr>
            <div class="row">
                <div class="col-md-6 col-md-offset-3">
                    <form class="form-horizontal">
                        <div class="form-group">
                            <label for="" class="col-md-3 control-label">姓名</label>
                            <input type="text" v-model.trim="userInfo.username" class="col-md-9 form-control ">
                        </div>
                        <div class="form-group">
                            <label for="" class="col-md-3 control-label">密码</label>
                            <input type="password" v-model.trim="userInfo.password" class="col-md-9 form-control ">
                        </div>
                        <div class="form-group">
                            <label for="" class="col-md-3 control-label">性别</label>
                            <div class="radio">
                                <label>
                                    <input type="radio" v-model.number="userInfo.sex" value="1" ></label>
                                <label>
                                    <input type="radio" v-model.number="userInfo.sex"  value="0" ></label>
                            </div>
                        </div>
                        <div class="form-group">
                            <label for="" class="col-md-3 control-label">爱好</label>
                            <div class="checkbox">
                                <label><input type="checkbox" v-model="userInfo.ah" value="篮球">篮球</label>
                                <label><input type="checkbox"  v-model="userInfo.ah" value="足球">足球</label>
                                <label><input type="checkbox"  v-model="userInfo.ah" value="羽毛球">羽毛球</label>
                                <label><input type="checkbox"  v-model="userInfo.ah" value="排球">排球</label>
                            </div>
                        </div>
                        <div class="form-group">
                            <label for="" class="col-md-3 control-label">是否成年</label>
                            <div class="checkbox">
                                <label><input type="checkbox" v-model="userInfo.isdr" >成年请勾选</label>
                            </div>
                        </div>
                        <div class="form-group">
                            <label for="" class="col-md-3 control-label">家乡</label>
                            <select class="col-md-9 form-control " v-model="userInfo.from">
                                <option value="0">---请选择---</option>
                                <option>北京</option>
                                <option>天津</option>
                                <option>南京</option>
                            </select>
                        </div>
                        <div class="form-group">
                                <label for="" class="col-md-3 control-label">想去的城市</label>
                                <select v-model="userInfo.city" multiple class="col-md-9 form-control ">
                                    <option >东京</option>
                                    <option >纽约</option>
                                    <option >伦敦</option>
                                    <option>伊拉克</option>
                                </select>
                            </div>
                        <div class="form-group">
                            <label for="" class="col-md-3 control-label">个性签名</label>
                            <textarea v-model="userInfo.desc" class="form-control" rows="3"></textarea>
                        </div>
                        <button type="submit" @click.prevent="eidt" class="btn btn-danger col-md-offset-3" >修改</button>
                    </form>
                </div>
            </div>
        </div>
    </body>
    <script>
        new Vue({
            el:"#app",
            data:{
                userInfo:{
                    username:"",
                    password:"",
                    sex:1,
                    ah:[],
                    isdr:false,
                    from:0,
                    city:[],
                    desc:""
                },
                idx:""
            },
            created(){
                let id = location.search.split("=")[1]
                this.idx  = id;
                let studentData = localStorage.getItem("studentData");
                studentData = JSON.parse(studentData);
                this.userInfo = studentData[id];
            },
            methods:{
                eidt(){
                    if(!this.userInfo.username || !this.userInfo.password){
                       alert("至少输入姓名和密码");
                       return; 
                    }
                    let data = localStorage.getItem("studentData");// 本地的学生数据
                    data = JSON.parse(data);
                    data[this.idx] = this.userInfo
                    localStorage.setItem('studentData',JSON.stringify(data));
                    window.location.href = "list.html"
                }
            }
        })
    
    </script>
    </html>
    
  • 详情页面

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <title>学生信息详情</title>
        <link href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" rel="stylesheet">
        <style>
            .form-control {
                width: 75%;
            }
        </style>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    
    </head>
    
    <body>
        <div class="container" id="app">
            <h3 class="text-center "> 学生信息 <a class="btn btn-success pull-left" href="javascript:history.go(-1);">&lt;返回</a>
            </h3>
            <hr>
            <div class="row">
                <div class="col-md-6 col-md-offset-3">
                    <form class="form-horizontal">
                        <div class="form-group">
                            <label for="" class="col-md-3 control-label">姓名</label>
                            <input type="text" readonly v-model="userInfo.username" class="col-md-9 form-control ">
                        </div>
                        <div class="form-group">
                            <label for="" class="col-md-3 control-label">密码</label>
                            <input type="password" readonly v-model="userInfo.password" class="col-md-9 form-control ">
                        </div>
                        <div class="form-group">
                            <label for="" class="col-md-3 control-label">性别</label>
                            <div class="radio">
                                {{ userInfo.sex ? "男":"女" }}
                            </div>
                        </div>
                        <div class="form-group">
                            <label for="" class="col-md-3 control-label">爱好</label>
                            <div class="checkbox">
                                {{ userInfo.ah.join(",")}}
                            </div>
                        </div>
                        <div class="form-group">
                            <label for="" class="col-md-3 control-label">是否成年</label>
                            <div class="checkbox">
                                {{ userInfo.isdr ? "成年":"小孩" }}
                            </div>
                        </div>
                        <div class="form-group">
                            <label for="" class="col-md-3 control-label">家乡</label>
                            {{userInfo.from ? userInfo.from : "来自远方"}}
                        </div>
                        <div class="form-group">
                            <label for="" class="col-md-3 control-label">想去的城市</label>
                            {{userInfo.city.join(",")}}
                        </div>
                        <div class="form-group">
                            <label for=""  class="col-md-3 control-label">个性签名</label>
                            <textarea readonly v-model="userInfo.desc" class="form-control" rows="3"></textarea>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </body>
    <script>
        new Vue({
            el: "#app",
            data: {
                userInfo: {
                    username: "",
                    password: "",
                    sex: "1",
                    ah: [],
                    isdr: false,
                    from: "",
                    city: [],
                    desc: ""
                }
            },
            created(){
                let id = location.search.split("=")[1]
                let studentData = localStorage.getItem("studentData");
                studentData = JSON.parse(studentData);
                this.userInfo = studentData[id];
            }
        })
    </script>
    
    </html>
    
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值