Vue相关指令

Vue相关指令

  • 具有特殊含义、拥有特殊功能的特性
  • 指令带有v-前缀,表示它们是Vue提供的特殊特性
  • 指令可以直接使用data中的数据

v-pre

  • 跳过这个元素和它的子元素的编译过程。可以用来显示原始 Mustache 标签。跳过大量没有指令的节点会加快编译。
    <!-- 不会被编译 -->
    <span v-pre>{{ msg }}</span>
    

v-cloak

  • 这个指令保持在元素上直到关联实例结束编译

  • 可以解决闪烁的问题

  • 和 CSS 规则如 [v-cloak] { display: none } 一起用时,这个指令可以隐藏未编译的 Mustache 标签直到实例准备完毕

    [v-cloak] {
      display: none;
    }
    
    <!-- {{ message }}不会显示,直到编译结束 -->
    <div v-cloak>
      {{ message }}
    </div>
    

v-once

  • 只渲染元素一次。随后的重新渲染,元素及其所有的子节点将被视为静态内容并跳过。这可以用于优化更新性能
    <!-- 单个元素 -->
    <span v-once>{{msg}}</span>
    <!-- 有子元素 -->
    <div v-once>
      <h1>comment</h1>
      <p>{{msg}}</p>
    </div>
    

v-text

  • 更新元素的 textContent
    <span v-text="msg"></span>
    <!-- 和下面的一样 -->
    <span>{{msg}}</span>
    

v-text VS Mustache

  • v-text替换元素中所有的文本,Mustache只替换自己,不清空元素内容
    <!-- 渲染为:<span>杉杉最美</span> -->
    <span v-text="msg">----</span>
    <!-- 渲染为:<span>----杉杉最美----</span> -->
    <span>----{{msg}}----</span>
    
  • v-text 优先级高于 {{ }}

textContent VS innerText

  1. 设置文本替换时,两者都会把指定节点下的所有子节点也一并替换掉。
  2. textContent 会获取所有元素的内容,包括 <script><style>元素,然而 innerText 不会。
  3. innerText 受 CSS 样式的影响,并且不会返回隐藏元素的文本,而textContent会。
  4. 由于 innerText 受 CSS 样式的影响,它会触发重排(reflow),但textContent 不会。
  5. innerText 不是标准制定出来的 api,而是IE引入的,所以对IE支持更友好。textContent虽然作为标准方法但是只支持IE8+以上的浏览器,在最新的浏览器中,两个都可以使用。
  6. 综上,Vue这里使用textContent是从性能的角度考虑的。

测试一下innerText & textContent两者性能

<ul class="list">
  <li>1</li>
  <!-- 此处省略998个 -->
  <li>1000</li>
</ul>
const oList = document.getElementById("list");

console.time("innerText");
for(let i = 0; i < oList.childElementCount; i++){
  ul.children[i].innerText="innerText";
}
console.timeEnd("innerText");

console.time("textContent");
for(let i = 0; i < oList.childElementCount; i++){
  ul.children[i].textContent="innerText";
}
console.timeEnd("textContent");

v-html

  • 更新元素的innerHTML
  • 注意:内容按普通 HTML 插入,不会作为 Vue 模板进行编译
  • 在网站上动态渲染任意 HTML 是非常危险的,因为容易导致 XSS 攻击。只在可信内容上使用 v-html,永不用在用户提交的内容上。
    <input type="text" />
    <button>点击</button>
    <div id="app">
      <div v-html="msg"></div>
    </div>
    
    const vm = new Vue({
      el: '#app',
      data: {
        msg: 'hello world'
      }
    })
    
    const oInput = document.getElementsByTagName('input')[0];
    const oButton = document.getElementsByTagName('button')[0];
    let msg = null;
    oButton.onclick = function () {
      vm.msg = oInput.value;
    }
    

条件渲染

v-if

  • 用于条件性地渲染一块内容。这块内容只会在指令的表达式返回 truthy 值的时候被渲染。

