Vue基础总结(4) | 青训营笔记

121 阅读4分钟

这是我参与「第四届青训营 」笔记创作活动的第4天

十一、绑定样式

1、绑定class样式

:class="xxx" xxx可以是字符串、对象、数组。

字符串写法适用于:类名不确定,要动态获取。

数组写法适用于:要绑定多个样式,个数不确定,名字也不确定。

对象写法适用于:要绑定多个样式,个数确定,名字也确定,但不确定用不用。

2、绑定style样式

对象写法 :style="{fontSize: xxx}" 或 :style="styleObj" 其中xxx是动态值。

数组写法 :style="[a,b]" 其中a、b是样式对象。

十二、条件渲染

条件渲染: 

 1、v-if 

 (1)v-if="表达式" 

 (2)v-else-if="表达式" 

 (3)v-else="表达式" 

 适用于:切换频率较低的场景 

 特点:不展示的DOM元素直接被移除 

 注意:v-if可以和v-else-if、v-else一起使用,但要求结构不能被打断 

 2、v-show v-show="表达式" 

 适用于:切换频率较高的场景 

 特点:不展示的DOM元素未被移除,仅仅是隐藏使用样式 

 3、备注 使用v-if时,元素可能无法获取到,而使用v-show一定可以获取到元素。

十三、列表渲染

1、基本列表

 v-for指令 

 1、用于展示列表数据 

 2、语法 v-for="(item,index) in xxx" :key="yyy" 

 3、可遍历:数组(常用)、对象(常用)、字符串、指定次数

<!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>
    <!-- 引入vue -->
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>

    <!-- 准备好一个容器 -->
    <div id="root">
        <!-- 遍历数组 -->
        <h2>人员列表</h2>
        <ul>
            <li v-for="p in personArr" :key="p.id"> 
            <!-- <li v-for="(p,index) in personArr" :key="index"> -->
                {{p.name}}-{{p.age}}
            </li>
        </ul>

        <!-- 遍历对象 -->
        <h2>汽车信息</h2>
        <ul>
            <li v-for="(value,key) in car" :key="key"> 
                {{key}}-{{value}}
            </li>
        </ul>

        <!-- 遍历字符串 -->
        <h2>测试遍历字符串</h2>
        <ul>
            <li v-for="(char,index) in str" :key="index"> 
                {{index}}-{{char}}
            </li>
        </ul>

        <!-- 遍历指定次数 -->
        <h2>测试遍历指定次数</h2>
        <ul>
            <li v-for="(number,index) in 5" :key="index"> 
                {{index}}-{{number}}
            </li>
        </ul>
    </div>
</body>

<script type="text/javascript">
    Vue.config.productionTip = false // 阻止vue在启动时生成生产提示

    new Vue({
        el:'#root',
        data:{
            personArr:[
                {id:'001',name:'张三',age:18},
                {id:'002',name:'李四',age:20},
                {id:'003',name:'王五',age:19},
            ],
            car:{
                name:'兰博基尼',
                pirce:'20元',
                coler:'白色',
            },
            str:'hello'
        }
    })
</script>

</html>

2、key的原理

面试题:react、vue中的key有什么作用? (key的内部原理) 

 1、虚拟DOM中key的作用:

key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】, 随后Vue进行【新虚拟DOM】与【旧虚拟DOM】的差异比较,比较规则如下: 

 2、对比规则:

 (1)旧虚拟DOM中找到了与新虚拟DOM相同的key: 若虚拟DOM中内容没变,直接使用之前的真实DOM 若虚拟DOM中内容变了,则生成新的真实DOM,随后替换掉页面中之前的真实DOM 

 (2).旧虚拟DOM中未找到与新虚拟DOM相同的key: 创建新的真实DOM,随后渲染到到页面 

 3、用index作为key可能会引发的问题: 

 (1)若对数据进行:逆序添加、逆序删除等破坏顺序操作: 会产生没有必要的真实DOM更新 ==> 界面效果没问题,但效率低 

 (2)如果结构中还包含输入类的DOM: 会产生错误DOM更新 ==> 界面有问题 

 4、开发中如何选择key? 

 (1)最好使用每条数据的唯一标识作为key,比如id、手机号、身份证号、学号等唯一值 

 (2)如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示,使用index作为key是没有问题的。

