Vue系统指令(二)


v-model:双向数据绑定

双向数据绑定,只能用于表单元素,或者用于自定义组件

区别
- v-bind:只能实现数据的单向绑定,从M自动绑定到V,无法实现数据的双向绑定
- v-model:只有v-model才能实现双向数据绑定。注意,v-model后面不需要跟冒号

v-model只能运用在表单元素中,或者用于自定义组件。常见的表单元素包括:input(radio,text,address,email...)、select、checkbox、textarea


v-forkey属性

对象数组的遍历

<div v-for="(val, i) in list">索引:{
    
    {
    
    i}} --- 姓名:{
    
    {
    
    val.name}} --- 年龄:{
    
    {
    
    val.age}}</div>

对象的遍历

<div v-for="(value, key) in obj1">值:{
    
    {
    
    value}} --- 键:{
    
    {
    
    key}}</div>
<div v-for="(value, key, index) in obj1">值:{
    
    {
    
    value}} --- 键:{
    
    {
    
    key}} --- 索引:{
    
    {
    
    index}}</div>

遍历数字

<!-- 如果用 v-for 遍历数字的话,前面的myCount值从1开始算起 -->
<div v-for="myCount in 10">这是第{
    
    {
    
    myCount}}次循环</div>
<body>
    <div id="app">
        <ul>
            <!-- 数组对象的遍历 -->
            <li v-for="(val, i) in list">索引:{
   
   {i}} --- 姓名:{
   
   {val.name}} --- 年龄:{
   
   {val.age}}</li>
            <br><br><br>
            <!-- 对象的遍历 -->
            <li v-for="(value, key) in obj1">值:{
   
   {value}} --- 键:{
   
   {key}}</li>
            <li v-for="(value, key, index) in obj1">值:{
   
   {value}} --- 键:{
   
   {key}} --- 索引:{
   
   {index}}</li>
            <br><br><br>
            <!-- 遍历数字 -->
            <!-- 如果用 v-for 遍历数字的话,前面的myCount值从1开始算起 -->
            <li v-for="myCount in 10">这是第{
   
   {myCount}}次循环</li>
        </ul>
    </div>
    <script>
        var vm = new Vue({
      
      
            el: '#app',
            data: {
      
      
                list: [
                    {
      
      name: '藤原拓海', age: 18},
                    {
      
      name: '夏树', age: 17}
                ],
                obj1: {
      
      
                    name: '八戒',
                    age: '26',
                    gender: '男',
                }
            },
            methods: {
      
      }
        })
    </script>
</body>

在这里插入图片描述

v-for中key的使用注意事项

注意:在Vue2.2.0+版本中,当在组件中使用v-for时,key属性是必须要加上的。

这样做是因为:每次for循环的时候,通过指定key来标示当前循环这一项的唯一身份

当vue.js用v-for正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序没有改变,Vue将不是移动DOM元素来匹配数据项的顺序,而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。

为了给Vue一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一key属性

key的类型只能是:string/number,而且要通过v-bind来指定

写Vue/React项目时为什么要在列表写key,其作用是什么

  1. key是给每一个Vnode的唯一id,可以依靠key更准确更快的拿到oldVnode中对应的Vnode节点
    1) 更准确
    因为带key就不是就地复用了,在sameNode函数 a.key==b.key 对比中可以避免就地复用的情况,所以更准确
    2) 更快
    利用key的唯一性生成map对象来获取对应节点,比遍历方式更快

  2. 为了在diff算法执行时更快的找到对应的节点,提高diff速度
    vue与react都是采用diff算法来对比新旧虚拟节点,从而更新节点。在Vue的diff函数中,做交叉对比中,当新节点跟旧节点头尾交叉对比没有结果时,会根据新节点的key去对比旧节点的数组中的key,从而找到相应旧节点(这里对应的是一个key->index的map映射).如果没找到就认为是一个新增节点。【而如果没有key,那么就会采用遍历查找的方式去找到对应的旧节点】
    一种一个map映射,另一种是遍历查找,相比而言,map映射速度更快

