Vue基础(二)

样式属性绑定

在应用界面中, 某个(些)元素的样式是变化的,class/style 绑定就是专门用来实现动态样式效果的技术

class 绑定

使用v-bind绑定class

  • 模板 :class=“变量”
  • 变量在data中声明 变量中写入style中定义好的样式
  • 如 :class=“a” data中 a:“aclass” style中 .aclass{fontSize:20px}
  • 可通过:class={样式名:变量名,样式名:变量名}的形式绑定多样式
  • 变量通过boolean值决定是否使用样式 函数中可实现动态改变样式
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        div{
            width:200px;height:30px;margin: 100px;
        }

        .active1{
            padding: 10px;
            background: #aff;
            color: #faa;
        }

        .active2{
            border: 2px solid #faf;
        }

        .computedStyle{ color: #f00; }
    </style>
</head>
<body>

<div id="v1" class="normal" :class="{ 'active1':style1 }">//判断style1的boolen值
    对象绑定style1
</div>

<script src="vue.min.js"></script>

<script>
    var v1=new Vue({
        el:"#v1",
        data:{
            style1:true,
            style2:true
        }
    });
</script>

</body>
</html>

style 绑定

:style="{ color: activeColor, fontSize: fontSize + 'px' }"

其中 activeColor/fontSize 是 data 属性

:style="{fontSize: xxx}"其中xxx是变量(动态值),fontSize是样式名。
:style="[a,b]"其中a、b是样式对象。

列表渲染v-for | key的原理

列表显示

v-for 指令

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

key的原理

  1. 虚拟DOM中key的作用:

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

对比规则:

  1. 旧虚拟DOM中找到了与新虚拟DOM相同的key
    • 若虚拟DOM中内容没变, 直接使用之前的真实DOM
    • 若虚拟DOM中内容变了, 则生成新的真实DOM,随后替换掉页面中之前的真实DOM
  2. 旧虚拟DOM中未找到与新虚拟DOM相同的key创建新的真实DOM,随后渲染到到页面。
  3. index作为key可能会引发的问题:
  1. 会产生没有必要的真实DOM更新 ==> 界面效果没问题, 但效率低
  2. 如果结构中还包含输入类的DOM: 会产生错误DOM更新 ==> 界面有问题

详情在以下链接

为什么使用v-for时必须添加唯一的key?

Vue监视数据的原理

  • vue会监视data中所有层次的数据。
  • 如何监测对象中的数据?

通过setter实现监视,且要在new Vue时就传入要监测的数据。

① 对象中后追加的属性,Vue默认不做响应式处理

② 如需给后添加的属性做响应式,请使用如下API:

Vue.set(target,propertyName/index,value) 或 vm.$set(target,propertyName/index,value)

  • 如何监测数组中的数据?
    • 当在项目中直接设置数组的某一项的值,或者直接设置对象的某个属性值,这个时候,你会发现页面并没有更新。
  • 通过包裹数组更新元素的方法实现,本质就是做了两件事:
  1. 调用原生对应的方法对数组进行更新。
  2. 重新解析模板,进而更新页面。
  • 在Vue修改数组中的某个元素一定要用如下方法:
  1. 使用这些API: push()pop()shift()unshift()splice()sort()reverse()
  2. Vue.set() 或 vm.$set()

注意:Vue.set() 和 vm.$set() 不能给 vm 或 vm 的根数据对象 添加属性!

this.persons[index] = newP;
//并没有改变persons本身,数组内部发生了变化,但是没有调用变异方法,vue不会更新界面

也可以替换item

相比之下,也有非变更方法,例如 filter()、concat() 和 splice()。它们不会变更原始数组,而总是返回一个新数组。当使用非变更方法时,可以用新数组替换旧数组。

updateP(index, newP) { // this.persons[index] = newP; //数据(数组内部)变了,界面没有变化(没有数据绑定) //并没有改变persons本身,数组内部发生了变化,但是没有调用变异方法,vue不会更新界面 // this.persons = [] //界面有变化,改变了persons this.persons.splice(index, 1, newP); }
<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8" />
  <title>总结数据监视</title>
  <style>
    button {
      margin-top: 10px;
    }
  </style>
  <!-- 引入Vue -->
  <script type="text/javascript" src="../js/vue.js"></script>
</head>

<body>
  <!--

    -->
  <!-- 准备好一个容器-->
  <div id="root">
    <h1>学生信息</h1>
    <button @click="student.age++">年龄+1岁</button> <br />
    <button @click="addSex">添加性别属性,默认值:男</button> <br />
    <button @click="student.sex = '未知' ">修改性别</button> <br />
    <button @click="addFriend">在列表首位添加一个朋友</button> <br />
    <button @click="updateFirstFriendName">修改第一个朋友的名字为:张三</button> <br />
    <button @click="addHobby">添加一个爱好</button> <br />
    <button @click="updateHobby">修改第一个爱好为:开车</button> <br />
    <button @click="removeSmoke">过滤掉爱好中的抽烟</button> <br />
    <h3>姓名:{{student.name}}</h3>
    <h3>年龄:{{student.age}}</h3>
    <h3 v-if="student.sex">性别:{{student.sex}}</h3>
    <h3>爱好:</h3>
    <ul>
      <li v-for="(h,index) in student.hobby" :key="index">
        {{h}}
      </li>
    </ul>
    <h3>朋友们:</h3>
    <ul>
      <li v-for="(f,index) in student.friends" :key="index">
        {{f.name}}--{{f.age}}
      </li>
    </ul>
  </div>
</body>

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

  const vm = new Vue({
    el: '#root',
    data: {
      student: {
        name: 'tom',
        age: 18,
        hobby: ['抽烟', '喝酒', '烫头'],
        friends: [{
            name: 'jerry',
            age: 35
          },
          {
            name: 'tony',
            age: 36
          }
        ]
      }
    },
    methods: {
      addSex() {
        // Vue.set(this.student,'sex','男')
        this.$set(this.student, 'sex', '男')
      },
      addFriend() {
        this.student.friends.unshift({
          name: 'jack',
          age: 70
        })
      },
      updateFirstFriendName() {
        this.student.friends[0].name = '张三'
      },
      addHobby() {
        this.student.hobby.push('学习')
      },
      updateHobby() {
        // this.student.hobby.splice(0,1,'开车')
        // Vue.set(this.student.hobby,0,'开车')
        this.$set(this.student.hobby, 0, '开车')
      },
      removeSmoke() {
        this.student.hobby = this.student.hobby.filter((h) => {
          return h !== '抽烟'
        })
      }
    }
  })
</script>

</html>
阅读剩余
THE END