<!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>
    <!-- 引入vue -->
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>

    <!-- 准备好一个容器 -->
    <div id="root">
        <!-- 遍历数组 -->
        <h2>人员列表</h2>
        <button @click.once="add">添加一个老刘</button>
        <ul>
            <li v-for="p in personArr" :key="p.id"> 
            <!-- <li v-for="(p,index) in personArr" :key="index"> -->
                {{p.name}}-{{p.age}}
                <input>
            </li>
        </ul>
    </div>
</body>

<script type="text/javascript">
    Vue.config.productionTip = false // 阻止vue在启动时生成生产提示

    new Vue({
        el:'#root',
        data:{
            personArr:[
                {id:'001',name:'张三',age:18},
                {id:'002',name:'李四',age:20},
                {id:'003',name:'王五',age:19},
            ]
        },
        methods: {
            add(){
                const p = {id:'004',name:'老刘',age:'200'}
                this.personArr.unshift(p) // 添加到原数组最上方
            }
        },
    })
</script>

</html>

3、列表过滤

以下为使用监视和计算属性实现的两种方法:

<!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>
    <!-- 引入vue -->
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>

    <!-- 准备好一个容器 -->
    <div id="root">
        <h2>人员列表</h2>
        <input type="text" placeholder="请输入名字" v-model="keyWord">
        <ul>
            <li v-for="p in filPersonArr" :key="p.id"> 
            <!-- <li v-for="(p,index) in personArr" :key="index"> -->
                {{p.name}}-{{p.age}}-{{p.sex}}
            </li>
        </ul>
    </div>
</body>

<script type="text/javascript">
    Vue.config.productionTip = false // 阻止vue在启动时生成生产提示

    new Vue({
        el:'#root',
        data:{
            keyWord:'',
            personArr:[
                {id:'001',name:'马冬梅',age:18,sex:'女'},
                {id:'002',name:'周冬雨',age:20,sex:'女'},
                {id:'003',name:'周杰伦',age:19,sex:'男'},
                {id:'004',name:'温兆伦',age:13,sex:'男'},
            ],
            // filPersonArr:[]
        },
        // watch:{
        //     keyWord:{
        //         immediate:true,
        //         handler(value){
        //             this.filPersonArr = this.personArr.filter((p)=>{ // filter()方法创建一个新的数组,新数组中元素是通过检查指定数组中符合条件的元素,原数组不受影响
        //             return p.name.indexOf(value) !== -1 // .indexOf('')返回值是0
        //         })
        //         }
        //     }
        // }
        computed:{
            filPersonArr(){
                return this.personArr.filter((p)=>{ 
                    return p.name.indexOf(this.keyWord) !== -1 
            })
        }
    }
    })
</script>

</html>

4、列表排序

<!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>
    <!-- 引入vue -->
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>

    <!-- 准备好一个容器 -->
    <div id="root">
        <h2>人员列表</h2>
        <input type="text" placeholder="请输入名字" v-model="keyWord">
        <button @click="sortType = 2">年龄升序</button>
        <button @click="sortType = 1">年龄降序</button>
        <button @click="sortType = 0">原顺序</button>
        <ul>
            <li v-for="p in filPersonArr" :key="p.id"> 
            <!-- <li v-for="(p,index) in personArr" :key="index"> -->
                {{p.name}}-{{p.age}}-{{p.sex}}
            </li>
        </ul>
    </div>
</body>