//列表功能举例
<body>
    <div id="app">
        <div>
            <label>Id:
                <input type="text" v-model="id">
            </label>
            <label>Name:
                <input type="text" v-model="name">
            </label>
            <input type="button" value="添加" @click="add">
        </div>
        <!-- 注意:v-for循环的时候,key属性只能使用 number 或者 string-->
        <!-- 注意:key在使用的时候,必须使用v-bind属性绑定的形式,指定 key 的值 -->
        <!-- 在组件中,使用v-for循环的时候,或者在一些特殊情况中,如果v-for有问题,必须在使用v-for的同时,指定唯一的 字符串/数字类型 :key 值-->
        <p v-for="item in list" :key="item.id">
            <input type="checkbox">{
   
   {item.id}} === {
   
   {item.name}}
        </p>
    </div>
    <script>
        var vm = new Vue({
      
      
            el: '#app',
            data: {
      
      
                id: '',
                name: '',
                list: [
                    {
      
      id: 1, name: 'abdc'},
                    {
      
      id: 2, name: 'kkd'},
                    {
      
      id: 3, name: 'liuxing'},
                    {
      
      id: 4, name: 'xiaoxue'},
                    {
      
      id: 5, name: 'xiaoyu'},
                ]
            },
            methods: {
      
      
                add(){
      
        //添加方法
                    this.list.unshift({
      
      id: this.id, name:this.name})
                }
            }
        })
    </script>

请添加图片描述


v-if:设置元素的显示和隐藏(添加/删除DOM元素)

作用:根据表达式的值的真假条件,来决定是否渲染元素,如果为false则不渲染(达到隐藏元素的目的),如果为true则渲染

在切换时,元素和它的数据绑定会被销毁并重建

//点击按钮,切换和隐藏盒子
<body>
    <div id="app">
        <button @click="toggle">显示/隐藏</button>
        <div v-if="isShow">我是盒子</div>
    </div>
    <script>
        var vm = new Vue({
      
      
            el: '#app',
            data: {
      
      
                isShow: true,
            },
            methods: {
      
      
                toggle() {
      
      
                    this.isShow = !this.isShow
                }
            }
        })
    </script>

请添加图片描述


v-show:设置元素的显示和隐藏(在元素上添加/移除style="display:none"属性

作用:根据表达式的真假条件,来切换元素的display属性。如果为false,则元素上添加display:none属性,否则移除display:none属性

//点击按钮时,切换和隐藏盒子
直接将上一段代码中的v-if改为v-show就可以了

display: none; visibility: hidden; opacity: 0的区别

  • display: none -> 隐藏元素、不占据位置(会产生回流和重绘,不会被子元素继承)
  • visibility: hidden; opacity: 0 -> 元素隐藏不显示,但占据页面位置(只会引起重绘,会被子元素继承)

JS浏览器的回流与重绘(Reflow & Repaint)

  • 回流:元素的大小或位置发生改变(当页面布局发生改变的时候),触发了重新布局导致渲染树重新计算布局和渲染
    - 回流以视口大小来计算元素的位置与大小,即浏览器窗口尺寸变化也会引起回流
  • 重绘:只改变自身样式,不会影响到其他元素

回流一定触发重绘,而重绘不一定会回流

v-if和v-show的区别

v-ifv-show都能够实现对一个元素的隐藏和显示操作

区别:

  • v-if:每次都会重新添加/删除DOM元素
  • v-show:每次不会重新进行DOM的添加/删除操作,只是在这个元素上添加/移除display:none属性,表示节点的显示和隐藏

优缺点:

  • v-if:有较高的切换性能消耗。(每次都要进行DOM操作)
  • v-show有较高的初始渲染消耗。也就是说,即使一开始v-show="false",该节点也会被创建,只是隐藏起来了。而v-if="false"的节点,根本就不会创建

总的来说

  • 如果元素涉及到频繁的切换,推荐使用v-show
  • 如果元素可能永远也不会被显示出来被用户看到,则推荐使用v-if

おすすめ

転載: blog.csdn.net/KennGum/article/details/121136503