vue——绑定样式、条件渲染、列表渲染、key的内部原理

本文介绍了Vue.js中如何绑定CSS样式,包括字符串写法、数组写法和对象写法,并展示了动态切换样式的实现。此外,文章详细讲解了条件渲染的三种方式:v-if、v-show及其应用场景,强调了它们的区别和使用注意事项。最后,通过实例演示了列表渲染的v-for指令,展示了遍历数组、对象和字符串的方法。文章还探讨了在React和Vue中key的作用,以及如何选择合适的key以优化性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

绑定样式
<!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>绑定css样式</title>
    <script src="../js/vue.js"></script>
    <style>
        #root {
            margin: 0 auto;
        }
        
        .box {
            width: 400px;
            height: 400px;
            margin: 20px 0;
            background-color: darkcyan;
        }
        
        .bor {
            border: 1px solid darkorange;
            border-radius: 20px;
        }
        
        .font {
            line-height: 400px;
            font-size: 28px;
            color: white;
            text-align: center;
        }
        
        .back {
            background-color: darksalmon;
            border-radius: 40px;
        }
    </style>
</head>

<body>
    <div id="root">
        <!-- 绑定class样式——字符串写法,适用于:样式的类名不确定,需要动态指定 -->
        <div class="box" :class="theme">
            方式一
        </div>
        <button @click="changed">切换样式</button>
        <!-- 绑定class样式——数组写法,适用于:要绑定的样式个数不确定,名字也不确定 -->

        <div class="box" :class="arr[1]">
            方式二
        </div>
        <!-- <button @click="changedArr">切换css</button> -->
        <!-- 绑定class样式——对象写法,适用于:要绑定的样式个数确定,名字也确定,但是要动态决定用不用 -->

        <div class="box" :class="classObj">
            方式三
        </div>
        <!-- 绑定style样式——对象 -->
        <div class="box" :style="styleObj1">
            方式四
        </div>
        <!-- 绑定style样式——数组 -->
        <!-- <div class="box" :style="[styleObj1,styleObj2]">
            方式五
        </div> -->
        <div class="box" :style="styleArr">
            方式五
        </div>
    </div>
    <script>
        new Vue({
            el: "#root",
            data: {
                theme: "bor",
                arr: ["bor", "back", "font"],
                classObj: {
                    bor: false,
                    back: false,
                    font: true
                },
                styleObj1: {
                    fontSize: '40px',
                    color: 'red'
                },
                styleObj2: {
                    fontWeight: "bolder"
                },
                styleArr: [{
                    fontSize: '40px',
                    color: 'red'
                }, {
                    fontWeight: "bolder"
                }]
            },
            methods: {
                changed() {
                    const arr = ["bor", "font", "back"];
                    // Math.floor(Math.random()*3):先随机获取[0,3)的数,然后再向下取整:0,1,2
                    const num = Math.floor(Math.random() * 3)
                    this.theme = arr[num];
                }
            }
        })
    </script>
</body>

</html>

条件渲染

1.v-if

​ 写法:

​ 1.1 v-if=“表达式”

​ 1.2 v-else-if=“表达式”

​ 1.3 v-else=“表达式”

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

​ 特点:不展示DOM元素会直接被移除。

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

2.v-show

​ 写法: v-show=“表达式”

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

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

3.备注:使用v-if是,元素可能无法获取到,而使用v-show一定可以获取到

<!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>条件渲染</title>
    <script src="../js/vue.js"></script>
</head>

<body>
    <div id="root">
        <!-- 如果切换频繁的,建议使用v-show,切换次数少的用v-if -->
        <h2>当前num的值为:<span v-show="flag">{{num}}</span></h2>
        <!-- v-show通过display属性来控制dom元素节点的显示和隐藏,v-show的值为true,就显示(display:block),否则就隐藏 (display:none)-->
        <h1 v-show="num==3">
            {{name}}
        </h1>
        <!-- v-if直接控制dom元素节点的存在与不存在,若v-if的值为true,dom元素存在,否则dom元素不存在 -->
        <h3 v-if="num==5">
            {{name}}
        </h3>
        <button @click="add">num++</button>
        <button @click="sub">num--</button>
        <!-- 如果使用v-if——v-else条件渲染的,在其之间不可以断开 -->
        <div v-if="num==1">{{num}}</div>
        <div v-else-if="num==3">{{num}}</div>
        <!-- <div>v-if和v-else之间不可以断开,否则无效</div> -->
        <div v-else-if="num==5">{{num}}</div>
        <div v-else>num上天了</div>
        <!-- template不影响页面结构,不渲染成元素,template与v-if配合使用有效,v-show无效 -->
        <template v-if="num==1">
            <p>num==1时出现</p>
            <p>num==1时出现</p>
            <p>num==1时出现</p>