<script type="text/javascript">
    Vue.config.productionTip = false // 阻止vue在启动时生成生产提示

    new Vue({
        el:'#root',
        data:{
            keyWord:'',
            sortType:0, // 0是原顺序,1是降序,2是升序
            personArr:[
                {id:'001',name:'马冬梅',age:18,sex:'女'},
                {id:'002',name:'周冬雨',age:20,sex:'女'},
                {id:'003',name:'周杰伦',age:19,sex:'男'},
                {id:'004',name:'温兆伦',age:13,sex:'男'},
            ],
        },
        computed:{
            filPersonArr(){
                const arr = this.personArr.filter((p)=>{ 
                    return p.name.indexOf(this.keyWord) !== -1 
            })
            // 判断是否需要排序
            if(this.sortType){
                arr.sort((p1,p2)=>{ // .sort((a,b)=>{}) a-b是升序排列,b-a是降序排列
                    return this.sortType === 1 ? p2.age-p1.age : p1.age-p2.age
                })
            }
            return arr
        }
    }
    })
</script>

</html>

十四、收集表单数据

收集表单数据: 

 若:,则v-model收集的是value值,用户输入的就是value值。 

 若:,则v-model收集的是value值,且要给标签配置value值。 

 若: 

 1、没有配置input的value属性,那么收集的就是checked(勾选or未勾选,是布尔值) 

 2、配置input的value属性: 

 (1)v-model的初始值是非数组,那么收集的就是checked(勾选 or未勾选,是布尔值) 

 (2)v-model的初始值是数组,那么收集的的就是value组成的数组 

 备注:v-model的三个修饰符:

 lazy:失去焦点再收集数据 

 number:输入字符串转为有效的数字 

 trim:输入首尾空格过滤 

<!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>
    <!-- 引入vue -->
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>

    <!-- 准备好一个容器 -->
    <div id="root">
        <form  @submit.prevent="demo">
            账号:<input type="text" v-model="userInfo.account"> <br/><br/>
            密码:<input type="password" v-model="userInfo.password"> <br/><br/>
            性别:
            男<input type="radio" name="sex" v-model="userInfo.sex" value="male"><input type="radio" name="sex" v-model="userInfo.sex" value="female"> <br/><br/>
            爱好:
            学习<input type="checkbox" v-model="userInfo.hobby" value="study">
            游戏<input type="checkbox" v-model="userInfo.hobby" value="game">
            吃饭<input type="checkbox" v-model="userInfo.hobby" value="eat"> <br/><br/>
            所属校区
            <select v-model="userInfo.city">
                <option value="">请选择校区</option>
                <option value="beijing">北京</option>
                <option value="shanghai">上海</option>
                <option value="shenzhen">深圳</option>
                <option value="wuhan">武汉</option>
            </select> <br/><br/>
            其他信息:
            <textarea v-model="userInfo.other"></textarea> <br/><br/>
            <input type="checkbox" v-model="userInfo.agree">阅读并接受<a href="https://www.baidu.com/">《用户协议》</a> <br/><br/>
            <button>提交</button>
        </form>
    </div>
</body>

<script type="text/javascript">
    Vue.config.productionTip = false // 阻止vue在启动时生成生产提示

    new Vue({
        el:'#root',
        data:{
            userInfo:{
                account:'',
                password:'',
                sex:'male',
                hobby:[],
                city:'beijing',
                other:'',
                agree:'',
            }
        },
        methods: {
            demo(){
                console.log(JSON,stringify(this.userInfo))
            }
        },
    })
</script>

</html>

本篇总结:

这篇笔记的主要内容是介绍Vue内,绑定样式、条件渲染、列表渲染、收集表单数据这四方面内容的概括和实践。

  • 绑定样式分为绑定class样式和绑定style样式,注意区分两者的作用
  • 条件渲染中主要掌握v-if和v-show的区别与使用方法,使用v-if时,元素可能无法获取到,而使用v-show一定可以获取到元素
  • 列表渲染中掌握v-for指令,尤其要理解key的原理,作为补充掌握列表排序和列表过滤的两种方法
  • 收集表单数据作为一个简单的小例子,在实践中理解知识

今天也是有收获的一天~