通过Vue的指令操作可以在template中对代码进行操作


1. 插值表达式

Vue中的元素通过插值表达式{{}}将其挂载到DOM上

而写在{{}}中的Vue变量都在data中进行声明

  1. <template>
  2. {{message}}
  3. </template>
  4. <script>
  5. export default {
  6. data() {
  7. return {
  8. message: "这是一个简单的Vue变量",
  9. };
  10. },
  11. </script>

2. v-bind 指令

动态的绑定属性到标签上

<!-- 绑定 属性 -->
<img v-bind:src="imageSrc" />
<!-- 缩写 -->
<img :src="imageSrc" />

因为Vue变量不能通过普通的CSS样式进行绑定 ,需要通过v-bind先绑定属性,再通过给属性里Vue变量修改值来改变标签


3. v-on 指令

将事件绑定到标签上

<!-- 绑定一个点击事件(不带参数) -->
<button v-on:click="doThis"></button>
<!-- 绑定一个点击事件(带参数) $event 就是事件对象e -->
<button v-on:click="doThis($event,other)"></button>

<!-- 缩写 -->
<button @click="doThis"></button>
<!-- enter健触发 -->
<button @keyup.enter="doThis"></button>

其他修饰符:

  • .stop - 调用 event.stopPropagation() 阻止事件冒泡。
  • .prevent - 调用 event.preventDefault() 阻止事件默认行为。
  • .self - 只当事件是从事件绑定的元素本身触发时才触发。
  • .{keyAlias} - 仅当事件是从特定键触发时才触发回调。
  • .once - 只触发一次事件,触发完事件清除。
  • .left - 只当点击鼠标左键时触发。
  • .right - 只当点击鼠标右键时触发。
  • .middle - 只当点击鼠标中键时触发。
  • .enter - 按下回车健时触发。
  • .passive - { passive: true } 模式添加侦听器

4. v-model 指令

数据变量的双向绑定 , 通常用在表单中

vmodel.gif

<!-- 基本用法 -->
<span>用户名:</span>
<input type="text" v-model="username" />
<span>密码:</span>
<input type="password" v-model="pass" />

<!-- 下拉菜单要绑定在select上 -->
<select v-model="from">
  <option value="北京市">北京</option>
  <option value="南京市">南京</option>
  <option value="天津市">天津</option>
</select>

<!-- (重要)
  遇到复选框, v-model的变量值
  非数组 - 关联的是复选框的checked属性
  数组   - 关联的是复选框的value属性   选中后将value里的值传入这个数组
-->
      <span>爱好: </span>
      <input type="checkbox" v-model="hobby" value="抽烟">抽烟
      <input type="checkbox" v-model="hobby" value="喝酒">喝酒
      <input type="checkbox" v-model="hobby" value="写代码">写代码
    <div>
      <span>性别: </span>
      <input type="radio" value="男" name="sex" v-model="gender">男
      <input type="radio" value="女" name="sex" v-model="gender">女
    </div>
<script>
export default {
  data() {
    return {
      username: "",
      pass: "",
      from: "",
      hobby: [], 
      sex: "",
      intro: "",
    };
    // 总结:
    // 特别注意: v-model, 在input[checkbox]的多选框状态
    // 变量为非数组, 则绑定的是checked的属性(true/false) - 常用于: 单个绑定使用
    // 变量为数组, 则绑定的是他们的value属性里的值 - 常用于: 收集勾选了哪些值
  }
};
</script>

v-model 修饰符

  • .lazy - 监听 change 而不是 input 事件
  • .number - 输入字符串转为有效的数字
  • .trim - 输入首尾空格过滤

5. v-tex v-html 指令

和innerText、innerHTML的功能是一样的

<template>
  <div>
    <p v-text="str1"></p>
    <p v-html="str2"></p>
  </div>
</template>
<script>
export default {
  data() {
    return {
      str1: "<span>不解析标签</span>",
      str2: "<div>解析标签</div>",
    }
  }
}
</script>

6. v-show v-if指令

控制标签的显示和隐藏,属性值为false时隐藏标签

  • v-show:false会将标签的display属性改为的display:none
  • v-if:false会再DOM树上暂时移除该标签

一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。

v-else

和if else 用法相同 如果v-if显示则 v-else隐藏

<!-- 值为false时隐藏元素 -->
<div v-if="Math.random() > 0.5">
  Now you see me
</div>
<div v-else>
  Now you don't
</div>

v-else-if

if{}else if{} 的f用法一致 ,表示另一种条件下的v-if

<!-- 值为false时隐藏元素 -->
<div v-if="Math.random() > 0.5">
  Now you see me
</div>
<div v-else-if>
  Now you see other
</div>

7. v-for 指令

v-for用于列表渲染,通常为通过一组数组形式的Vue变量来渲染列表

<template>
  <ul>
      <!-- v-for 的局部变量只有绑定的标签及其子标签才能生效 -->
    <li v-for="(item, index) in arr" :key="index"> 
      <input type="checkbox" />{{ item.message }}
    </li>
  </ul>
</template>

<script>
export default {
  data() {
    return {
      arr: [{ message: "cat" }, { message: "bear" }, { message: "lion" }],
    };
  },
};
</script>
  • item是当前循环的数组元素
  • index是一个可选参数 ,为当前循环索引
  • 当修改数组元素时,v-for会更新当前渲染的数据,v-for根据绑定地址内的数据来实时更新,所以如果不是对原数据进行的修改v-for并不会渲染在页面上(例如filter()concat()slice()。它们不会变更原始数组,而总是返回一个新数组)

v-for 跟新数据

v-for 的跟新默认行为会先尝试原地修改数据,即就地跟新的策略,这就和虚拟DOM以及diff算法有关了 这个默认的模式是高效的,但是只适用于不依赖子组件状态或临时 DOM 状态 (例如:表单输入值) 的列表渲染输出

可以通过添加 key 来提高跟新数据的性能

  - **没有**`key`时 `v-for`为就地更新的策略
  - **有**`key`时`v-for`按照`key`来进行比较跟新
     - `key`建议为数组内部对象的`Id`如果没有也可以绑定索引(index)
<!-- 优先绑定id -->
<div v-for="item,index in arr" :key="item.id"> 
  <!-- 省略的代码 -->
</div>

<!-- 没有就绑定index -->
<div v-for="item,index in arr" :key="index">
  <!-- 省略的代码 -->
</div>

提示 不要使用对象或数组之类的非基本类型值作为 v-for 的 key。请用字符串或数值类型的值。

虚拟DOM

.vue文件中的template里写的标签, 都是模板, 都要被vue处理成虚拟DOM对象, 才会渲染显示到真实DOM页面上(虚拟DOM本质上其实就是一个JS对象)

Vue里的template里标签结构 转变为对应的虚拟DOM

<template>
    <div id="app">
        <p class="myCard">adscrsdf</p>
    </div>
</template>
const dom = {
    type: 'div',
    attributes: [{id: 'app'}],
    children: {
        type: 'p',
        attributes: [{class: 'myCard'}],
        text: 'adscrsdf'
    }
}

所以Vue跟新数据为:

  1. 生成新的虚拟DOM结构
  2. 与旧的虚拟DOM结构进行对比
  3. 利用diff算法来跟新变化的部分(重绘or回流)到页面上

这样做的优点 :

  • 提高更新DOM的性能
  • 虚拟DOM只包含必要的属性

总结: 虚拟DOM保存在内存中, 只记录dom关键信息, 配合diff算法提高DOM更新的性能