24-39 v-if/v-show;v-for;v-model

v-if 和v-show区别

v-if 是真正的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当的销毁重建
v-show不管初始条件是什么,元素总是会被渲染,并且只是简单基于css进行切换
v-show适用于页面多次切换;

在这里插入图片描述

小案例:登录方式切换

v-if方式

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="js/vue.js"></script>
</head>

<body>
    <div id ="app">
        <div v-if="logintype === 'phone'">
            <label >手机:</label>
            <input type="text" placeholder="请输入手机号"><br>
            <label >密码:</label> 
            <input type="password" placeholder="请输入密码">
        </div>
        <div v-else-if="logintype === 'email'">
            <label >email:</label>
            <input type="text" placeholder="请输入邮箱"><br>
            <label >密码:</label> 
            <input type="password" placeholder="请输入密码">
        </div>
        <button @click="change">切换登录方式</button>
    </div>
    <script>
     const app = Vue.createApp({
        data() {
            return{
                logintype:'phone'
            }
        },
        methods: {
            change(){
                this.logintype === 'phone'? this.logintype ='email': this.logintype ='phone'
            }
        }
     }).mount('#app');
    </script>
</body>

</html>

点击后会切换
在这里插入图片描述
在这里插入图片描述
v-show方式

        <div v-show="logintype === 'phone'">
            <label >手机:</label>
            <input type="text" placeholder="请输入手机号"><br>
            <label >密码:</label> 
            <input type="password" placeholder="请输入密码">
        </div>
        <div v-show="logintype === 'email'">
            <label >email:</label>
            <input type="text" placeholder="请输入邮箱"><br>
            <label >密码:</label> 
            <input type="password" placeholder="请输入密码">
        </div>
        <button @click="change">切换登录方式</button>

区别:当写完后切换,再切换回来原数据还是保留的
在这里插入图片描述

v-for 遍历数组

其中index,是数组自带的序列,在开发中很常见

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="js/vue.js"></script>
</head>

<body>
    <div id ="app">
        <!-- 遍历数组里的对象-->
        <ul>
            <li v-for="(p,index) in personArr">{{index}}--{{p}}</li>
        </ul>
        <p>--------------</p>
        <!-- 遍历对象 -->
        <ul>
            <li v-for ="(p,index) in persons">{{index}}--{{p}}---{{p.name}}</li>
        </ul>

    </div>
    <script>
     const app = Vue.createApp({
        data() {
            return{
                personArr:['哈哈',20,'你好啊'],
                persons:[
                    {name:'sana',age:20,add:'上海'},
                    {name:'anna',age:10,add:'北京'},
                    {name:'tina',age:30,add:'深圳'},

                ]
            }
        },
        methods: {}
     }).mount('#app');
    </script>
</body>

</html>

在这里插入图片描述

v-for 遍历对象

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="js/vue.js"></script>
</head>

<body>
    <div id ="app">
        <ul>
            <li v-for="item in preson">{{item}}</li>
        </ul>

        <p>--------</p>
        <ul>
            <li v-for="item,key in preson">{{key}}:{{item}}</li>
        </ul>
        <ul>
            <li v-for="item,key,index in preson">{{index}}--{{key}}:{{item}}</li>
        </ul>
    </div>
    <script>
     const app = Vue.createApp({
        data() {
            return{
                preson:{
                    name:'sana',
                    age:18,
                    friends:['张三','李四']
                }
            }
        },
        methods: {}
     }).mount('#app');
    </script>
</body>

</html>

在这里插入图片描述

v-if 和v-for 优先级对比

在2.0版本中 v-for 优先
在3.0版本中v-if优先
最好两个不要同时使用

v-for 案例

js函数参考链接:indexOf()
js函数参考链接:sort()
深度拷贝参考链接
深度拷贝参考链接2

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="js/vue.js"></script>
    <style>
        body{
            text-align: center;
        }
        ul li{
            list-style: none;
            line-height: 40px;
        }
    </style>
</head>