切换多个元素

  • 因为 v-if 是一个指令,所以必须将它添加到一个元素上,但是如果想切换多个元素呢?此时可以把一个 <template>元素当做不可见的包裹元素,并在上面使用 v-if。最终的渲染结果将不包含 <template>元素
    <template v-if="ok">
      <h1>Title</h1>
      <p>Paragraph 1</p>
      <p>Paragraph 2</p>
    </template>
    

v-else

  • 为 v-if 或者 v-else-if 添加“else 块”。
  • 注意:前一兄弟元素必须有 v-if 或 v-else-if
    <div v-if="Math.random() > 0.5">
    	小明
    </div>
    <div v-else>
      你看不见小明啦
    </div>
    

v-else-if

  • 表示 v-if 的 “else if 块”。可以链式调用。
  • 注意:前一兄弟元素必须有 v-if 或 v-else-if
    <div v-if="type === 'A'">
      A
    </div>
    <div v-else-if="type === 'B'">
      B
    </div>
    <div v-else-if="type === 'C'">
      C
    </div>
    <div v-else>
      Not A/B/C
    </div>
    

v-show

  • 根据表达式之真假值,切换元素的 display CSS 属性。
    <h1 v-show="ok">Hello!</h1>
    

v-if VS v-show

  1. v-if 是惰性的,如果在初始渲染时条件为假,则什么也不做,直到条件第一次变为真时,才会开始渲染条件块。v-show则不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。
  2. v-if 有更高的切换开销,v-show 有更高的初始渲染开销,如果需要非常频繁地切换,则使用 v-show 较好,如果在运行时条件很少改变,则使用 v-if 较好
  3. v-show不支持<template>元素
  4. v-show不支持v-else/v-else-if

v-bind 指令

  • 动态地绑定一个或多个特性

  • :后的为传递的参数

    <!-- 绑定一个属性 -->
    <img v-bind:src="imageSrc">
    
    <!-- 动态特性名 (2.6.0+) -->
    <button v-bind:[key]="value"></button>
    
    <!-- 缩写 -->
    <img :src="imageSrc">
    
    <!-- 动态特性名缩写 (2.6.0+) -->
    <button :[key]="value"></button>
    
    <!-- 内联字符串拼接 -->
    <img :src="'/path/to/images/' + fileName">
    
  • 没有参数时,可以绑定到一个包含键值对的对象。注意此时 class 和 style 绑定不支持数组和对象。

    <!-- 绑定一个有属性的对象 -->
    <div v-bind="{ id: someProp, 'other-attr': otherProp }"></div>
    
  • 由于字符串拼接麻烦且易错,所以在绑定 class 或 style 特性时,Vue做了增强,表达式的类型除了字符串之外,还可以是数组或对象。

    • 绑定class

      • 对象语法

        <div v-bind:class="{ red: isRed }"></div>
        

        上面的语法表示 active 这个 class 存在与否将取决于数据属性 isActive 的 真假。

      • 数组语法
        我们可以把一个数组传给 v-bind:class,以应用一个 class 列表

        <div v-bind:class="[classA, classB]"></div>
        
      • 在数组语法总可以使用三元表达式来切换class

        <div v-bind:class="[isActive ? activeClass : '', errorClass]"></div>
        
      • 在数组语法中可以使用对象语法

          <div v-bind:class="[classA, { classB: isB, classC: isC }]">
          <div v-bind:class="classA" class="red">
        
      • v-bind:class 可以与普通 class 共存

          <div v-bind:class="classA" class="red">
        
    • 绑定style

      • 使用对象语法
        看着比较像CSS,但其实是一个JavaScript对象
        CSS属性名可以用驼峰式(camelCase)或者短横线分隔(kebab-case)来命名
        但是使用短横线分隔时,要用引号括起来
        <div v-bind:style="{ fontSize: size + 'px' }"></div>
        
        data: {
          size: 30
        }
        
        也可以直接绑定一个样式对象,这样模板会更清晰:
        <div v-bind:style="styleObject"></div>
        
        data: {
          styleObject: {
            fontSize: '13px'
          }
        }
        
      • 使用数组语法
        数组语法可以将多个样式对象应用到同一个元素
        <div v-bind:style="[styleObjectA, styleObjectB]"></div>
        
      • 自动添加前缀
        绑定style时,使用需要添加浏览器引擎前缀的CSS属性时,如 transform,Vue.js会自动侦测并添加相应的前缀。
      • 多重值
        从 2.3.0 起你可以为 style 绑定中的属性提供一个包含多个值的数组,常用于提供多个带前缀的值:
        <div v-bind:style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>
        
        这样写只会渲染数组中最后一个被浏览器支持的值。在本例中,如果浏览器支持不带浏览器前缀的 flexbox,那么就只会渲染 display: flex。
  • 缩写: :

  • 修饰符:
    修饰符 (modifier) 是以英文句号 . 指明的特殊后缀,用于指出一个指令应该以特殊方式绑定。

    • .camel
      由于绑定特性时,会将大写字母转换为小写字母,如:

      <!-- 最终渲染的结果为:<svg viewbox="0 0 100 100"></svg> -->
      <svg :viewBox="viewBox"></svg>
      

      所以,Vue提供了v-bind修饰符 camel,该修饰符允许在使用 DOM 模板时将 v-bind 属性名称驼峰化,例如 SVG 的 viewBox 属性

      <svg :view-box.camel="viewBox"></svg>
      
    • .prop
      被用于绑定 DOM 属性 (property)

      <div v-bind:text-content.prop="text"></div>
      
    • .sync
      讲解组件时再说