</template>
    </div>
    <script>
        new Vue({
            el: '#root',
            data: {
                name: "张三",
                flag: true,
                num: 1
            },
            methods: {
                add() {
                    this.num++;
                    if (this.num > 0) {
                        this.flag = true
                    }
                },
                sub() {
                    this.num--;
                    if (this.num == 0) {
                        this.num = 0
                        this.flag = false
                    }
                }
            },
        })
    </script>
</body>

</html>

列表渲染

v-for指令:

​ 1.用于展示列表数据

​ 2.语法:v-for =“item,index in(of) 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>
    <script src="../js/vue.js"></script>
</head>

<body>
    <div id="root">
        <h2>人员列表</h2>
        <ul>
            <!--inof都可以 -->
            <li v-for="person in persons" :key="person.id">{{person.name}}——{{person.age}}</li>
            <!-- <li></li>
            <li></li>
            <li></li>
            <li></li> -->
        </ul>
        <!-- 确定的遍历次数 -->
        <ul>
            <!-- v是1-5的数值,i从0开始的索引值 -->
            <li v-for="(v,i) of 5" :key="i">
                {{v}}-{{i}}
            </li>
        </ul>
        <!-- 遍历字符串 -->
        <ul>
            <li v-for="(v,i) in str" :key="i">{{v}}</li>
        </ul>
    </div>
    <script>
        new Vue({
            el: "#root",
            data: {
                str: "hello",
                persons: [{
                    id: 001,
                    name: "张三",
                    age: 24
                }, {
                    id: 002,
                    name: "李四",
                    age: 28
                }, {
                    id: 003,
                    name: "王五",
                    age: 20
                }, {
                    id: 004,
                    name: "周六",
                    age: 26
                }, {
                    id: 005,
                    name: "田七",
                    age: 22
                }, ]
            }
        })
    </script>
</body>

</html>

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

1.虚拟DOM中key的作用:

​ key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据[新数据]生成[新的虚拟DOM],随后vue进行[新虚拟DOM]与[旧虚拟DOM]的差异比较。

2.对比规则:

​ 2.1 在旧虚拟DOM中找到了与新虚拟DOM相同的key:

​ 2.1.1 若旧虚拟DOM中的内容与新虚拟DOM中的内容一致,直接使用之前的真实DOM

​ 2.1.2 若旧虚拟DOM中的内容与新虚拟DOM中的内容不一致,则生成新的真实DOM,随后替换掉页面中之前的真实DOM

​ 2.2 旧虚拟DOM中未找到与新虚拟DOM相同的key“

​ 创建新的真实DOM,随后渲染到页面

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

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

​ 3.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>
    <script src="../js/vue.js"></script>
</head>

<body>
    <div id="root">
        <h2>人员列表</h2>
        <button @click="add">添加新成员</button>
        <ul>
            <li v-for="(p,index) in persons" :key="index">
                {{p.name}}-{{p.age}}
                <input type="text">
            </li>
        </ul>
    </div>
    <script>
        new Vue({
            el: "#root",
            data: {
                persons: [{
                    id: 001,
                    name: "张三",
                    age: 24
                }, {
                    id: 002,
                    name: "李四",
                    age: 28
                }, {
                    id: 003,
                    name: "王五",
                    age: 20
                }, {
                    id: 004,
                    name: "周六",
                    age: 26
                }, {
                    id: 005,
                    name: "田七",
                    age: 22
                }, ]
            },
            methods: {
                add() {
                    const p = {
                        id: '006',
                        name: '老刘',
                        age: 40
                    }
                    this.persons.unshift(p)
                }
            },
        })
    </script>
</body>

</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值