<body>
    <div id ="app">
        <h3>搜索列表</h3>
        <label><input v-model="searchStr" type="text" placeholder="输入搜索的姓名"></label>
        <div>
            <h3>排序</h3>
            <button @click="setOrderType(2)">age升序</button>
            <button @click="setOrderType(1)">age降序</button>
            <button @click="setOrderType(0)">还原</button>
        </div>
        <ul>
            <li v-for="(p,index) in filterPerson">
                {{index +1}}姓名:{{p.name}},性别:{{p.sex}},年龄:{{p.age}},手机:{{p.phone}}
            </li>
        </ul>
    </div>
    <script>
     const app = Vue.createApp({
        data() {
            return{
                persons:[
                    {name:'张三',sex:'女',age:16,phone:'12344321'},
                    {name:'李四',sex:'男',age:30,phone:'74634646'},
                    {name:'王五',sex:'女',age:20,phone:'32534688'},
                    {name:'吕一',sex:'男',age:41,phone:'98997866'},
                    {name:'赵云',sex:'男',age:60,phone:'34578734'}
                ],
                searchStr:"",
                // flag: 0:默认 ;1升序 ;2降序
                ordertype:0
            }
        },
        computed: {
            // 最常发生变化的是person数组
          filterPerson(){
            //   1、取出相关的属性
            const {persons,searchStr,ordertype} = this;
            // 2、定义过滤数组(深度拷贝成一个新的数组(这样两个数组互不影响))
            let arr=[...persons]; 
            // 3、根据条件过滤
            // trim去掉两边空格
            if(searchStr.trim()){
                arr = persons.filter((p)=>{
                    // indexOf() 方法可返回某个指定的字符串值在字符串中首次出现的位置。找不到返回-1
                    return p.name.indexOf(searchStr) !==-1;
                })
            }
            // 4、排序
            if(ordertype){
                arr.sort((p1,p2)=>{
                    // console.log(p1,p2);
                    if(ordertype === 1){
                        return p2.age - p1.age;
                    }
                    else{
                        return p1.age - p2.age;
                    }
                })
            }
            // 返回过滤后的数组
            return arr;
          }
        },
        methods: {
            setOrderType(ordertype){
                this.ordertype = ordertype;
            }
        }
     }).mount('#app');
    </script>
</body>

</html>

效果:可按照搜索值进行排序,点击降序、升序按年龄排序,还原清除排序
正常数据
在这里插入图片描述
搜索
在这里插入图片描述
升序
在这里插入图片描述

绑定key的原因和条件

当for循环后,需要插入或者修改其中一个,key作为作为标识,key最好是数字或者字符串类型
绑定key的条件,往中间或者头部追加或者修改,或者对记录需要做内部处理等情景下
例如

        <ul>
            <li v-for="(p,index) in filterPerson" :key="id">
                {{index +1}}姓名:{{p.name}},性别:{{p.sex}},年龄:{{p.age}},手机:{{p.phone}}
            </li>
        </ul>

绑定key可用于避免bug
例如未绑定key的话,插入后选择的会发生移位
例子:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="js/vue.js"></script>
</head>

<body>
    <div id ="app">
        <div>
            <label>ID:<input type="text" v-model="id" ></label>
            <label>Name:<input type="text" v-model="name"></label>
            <button @click="add">添加</button>
        </div>
        <ul>
            <li v-for="item in listarr" :key="item.id">
                <input type="checkbox">
                {{item.id}} ---- {{item.name}}
            </li>
        </ul>
    </div>
    <script>
     const app = Vue.createApp({
        data() {
            return{
                id:'',
                name:'',
                listarr:[
                    {id:1,name:'张三'},
                    {id:2,name:'李四'},
                    {id:3,name:'王五'},
                    {id:4,name:'赵六'},
                    {id:5,name:'刘七'},
                ]
            }
        },
        methods: {
            add(){
                // 尾部追加
                // this.listarr.push({id:this.id,name:this.name},)
                // 头部追加
                // this.listarr.unshift({id:this.id,name:this.name},)
                // 中间追加
                // splice()从第二个开始,删除0条
                this.listarr.splice(2,0,{id:this.id,name:this.name},)
            }

        }
     }).mount('#app');
    </script>
</body>

</html>

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
当插入了key值可以用于识别时
在这里插入图片描述
在这里插入图片描述

v-model的基础使用-实现表单元素和数据的双向绑定

表单-数据双向绑定
在这里插入图片描述

内部实现原理:先绑定一个值获取输入内容,在通过input自动的input时间动态输出event.target

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="js/vue.js"></script>
</head>

<body>
    <div id ="app">
        <input type="text" :value="msg" @input="valuechange">
        <!-- 简写方式 -->
        <input type="text" :value="msg" @input="msg=$event.target.value">
        <h1>{{msg}}</h1>

    </div>
    <script>
     const app = Vue.createApp({
        data() {
            return{
                msg:'hello'
            }
        },
        methods: {
            valuechange(event){
                this.msg = event.target.value;
            }
        }
     }).mount('#app');
    </script>
</body>

</html>

v-model常见操作

v-model 单选

两个选项只能选择其中一个,选择了就在下方显示值
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="js/vue.js"></script>
</head>

<body>
    <div id ="app">
        <label><input type="radio" value="男" name="sex" v-model="sex"></label>
        <label><input type="radio" value="女" name="sex" v-model="sex"></label>

        <p>-------------</p>

        <h2>选择的性别是{{sex}}</h2>

    </div>
    <script>
     const app = Vue.createApp({
        data() {
            return{
                // 默认是男
                sex:'男',
            }
        },
        methods: {}
     }).mount('#app');
    </script>