v-on指令

  • v-on 指令可以监听 DOM 事件,并在触发时运行一些 JavaScript 代码

  • 事件类型由参数指定

    <div id="app">
      <button v-on:click="counter += 1">点击加 1</button>
      <p>按钮被点击了 {{ counter }} 次</p>
    </div>
    
    const vm = new Vue({
      el: 'app',
      data: {
        counter: 0
      }
    })
    
  • 但是很多事件处理逻辑是非常复杂的,所以直接把 JavaScript 代码写在 v-on 指令中是不可行的。所以 v-on 还可以接收一个需要调用的方法名称。

    <div id="app">
      <!-- `addCounter` 是在下面定义的方法名 -->
      <button v-on:click="addCounter">点击加 1</button>
      <p>按钮被点击了 {{ counter }} 次</p>
    </div>
    
    const vm = new Vue({
      el: '#app',
      data: {
        counter: 0
      },
      // 在 methods 对象中定义方法
      methods: {
        addCounter: function (e) {
          // this 在方法里指向当前 Vue 实例
          this.counter += 1// e 是原生 DOM 事件
          cosnole.log(e.target)}
      }
    })
    
  • methods中的函数,也会直接代理给Vue实例对象,所以可以直接运行:

      vm.addCounter();
    
  • 除了直接绑定到一个方法,也可以在内联JavaScript 语句中调用方法:

    <div id="app">
      <button v-on:click="addCounter(5)">点击加 5</button>
      <p>按钮被点击了 {{ counter }} 次</p>
    </div>
    
    new Vue({
      el: '#app',
      data: {
        counter: 0
      },
      methods: {
        addCounter: function (num) {
          this.counter += 5;
        }
      }
    })
    
  • 在内联语句中使用事件对象时,可以利用特殊变量 $event:

    <div id="app">
     <button v-on:click="addCounter(5, $event)">点击加 5</button>
     <p>按钮被点击了 {{ counter }} 次</p>
    </div>
    
    new Vue({
      el: '#app',
      methods: {
        addCounter: function (num, e) {
          this.counter += 5;
          cosnole.log(e.target)}
      }
    })
    
  • 可以绑定动态事件,Vue版本需要2.6.0+

    <div v-on:[event]="handleClick">点击,弹出1</div>  
    
    const vm = new Vue({
      el: '#app',
      data: {
        event: 'click'
      },
      methods: {
        handleClick () {
          alert(1);
        }
      }
    })
    
  • 可以不带参数绑定一个对象,Vue版本需要2.4.0+。

    • { 事件名:事件执行函数 }
    • 使用此种方法不支持函数传参&修饰符
    <div v-on="{ mousedown: doThis, mouseup: doThat }"></div>
    
  • v-on指令简写:@

