跟着尚硅谷学vue-day6

发布于:2025-07-01 ⋅ 阅读:(18) ⋅ 点赞:(0)

 要记着培养一个输出型爱好。绑定class和style样式,条件渲染和列表渲染。

绑定样式 

绑定class样式

    1.class样式

    写法:class="xxx”

    xxx可以是字符中、对象、数组

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

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

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

  绑定style样式

    2.style样式

    :style="{fontSize:xxx}"其中xxx是动态值,

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

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>绑定样式</title>
    <style>
        .basic{
            width: 300px;
            height: 100px;
            border: 2px solid blue;
        }
        .happy{
            background-color: red;
        }
        .sad{background-color: gray;}
        .normal{background-color: blue;}
        .atguigu1{background-color: green;}
        .atguigu2{text-align: center;}
        .atguigu3{border-radius: 20%;}

    </style>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <div id="root">
        <div class="basic" :class= 'mood' @click="changemode" id="childroot">我的小猫:{{name}}</div>  <br/>
        <div class="basic" :class= 'classArr' @click="changemode" >我的小猫:{{name}}</div>
        <br/>
        <div class="basic" :class= 'classObj' @click="changemode" >我的小猫:{{name}}</div>
        <br/>
        <div class="basic" :style="{fontSize:fsize+'px'}"  @click="changemode" >我的小猫:{{name}}</div><br/>
        <div class="basic" :style="styleObj"  @click="changemode" >我的小猫:{{name}}</div><br/>
        <div class="basic" :style="styleArr"  @click="changemode" >我的小猫:{{name}}</div>

    </div>
    <script type="text/javascript">
        Vue.config.productionTip = false;
        new Vue({
            el:'#root',
            data:{
                name:'douzi',
                address:'alsjjj',
                mood:'normal',
                classArr:['atguigu1','atguigu2','atguigu3'],
                classObj:{
                    atguigu1:true,
                    atguigu2:false
                },
                fsize:40,
                // 样式对象
                styleObj:{
                    fontSize:'40px'
                },
                styleArr:[
                    {fontSize:'20px'},{backgroundColor:'orange'}
                   ]

            },
            methods: {
                changemode(){
                    const arr = ['happy','sad','normal']
                    const string = arr[Math.floor(Math.random()*3)]
                    this.mood = string
                    console.log(this.mood)
                }
            },
        })
    </script>
</body>
</html>

生成的页面 


案例 

1.在初始状态下,div 元素应用基础样式和正常样式。当用户点击该元素时,样式会切换为开心样式或悲伤样式。

思路:利用:class动态绑定mood类名,使得类名可以根据 mood 变量的值动态变化。然后在Vue 实例的 data 中定义 mood 变量,之后为 div 元素绑定一个事件方法,在方法内部修改 mood 的值

实现:当用户点击该元素时,样式会切换为开心样式,悲伤样式或者正常样式。

 changemode(){
                    const arr = ['happy','sad','normal']
                    const string = arr[Math.floor(Math.random()*3)]
                    this.mood = string
             }


技巧 

技巧1:在 Vue 中,如果有大量样式需要管理,可以采用数组的形式进行存储。这种方式不仅方便初始化,还能在后续随意修改数组内容。由于数组由 Vue 进行管理,操作更加便捷和高效。

通过布尔值控制多个class样式的显示。可以修改true或者false,可以动态修改class样式。

 <div class="basic" :class= 'classObj' @click="changemode" >我的小猫:{{name}}</div>
data:{classObj:{
                    atguigu1:true,
                    atguigu2:false
         }}

技巧2:style样式的技巧

<div class="basic" :style="{fontSize:fsize+'px'}"  @click="changemode" >我的小猫:{{name}}</div><br/>

:style="{fontSize:fsize+'px'}" 其中"{fontSize:fsize+'px'}"可以替换成为相同意义的对象和数组,比如

<div class="basic" :style="styleObj"  @click="changemode" >我的小猫:{{name}}</div><br/>
<div class="basic" :style="styleArr"  @click="changemode" >我的小猫:{{name}}</div>
                styleObj:{
                    fontSize:'40px'
                },
                styleArr:[
                    {fontSize:'20px'},{backgroundColor:'orange'}
                ]

补充知识点

1.document.getElementById('childroot').className = 'basic happy' 手动修改结点,在vue中不推荐

2.在HTML和CSS中,class属性可以包含多个样式类名,这些类名之间用空格分隔。当有两个class的时候,采用第一个class。

3.const 和 var 的区别

作用域constlet 具有块级作用域,意味着它们只在声明它们的块或子块中有效。var 具有函数作用域,意味着它在整个函数内部都有效。

重复声明:var 允许在同一作用域内重复声明变量,而 constlet 不允许。

值的可变性:const 声明的变量必须立即初始化,且不能重新赋值。varlet 声明的变量可以重新赋值。

全局对象属性:在全局作用域中,var 声明的变量会成为全局对象的属性(如 window 对象),而 constlet 不会。

var j = 15;
console.log(window.j); // 15

const k = 16;
console.log(window.k); // undefined

变量提升:var 声明的变量会被提升到其作用域的顶部,即使赋值操作在声明之后。constlet 不会被提升,且在声明之前访问会导致 ReferenceError