</body>

</html>

v-model 多选

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="js/vue.js"></script>
</head>

<body>
    <div id ="app">
        <!-- 1、勾选1-->
        <label ><input type="checkbox" v-model="isagree">同意xxx协议</label>
        <h2>是否同意协议:{{isagree?'同意':'不同意'}}</h2>
        <button :disabled="!isagree">注册</button>


        <p>========</p>
        <!-- 多选 -->
        <label>兴趣爱好</label>
        <input type="checkbox" value="篮球" v-model="habits">篮球
        <input type="checkbox" value="足球" v-model="habits">足球
        <input type="checkbox" value="羽毛球" v-model="habits">羽毛球
        <input type="checkbox" value="乒乓球" v-model="habits">乒乓球
        <h2>用户的兴趣爱好:{{habits}}</h2>




        <!--值绑定 -->
        <label v-for="star in starts" :for="star">
            <input type="checkbox" :value="star" :id="star" v-model="like">{{star}}
        </label>
        <h2>用户的兴趣爱好:{{like}}</h2>
    </div>
    <script>
     const app = Vue.createApp({
        data() {
            return{
                isagree:false,
                habits:[],
                starts:['周杰伦','蔡依林','刘德华'],
                like:[]
            }
        },
        methods: {}
     }).mount('#app');
    </script>
</body>

</html>

例子1:同意时,注册按钮可选择,常用于前端页面
在这里插入图片描述

例子2:多选,动态获取值,可用于服务器进行交互
在这里插入图片描述

例子3:更符合开发过程中,数据由后端提供,用变量注入,可以更方便的展示
在这里插入图片描述

v-model下拉

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="js/vue.js"></script>
</head>

<body>
    <div id ="app">
        <p>选择所在城市</p>
        <select name="city"  v-model="city">
            <option value="上海">上海</option>
            <option value="北京">北京</option>
            <option value="南京">南京</option>
        </select>
        <p>选择的城市是:{{city}}</p>

        <p>=========================</p>
        <p>选择所在城市</p>
        <select name="citys"  v-model="citys" multiple>
            <option value="上海">上海</option>
            <option value="北京">北京</option>
            <option value="南京">南京</option>
        </select>
        <p>选择的城市是:{{citys}}</p>
    </div>  
    <script>
     const app = Vue.createApp({
        data() {
            return{
                city:'北京',
                citys:[]
            }
        },
        methods: {}
     }).mount('#app');
    </script>
</body>

</html>

例子1:下拉单选,动态切换选择的
在这里插入图片描述
例子2:下拉多选,进行展示
在这里插入图片描述

v-model 使用修饰符

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="js/vue.js"></script>
</head>

<body>
    <div id ="app">
        <!-- 1、lazy -->
        <input type="text" v-model.lazy="msg">
        <h1>{{msg}}</h1>

        <!-- 2、number -->
        <input type="number" v-model.number="age">
        <h1>{{age}}=={{typeof age}}</h1>

        <!-- 3、trim -->
        <input type="text" v-model.trim="name">
        <h1>xxx{{name}}xxx</h1>

    </div>  
    <script>
     const app = Vue.createApp({
        data() {
            return{
                msg:"hello",
                age:18,
                name:''
            }
        },
        methods: {}
     }).mount('#app');
    </script>
</body>

</html>

lazy 可用于输入完之后再展示,避免频繁切换

在这里插入图片描述

number 强制为数字类型

在这里插入图片描述

trim 去除前后空格

在这里插入图片描述

指令小案例

先搭建静态页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="js/vue.js"></script>
</head>
<style>
    #app{
        margin: 50px auto;
        width: 600px;
    }
    fieldset{
        border:1px solid purple;
        margin-bottom: 20px;
    }
    fieldset input{
        width: 200px;
        height: 30px;
        margin: 10px 0;
    }
    table{
        width: 600px;
        border:2px solid purple;
        text-align: center;
    }
    thead{
        background-color: purple;
        color: #fff;
    }
</style>
<body>
    <div id ="app">
        <fieldset>
            <legend>信息录入系统(vue)</legend>
            <div>
                <label>姓名:<input type="text" placeholder="姓名"></label>
            </div>
            <div>
                <label>年龄:<input type="text" placeholder="年龄:"></label>
            </div>
            <div>
                <label>性别:
                    <select>
                        <option value="男"></option>
                        <option value="女"></option>
                    </select>
                </label>
            </div>
            <div>
                <label>手机:<input type="text" placeholder="手机"></label>
            </div>
            <button>创建新用户</button>
        </fieldset>
        
        <!-- 下部分 -->
        <table>
            <thead>
                <tr>
                    <td>姓名</td>
                    <td>性别</td>
                    <td>年龄</td>
                    <td>手机</td>
                    <td>删除</td>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>续航三</td>
                    <td></td>
                    <td>23</td>
                    <td>12414</td>
                    <td><button>删除</button></td>
                </tr>
            </tbody>
        </table>

    </div>
    <script>
     const app = Vue.createApp({
        data() {
            return{
                persons:[
                    {name:'jack',age:20,sex:'男',phone:'12345567'},
                    {name:'lily',age:17,sex:'女',phone:'54256445'},
                    {name:'sana',age:51,sex:'男',phone:'84624145'},

                ]
            }
        },
        methods: {}
     }).mount('#app');
    </script>