为什么在 HTML 中监听事件?

  1. 扫一眼 HTML 模板便能轻松定位在 JavaScript 代码里对应的方法。
  2. 因为你无须在 JavaScript 里手动绑定事件,你的 ViewModel 代码可以是非常纯粹的逻辑,和 DOM 完全解耦,更易于测试
  3. 当一个 ViewModel 被销毁时,所有的事件处理器都会自动被删除。你无须担心如何清理它们

v-on指令的修饰符

事件修饰符

.stop

  • 调用 event.stop,阻止事件冒泡
    <!-- 此时只弹出button -->
    <div id="app">
      <div @click="alert('div')">
        <button @click.stop="alert('button')">点击</button>
      </div>
    </div>
    
    const vm = new Vue({
      el: '#app',
      methods: {
        alert(str) { alert(str); }
      }
    })
    

.prevent

  • 调用 event.preventDefault(),阻止默认事件
    <!-- 点击提交按钮后,页面不会重载 -->
    <div id="app">
      <form v-on:submit.prevent="onSubmit">
        <input type="submit">
      </form>
      <!-- 也可以只有修饰符 -->
      <form v-on:submit.prevent>
        <input type="submit">
      </form>
    </div>
    
    const vm = new Vue({
      el: '#app',
      methods: {
        onSubmit() { console.log('submit'); }
      }
    })
    

.capture

  • 事件捕获模式
    <!-- 此时先弹出div再弹出button -->
    <div id="app">
      <div @click.capture="alert('div')">
        <button @click="alert('button')">点击</button>
      </div>
    </div>
    
    const vm = new Vue({
      el: '#app',
      methods: {
        alert(str) { alert(str) }
      }
    })  
    

.self

  • 只当事件是从侦听器绑定的元素本身触发时才触发回调

    <!-- 点击button时,只弹出 button -->
    <div id="app">
      <div id="app">
        <div :style="{ backgroundColor: 'red' }" 
        @click.self="alert('div')">
          <button @click="alert('button')">点击</button>
        </div>
      </div>
    </div>
    
    const vm = new Vue({
      el: '#app',
      methods: {
        alert(str) { alert(str) }
      }
    })
    

.once

  • 只触发一次回调

  • 2.1.4新增

    点击两次button按钮,只弹出一次button
    <div id="app">
      <button @click.once="alert('button')">点击</button>
    </div>
    
    const vm = new Vue({
      el: '#app',
      methods: {
        alert(str) { alert(str) }
      }
    })
    

.passive

  • 设置 addEventListener 中的 passive 选项
  • 能够提升移动端的性能
  • 2.3.0新增

why passive?

  • 即使在触发触摸事件时,执行了一个空的函数,也会让页面卡顿。因为浏览器不知道监听器到底会不会阻止默认事件,所以浏览器要等到执行完整个函数后,才能决定是否要滚动页面。passive事件监听器,允许开发者告诉浏览器,监听器不会阻止默认行为,从而浏览器可以放心大胆的滚动页面,这样可以大幅度提升移动端页面的性能,因为据统计只有20%的触摸事件会阻止默认事件。
  • .passive 会告诉浏览器你不想阻止事件的默认行为

注意

  1. 使用修饰符时,顺序很重要。相应的代码会以同样的顺序产生。因此,
    v-on:click.prevent.self 会阻止所有的点击的默认事件
    v-on:click.self.prevent 只会阻止对元素自身点击的默认事件
  2. 不要把 .passive 和 .prevent 一起使用,因为 .prevent 将会被忽略,同时浏览器可能会向你展示一个警告。