console.log(c); // undefined
var c = 3;

console.log(d); // ReferenceError: Cannot access 'd' before initialization
const d = 4;

4. Math.random 是包含0,但是不包含1,所以乘以3就无限接近于3,然后floor,是向下取整,就可以取到0,1,2

条件渲染:v-show,v-if和v-for

v-show的底层实现就是display:none,可以见到节点

v-if看不到节点 

 
1.v-if
写法:
(1).v-if="表达式”
(2).v-else-if="表达式”
(3)v-elses"="表达式”
适用于:切换频率较低的场最
特点:不展示的DOM元素直接移出
注意:v-if可以和:v-else-if、v-else一起使用,但要求结构不被“打断”
2.v-show
写法:v-show="表达式”
适用于:切换频率较高的场景。
特点:不展示的DOM元素未被移除,仅仅是使用样式隐藏掉
3.备注:使用v-if的时,元素(结点)可能无法获取到,而使用v-show一定可以获取到。

undefined不呈现在页面上

列表渲染:

v-for指令
1.用于展示列表数据
2.语法:v-for="(item,index)in xxx" :key="yyy" 
3.可遍历:数组、对象、字符中(用的很少)、指定次数(用的很少)

列表渲染

遍历数组,:key="p.id" ,让每一个li都有标识。key不能重复

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>基本列表</title>
    <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">
                {{p.name}}-{{p.age}}
            </li>
        </ul>
    </div>

    <script type="text/javascript">
        Vue.config.productionTip = false;
        new Vue({
            el:'#root',
            data:{
                personArr:[
                    {id:'001',name:'小粉',age:20},
                    {id:'001',name:'小红',age:30},
                    {id:'001',name:'小绿',age:25}
                ]   
               
            }
        })
    </script>
</body>
</html>

可遍历:数组、对象、字符中(用的很少)、指定次数(用的很少)

        用两个参数遍历
        <ul>
            <li v-for="(p,index) in personArr" :key="index" >
                {{p.name}}-{{p.age}}--{{index}}
            </li>
        </ul>
        api of
        <ul>
            <li v-for="(p,index) of personArr" :key="index" >
                {{p.name}}-{{p.age}}--{{index}}
            </li>
        </ul>
        遍历对象
        <ul>
            <li v-for="(value,key) of carmessage" :key="key" >
               {{value}}-{{key}}
            </li>
        </ul>
        遍历字符串
        <ul>
            <li v-for="(char,index) of str" :key="index" >
               {{char}}-{{index}}
            </li>
        </ul>
        遍历指定次数
        <ul>
            <li v-for="(a,b) of 5"  >
               {{a}}-{{b}}
            </li>
        </ul>

案例:在数组第一个元素添加一个变量(unshift)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>基本列表</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>

<body>
    <div id="root">
        <h2>人员列表</h2>
        <button @click="add">添加一个用户</button>
        用两个参数遍历
        <ul>
            <li v-for="(p,index) in personArr" :key="index" >
                {{p.name}}-{{p.age}}--{{index}}
            </li>
        </ul>
        :key是被vue征用的。因为打开真实dom发现key并不在页面上。
    </div>

    <script type="text/javascript">
        Vue.config.productionTip = false;
        new Vue({
            el:'#root',
            data:{
                personArr:[
                    {id:'001',name:'小粉',age:20},
                    {id:'001',name:'小红',age:30},
                    {id:'001',name:'小绿',age:25}
                ]
            },
            methods:{
                add(){
                    const p = {id:'004',name:'小liu',age:25}
                    this.personArr.unshift(p)

                }
            }
        })
    </script>
</body>
</html>

接着,给每一个li添加一个输入框。点击添加用户,发现输入框和用户姓名发生了错乱

解决办法

用key绑定用户标识id,涉及到的就是key的基本原理和虚拟dom的对比算法。

虚拟dom更新

以下是以 index 作为 key 时,虚拟 DOM 更新过程的描述:

图中展示了在添加“老刘”这一数据项前后,旧数据和新数据生成虚拟 DOM,并将虚拟 DOM 转换为真实 DOM 的过程。

在初始状态下,旧数据会生成对应的虚拟 DOM。这些虚拟 DOM 以 key 的值(这里 keyindex)作为索引,存储在内存中(虚拟 DOM 是抽象概念,无法直接看到)。而此时生成的真实 DOM 节点本身并不携带 key 属性。

当添加“老刘”这一新数据项后,新数据同样会生成新的虚拟 DOM。接下来,React(或其他相关框架)会将这些新生成的虚拟 DOM 与旧的虚拟 DOM 进行对比,判断节点是否发生改变。如果检测到节点有变化,就会将新数据对应的虚拟 DOM 节点转换为真实 DOM 节点;如果节点未发生变化,则会复用旧数据对应的真实 DOM 节点。比如,key相等,但是老刘节点和张三节点不同,所以会生成真实dom节点。两个input节点相等,复用旧数据对应的真实dom节点。

以下是以 id 作为 key 时,虚拟 DOM 更新过程的描述:

因为id是每一组数据都有的,所以可以避免索引值的问题,提升dom的复用率。

  面试题:react、Ivue中的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是没有问题的。


网站公告

今日签到

点亮在社区的每一天
去签到