</body>

</html>

在这里插入图片描述
表单进行渲染,绑定事件,点击删除能删除


        <!-- 下部分 -->
        <table>
            <thead>
                <tr>
                    <td>姓名</td>
                    <td>性别</td>
                    <td>年龄</td>
                    <td>手机</td>
                    <td>删除</td>
                </tr>
            </thead>
            <tbody>
                <tr v-for="(p,index) in persons" :key="id">
                    <td>{{p.name}}</td>
                    <td>{{p.sex}}</td>
                    <td>{{p.age}}</td>
                    <td>{{p.phone}}</td>
                    <td><button @click="delP(index)">删除</button></td>
                </tr>
            </tbody>
        </table>

    </div>
    <script>
     const app = Vue.createApp({
        data() {
            return{
                persons:[
                    {id:1,name:'jack',age:20,sex:'男',phone:'12345567'},
                    {id:2,name:'lily',age:17,sex:'女',phone:'54256445'},
                    {id:3,name:'sana',age:51,sex:'男',phone:'84624145'},

                ]
            }
        },
        methods: {
            // 传递下标来识别,进行操作
            delP(index){
                this.persons.splice(index,1);
            }
        }
     }).mount('#app');
    </script>
</body>

</html>

在这里插入图片描述

在这里插入图片描述
完整代码
实现效果:数据不能为空,可新增记录,下方可删除记录

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="js/vue.js"></script>
</head>
<style>
    #app{
        margin: 50px auto;
        width: 600px;
    }
    fieldset{
        border:1px solid purple;
        margin-bottom: 20px;
    }
    fieldset input{
        width: 200px;
        height: 30px;
        margin: 10px 0;
    }
    table{
        width: 600px;
        border:2px solid purple;
        text-align: center;
    }
    thead{
        background-color: purple;
        color: #fff;
    }
</style>
<body>
    <div id ="app">
        <fieldset>
            <legend>信息录入系统(vue)</legend>
            <div>
                <label>姓名:<input type="text" placeholder="姓名" v-model.trim="newperson.name"></label>
            </div>
            <div>
                <label>年龄:<input type="text" placeholder="年龄:" v-model.trim="newperson.age"></label>
            </div>
            <div>
                <label>性别:
                    <select v-model="newperson.sex">
                        <option value="男"></option>
                        <option value="女"></option>
                    </select>
                </label>
            </div>
            <div>
                <label>手机:<input type="text" placeholder="手机" v-model.trim="newperson.phone"></label>
            </div>
            <button @click="addnewp">创建新用户</button>
        </fieldset>
        
        <!-- 下部分 -->
        <table>
            <thead>
                <tr>
                    <td>姓名</td>
                    <td>性别</td>
                    <td>年龄</td>
                    <td>手机</td>
                    <td>删除</td>
                </tr>
            </thead>
            <tbody>
                <tr v-for="(p,index) in persons" >
                    <td>{{p.name}}</td>
                    <td>{{p.sex}}</td>
                    <td>{{p.age}}</td>
                    <td>{{p.phone}}</td>
                    <td><button @click="delP(index)">删除</button></td>
                </tr>
            </tbody>
        </table>

    </div>
    <script>
     const app = Vue.createApp({
        data() {
            return{
                persons:[
                    {id:1,name:'jack',age:20,sex:'男',phone:'12345567'},
                    {id:2,name:'lily',age:17,sex:'女',phone:'54256445'},
                    {id:3,name:'sana',age:51,sex:'男',phone:'84624145'},

                ],
                newperson:[
                {name:'',age:'',sex:'',phone:''},
                ]
            }
        },
        methods: {
            // 传递下标来识别,进行操作
            delP(index){
                this.persons.splice(index,1);
            },
            // 增加一条新记录
            addnewp(){
                const {name,age,sex,phone}=this.newperson;
                // 1、判断
                if(!name||!age||!sex||!phone){
                    alert("输入数据不完整")
                    return
                }
                // 2、插入一条新纪录
                this.persons.unshift(this.newperson)
                // 3、清空
                this.newperson=""
            }
        }
     }).mount('#app');
    </script>
</body>

</html>

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值