按键修饰符

在监听键盘事件时,我们经常需要检查详细的按键。Vue 允许为 v-on 在监听键盘事件时添加按键修饰符

<!-- 只有在 `key` 是 `Enter` 时调用 `vm.submit()` -->
<input v-on:keyup.enter="submit">

你可以直接将 KeyboardEvent.key 暴露的任意有效按键名转换为 kebab-case 来作为修饰符。

<input v-on:keyup.page-down="onPageDown">

在上述示例中,处理函数只会在 $event.key 等于 PageDown 时被调用。

按键码

使用 keyCode 特性也是允许的:

<!-- 按回车键会触发执行submit函数 -->
<input v-on:keyup.13="submit">

注意:keyCode 的事件用法已经被废弃了,并可能不会被最新的浏览器支持。

为了在必要的情况下支持旧浏览器,Vue 提供了绝大多数常用的按键码的别名:

  • .enter(回车键)
  • .tab
  • .delete (捕获“删除”和“退格”键)
  • .esc
  • .space (空格键)
  • .up (箭头上键)
  • .down (箭头下键)
  • .left(箭头左键)
  • .right(箭头右键)

除了使用Vue提供的按键别名之外,还可以自定义按键别名:

// 全局配置
// 可以使用 `v-on:keyup.f1`
Vue.config.keyCodes.f1 = 112
Vue.config.keyCodes = {
  v: 86,
  f1: 112,
  // 小驼峰 不可用
  mediaPlayPause: 179,
  // 取而代之的是 短横线分隔 且用双引号括起来
  "media-play-pause": 179,
  up: [38, 87]
}
<input type="text" @keyup.media-play-pause="method">

系统修饰键

可以用如下修饰符来实现仅在按下相应按键时才触发鼠标或键盘事件的监听器。
修饰键与常规按键不同,在和 keyup 事件一起用时,事件触发时修饰键必须处于按下状态,换句话说,只有在按住 ctrl 的情况下释放其它按键,才能触发 keyup.ctrl。而单单释放 ctrl 也不会触发事件。如果你想要这样的行为,请为 ctrl 换用 keyCode:keyup.17。

  • .ctrl
  • .alt
  • .shift
  • .meta
    在 Mac 系统键盘上,meta 对应 command 键 (⌘)。
    在 Windows 系统键盘 meta 对应 Windows 徽标键 (⊞)。
    在 Sun 操作系统键盘上,meta 对应实心宝石键 (◆)。
    在其他特定键盘上,尤其在 MIT 和 Lisp 机器的键盘、以及其后继产品,比如 Knight 键盘、space-cadet 键盘,meta 被标记为“META”。
    在 Symbolics 键盘上,meta 被标记为“META”或者“Meta”
<!-- Alt + C -->
<input @keyup.alt.67="clear">

<!-- Ctrl + Click -->
<div @click.ctrl="doSomething">Do something</div>

exact 修饰符

  • 允许你控制由精确的系统修饰符组合触发的事件。
  • 2.5.0 +
<!-- 即使 Alt 或 Shift 被一同按下时也会触发 -->
<button @click.ctrl="onClick">A</button>

<!-- 有且只有 Ctrl 被按下的时候才触发 -->
<button @click.ctrl.exact="onCtrlClick">A</button>

<!-- 没有任何系统修饰符被按下的时候才触发 -->
<button @click.exact="onClick">A</button>

鼠标按钮修饰符

  • 仅当点击特定的鼠标按钮时会处理执行函数
  • 2.2.0 +
  • .left
  • .right
  • .middle

列表渲染

利用v-for指令,基于数据多次渲染元素。

在v-for中使用数组

用法:(item, index) in items
参数:items: 源数据数组
           item:数组元素别名
           index:可选,索引
可以访问所有父作用域的属性

<ul id="app">
  <li v-for="(person, index) in persons">
    {{ index }}---{{ person.name }}---{{ person.age }}
  </li>
</ul>
const vm = new Vue({
  el: '#app',
  data: {
    persons: [
      { name: '小明', age: 18 },
      { name: '小宝', age: 20 },
      { name: '小刘', age: 22 },
      { name: '小张', age: 88 },
    ]
  }
})

可以利用of替代in作为分隔符,因为它更接近迭代器的语法:

<div v-for="item of items"></div>

在v-for中使用对象

用法:(value, key, index) in Object
参数:value: 对象值
           key:可选,键名
           index:可选,索引

<ul id="app">
  <li v-for="(value, key, index) in shan">
    {{ value }}
  </li>
</ul>
const vm = new Vue({
  el: '#app',
  data: {
    shan: {
      name: '杉',
      age: 18,
      height: '163cm'
    }
  }
})

在v-for中使用数字

用法:n in num
参数:n: 数字,从1开始

<div>
  <span v-for="n in num">{{ n }} </span>
</div>
const vm = new Vue({
  el: '#app',
  data: {
    num: 10
  }
})

在v-for中使用字符串

用法:str in string
参数:str: 字符串,源数据字符串中的每一个

<div>
  <span v-for="str in string">{{ str }} </span>
</div>
const vm = new Vue({
  el: '#app',
  data: {
    string: 'shanshan'
  }
})

循环一段包含多个元素的内容

可以利用template元素循环渲染一段包含多个元素的内容

<ul id="app">
  <template v-for="person in persons">
    <li>{{ item.msg }}</li>
    <li>哈哈</li>
  </template>
</ul>
const vm = new Vue({
  el: '#app',
  data: {
    persons: ['shan', 'jc', 'cst', 'deng']
  }
})

关于key

Vue更新使用v-for渲染的元素列表时,它默认使用“就地更新”的策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序,而是简单复用此处每个元素:

<ul id="app">
  <li v-for="(person, index) in persons">
    {{ person }}
    <input type="text" />
    <button @click="handleClick(index)">下移</button>
  </li>
</ul>
const vm = new Vue({
  el: '#app',
  data: {
    persons: ['shan', 'jc', 'cst', 'deng']
  },
  methods: {
    handleClick (index) {
      const deleteItem = this.persons.splice(index, 1);
      this.persons.splice(index + 1, 0, ...deleteItem);
    }
  }
})

在"就地复用"策略中,点击按钮,输入框不随文本一起下移,是因为输入框没有与数据绑定,所以vuejs默认使用已经渲染的dom,然而文本是与数据绑定的,所以文本被重新渲染。这种处理方式在vue中是默认的列表渲染策略,因为高效。

这个默认的模式是高效的,但是在更多的时候,我们并不需要这样去处理,所以,为了给Vue一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,我们需要为每项提供一个唯一key特性,Vue会基于 key 的变化重新排列元素顺序,并且会移除 key 不存在的元素。

key的使用方法

预期值:number | string
有相同父元素的子元素必须有独特的 key,重复的 key 会造成渲染错误,key应唯一。

<ul id="app">
  <li v-for="(person, index) in persons" :key="person">
    {{ person }}
  </li>
</ul>
const vm = new Vue({
  el: '#app',
  data: {
    persons: ['小明', '小宝', '小张', '小刘']
  }
}) 

不建议将数组的索引作为key值,如:

<li v-for="(person, index) in persons" :key="index">
  {{ person }}
</li>

当改变数组时,页面会重新渲染,Vue会根据key值来判断要不要移动元素。例如当页面重新渲染时,key值为"杉杉"的元素为<li>小明</li>,页面重新渲染前,key值为"杉杉"的元素也为<li>小明</li>,那么Vue就会移动这个li元素,而不是重新生成一个元素。
当使用数组的索引作为key值时,页面重新渲染后,元素的key值会重新被赋值,例如我们将数组进行反转,
反转前:

元素key值
<li>小明</li>0
<li>小宝</li>1
<li>小张</li>2
<li>小刘</li>3

反转后:

元素key值
<li>小刘</li>0
<li>小张</li>1
<li>小宝</li>2
<li>小明</li>3

Vue会比对渲染前后拥有同样key的元素,发现有变动,就会再生成一个元素,如果用索引作key值得话,那么此时,所有的元素都会被重新生成。

那么key如何唯一的?

跟后台协作时,传回来的每一条数据都有一个id值,这个id就是唯一的,用id做key即可。

key不仅为v-for所有,它可以强制替换元素,而不是重复使用它:

<ul id="app">
  <button @click="show = !show">{{ show ? '显示' : '隐藏'}}</button>
  <input type="text" v-if="show" key="a" />
  <input type="text" v-else key="b" />
</ul>
const vm = new Vue({
  el: '#app',
  data: {
    show: true
  }
}) 

v-for 和 v-if 一同使用

永远不要把 v-if 和 v-for 同时用在同一个元素上。
当 Vue 处理指令时,v-for 比 v-if 具有更高的优先级,所以这个模板:

<ul>
  <li
    v-for="user in users"
    v-if="user.isActive"
    :key="user.id"
  >
    {{ user.name }}
  </li>
</ul>

将会经过如下运算:

this.users.map(function (user) {
  if (user.isActive) {
    return user.name
  }
})

因此哪怕我们只渲染出一小部分用户的元素,也得在每次重新渲染的时候遍历整个列表,不论活跃用户是否发生了变化。
所以以下两种场景,我们可以做出如下处理:

  1. 为了过滤一个列表中的项目。
<ul id="app">
  <li
    v-for="user in users"
    v-if="user.isActive"
    :key="user.id"
  >
    {{ user.name }}
  </li>
</ul>
const vm = new Vue({
  el: '#app',
  data: {
    users: [
      { name: 'shan', isActive: true, id: 1},
      { name: 'jc', isActive: false, id: 2},
      { name: 'cst', isActive: false, id: 3},
      { name: 'deng', isActive: true, id: 4},
    ]
  }
})

可以把上面的代码更新为:

<!-- 通过原来的数组,得到一个新数组,渲染这个新的数组 -->
<ul>
  <li
    v-for="user in activeUsers"
    :key="user.id"
  >
    {{ user.name }}
  </li>
</ul>
const vm = new Vue({
  el: '#app',
  data: {
    users: [
      { name: 'shan', isActive: true, id: 1},
      { name: 'jc', isActive: false, id: 2},
      { name: 'cst', isActive: false, id: 3},
      { name: 'deng', isActive: true, id: 4},
    ],
    activeUsers: []
  }
})
vm.activeUsers = vm.users.filter(user => user.isActive);

这种方式仅为演示,在日后学习完计算属性后,要利用计算属性来做。

  1. 为了避免渲染本应该被隐藏的列表
<ul>
  <li
    v-for="user in users"
    v-if="shouldShowUsers"
    :key="user.id"
  >
    {{ user.name }}
  </li>
</ul>
const vm = new Vue({
  el: '#app',
  data: {
    users: [
      { name: 'shan', isActive: true, id: 1},
      { name: 'jc', isActive: false, id: 2},
      { name: 'cst', isActive: false, id: 3},
      { name: 'deng', isActive: true, id: 4},
    ],
    shouldShowUsers: false
  }
})

html部分可替换成为:

<ul v-if="shouldShowUsers">
  <li
    v-for="user in users"
    :key="user.id"
  >
    {{ user.name }}
  </li>
</ul>

将 v-if 置于外层元素上,我们不会再对列表中的每个用户检查 shouldShowUsers。取而代之的是,我们只检查它一次,且不会在 shouldShowUsers 为否的时候运算 v-for。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力爬坑的小崔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值