事件处理和事件修饰符

使用方法

  • 事件绑定指令:v-on:方法名,方法定义在vue的methods对象中
  • 事件传参:@click="aaa('')"

注意点:

  • methods中配置的函数不可使用箭头函数
  • event.target.innerText能拿到标签的值,但是调用不加(),或者使用($event)

常用修饰符

阻止默认事件
// js中的阻止默认事件
e.preventDefault()

// vue
@click.prevent="showMessge"
阻止事件冒泡
// js中的阻止事件冒泡
e.stopPropagation()

// vue
@click.stop="showMessge"

// 阻止冒泡、默认事件连用
@click.stop.prevent="showMessge"
只触发一次事件

事件在当前页面只触发一次,之后便被移除,不再触发

@click.once="showMessge"

键盘事件

使用@keyup监听按键抬起事件,如果只使用@keyup表示监听所有按键抬起事件,而使用@keyup.xxx表示xxx键抬起时才触发对应的方法

<input @keyup="keyCheck" type="text" placeholder="实时更新">
<input @keyup.enter="keyCheck" type="text" placeholder="回车更新">

计算属性

定义

在Vue.js中,计算属性(computed properties)是基于它们的依赖进行缓存的响应式属性。计算属性主要用于当一个属性依赖于其他属性值,并且需要进行一些运算时。使用计算属性可以避免在模板中放入过多的逻辑,使得模板更加简洁和易于维护。

写法

计算属性的定义通常在Vue实例的computed选项中进行,如下所示:

new Vue({
    el: '#app',
    data: {
        firstName: 'Foo',
        lastName: 'Bar'
    },
    computed: {
        fullName: {
            get: function (){
                return this.firstName + ' ' + this.lastName
            },
            set: function (newValue){
                var names = newValue.split(' ');
                this.firstName = names[0];
                this.lastName = names[names.length - 1];
            }
        }
    }
})
;

在这个例子中,fullName是一个计算属性,它依赖于data中的firstNamelastName。当firstNamelastName发生变化时,fullName会自动更新。在模板中,你可以像访问数据属性一样访问计算属性:

<div id="app">
  <p>Full name: {{ fullName }}</p>
</div>

如果fullName中的值有修改,那么set方法会将fullName重新进行拆分,并赋值给data中相应的对象。

如果对于计算属性只有读的需求,那么可以将以上代码改写为:

new Vue({
  el: '#app',
  data: {
    firstName: 'Foo',
    lastName: 'Bar'
  },
  computed: {
    fullName: function() {
      return this.firstName + ' ' + this.lastName;
    }
  }
});

计算属性的特性包括:

  1. 缓存:计算属性是基于它们的响应式依赖进行缓存的。只有当它的依赖项发生改变时,计算属性才会重新计算。这意味着,只要依赖项没有发生变化,多次访问计算属性将立即返回之前的计算结果,而不需要再次执行函数。
  2. 响应式:计算属性内部跟踪了哪些数据被访问,从而知道何时需要重新计算。如果计算属性依赖的数据发生变化,它将重新计算并触发相应的DOM更新。
  3. Getter 和 Setter:计算属性默认只有getter函数,但是你也可以提供一个setter函数,当你尝试对计算属性赋值时,setter函数将被调用。

原理

Vue.js 的计算属性实现原理涉及到几个核心概念:响应式系统、依赖追踪、以及惰性求值。下面是计算属性背后的实现细节:

  1. 响应式系统
    Vue.js 使用 Object.defineProperty(在 Vue 2.x 中)或 Proxy(在 Vue 3.x 中)来使对象成为响应式。这意味着当你访问或修改一个对象的属性时,Vue.js 能够检测到这个变化。
  2. 依赖追踪
    当计算属性的 getter 函数被执行时,Vue 会记录所有被访问的响应式属性作为这个计算属性的依赖。这是通过一个全局的依赖目标(通常是一个 watcher 实例)来实现的,它在计算属性的函数执行过程中收集依赖。
  3. 惰性求值
    计算属性的值会被缓存,Vue.js 会为每个计算属性创建一个 watcher 实例。只有在依赖项发生变化时,这个缓存值才会失效。在下一次访问计算属性时,如果依赖项没有发生变化,Vue.js 会返回缓存的值而不是重新计算。
  4. 依赖变更通知
    当计算属性的依赖项发生变化时,依赖项的 setter 会通知其相关的 watcher。如果这个 watcher 对应的是一个计算属性,它会标记为脏(dirty),表示其缓存的值已经失效。
  5. 重新计算
    当你下一次访问这个计算属性时,如果它被标记为脏,Vue.js 将重新运行它的 getter 函数来计算新的值,并更新缓存。
  6. Getter 和 Setter
    Vue.js 允许你为计算属性指定 getter 和 setter 函数。getter 负责计算和返回值,而 setter 在你尝试设置计算属性的值时被调用,允许你自定义如何响应这个变化。

在 Vue 3.x 中,响应式系统从 Object.defineProperty 升级到了使用 Proxy,这提供了更好的性能和更多的语言特性支持,但基本原理保持不变。

这个系统的设计使得 Vue.js 的计算属性非常高效。只有在必要时才重新计算值,并且确保了数据的一致性和组件的性能。

监视属性

定义和用法

在Vue.js中,监视属性(watchers)是一种特别的功能,允许你监听组件状态中的数据变化。当你需要在数据变化时执行异步操作或昂贵的操作时,监视属性非常有用。你可以使用watch选项在Vue组件中定义监视属性。

下面是一个基本的例子来说明如何在Vue组件中使用监视属性:

<template>
  <div>
    <p>输入你的名字:</p>
    <input v-model="name" placeholder="输入名字">
  </div>
</template>

<script>
export default {
  data() {
    return {
      name: ''
    };
  },
  watch: {
    // 当name变化时,这个函数就会被调用
    name(newValue, oldValue) {
      console.log(`名字从 ${oldValue} 改变成了 ${newValue}`);
    }
  }
};
</script>

在这个例子中,我们有一个名为name的数据属性,它通过v-model指令与输入框绑定。我们还定义了一个监视属性,它会在name的值发生变化时被触发。在监视属性的函数内部,你可以访问新值(newValue)和旧值(oldValue),并执行任何你需要的逻辑。

监视属性也可以监视嵌套的对象属性或数组,使用字符串形式表示路径,例如:

watch: {
  'someObject.someProperty'(newValue, oldValue) {
    // ...
  }
}

深度监视

Vue还提供了一种更先进的监视属性使用方式,你可以提供一个对象而不是一个函数,来包含更多的选项,如下:

watch: {
  name: {
    handler(newValue, oldValue) {
      // 处理name变化的逻辑
    },
    immediate: true, // 立即以当前的值触发回调
    deep: true // 深度观察对象内部的变化
  }
}

在这个高级用法中,handler是实际执行监视逻辑的函数,immediate选项指定是否在监视开始时立即执行一次(使用当前值),而deep选项允许你深度观察一个嵌套对象内部的变化。

监视属性和计算属性的异同

特性计算属性 (Computed Properties)监视属性 (Watchers)
定义基于它们的依赖进行缓存的响应式属性。观察和响应Vue实例上的数据变动的函数。
缓存有缓存,只有当依赖发生变化时才会重新计算。无缓存,每次触发数据变更时都会执行。
写法computed选项中定义为函数,返回计算结果。watch选项中定义,键是要观察的表达式,值是回调函数。
用途对数据进行转换或组合,方便在模板中直接使用。执行异步操作、复杂逻辑或在数据变化时执行副作用(例如日志记录)。
性能由于有缓存,性能较高,适用于重复计算和大量数据处理。由于无缓存,可能在性能上不如计算属性,但适用于响应数据变化进行操作。
双向绑定默认只有getter,可以添加setter来实现。不适用于双向绑定,只用于监听数据变化。
灵活性主要用于同步操作,计算值通常直接用于模板渲染。更灵活,可以监听任何响应式数据,包括props、计算属性等,并执行任何代码。
访问旧值和新值不适用,只关心当前计算值。可以访问变化前后的值,便于比较和执行基于变化的操作。
应用场景当需要根据某些数据自动计算新的数据时使用。当需要在数据变化时执行一些额外的操作,如调用API或执行异步任务时使用。

通常情况下,如果你需要根据某些数据自动计算出新的数据,并且这些新数据不需要进行复杂的操作或异步处理,那么使用计算属性会更加合适。如果你需要在数据变化时执行更复杂的逻辑,或者需要进行异步操作,那么使用监视属性会更加适合。

动态绑定

class样式的动态绑定

在Vue中,可以使用v-bind:class(或简写为:class)指令来动态绑定class样式。这允许你根据数据的变化来切换元素的class。以下是几种常见的动态绑定class的方式:

  1. 对象语法
    可以将一个对象传给:class,对象的键是class的名字,值是一个布尔值,用来决定是否应用该class。

    <template>
      <div :class="{ active: isActive, 'text-danger': hasError }"></div>
    </template>
    
    <script>
    export default {
      data() {
        return {
          isActive: true,
          hasError: false
        };
      }
    };
    </script>

    如果isActivetrueactive类会被添加到元素上;如果hasErrortruetext-danger类会被添加。

  2. 数组语法
    可以传递一个数组给:class,以应用一个class列表。

    <template>
      <div :class="[activeClass, errorClass]"></div>
    </template>
    
    <script>
    export default {
      data() {
        return {
          activeClass: 'active',
          errorClass: 'text-danger'
        };
      }
    };
    </script>

    这将根据activeClasserrorClass的值动态添加activetext-danger类。

  3. 与普通class属性混用
    可以将:class与普通的class属性一起使用。Vue会智能地合并它们。

    <template>
      <div class="static" :class="{ active: isActive, 'text-danger': hasError }"></div>
    </template>
    
    <script>
    export default {
      data() {
        return {
          isActive: true,
          hasError: true
        };
      }
    };
    </script>

    这里的div将同时拥有staticactivetext-danger类(如果isActivehasError都为true)。

  4. 在组件上使用
    当使用自定义组件时,你也可以绑定class。

    <template>
      <MyComponent :class="{ 'custom-class': isCustom }"></MyComponent>
    </template>
    
    <script>
    export default {
      data() {
        return {
          isCustom: true
        };
      }
    };
    </script>

    如果isCustomtruecustom-class将被添加到MyComponent的根元素上。

这些是Vue中动态绑定class样式的基本方法。它们可以根据实际情况和需求灵活使用,从而使得应用的样式更加动态和响应式。

style样式的动态绑定

在Vue中,可以使用v-bind:style(或简写为:style)指令来动态绑定内联样式。这允许你根据组件的状态来改变元素的样式属性。以下是几种常见的动态绑定style的方式:

  1. 对象语法
    可以将一个对象传给:style,对象的键是CSS属性名,值是对应的样式值。

    <template>
      <div :style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
    </template>
    
    <script>
    export default {
      data() {
        return {
          activeColor: 'red',
          fontSize: 20
        };
      }
    };
    </script>

    如果activeColor'red',并且fontSize20,那么div的文字颜色将是红色,字体大小将是20像素。

  2. 数组语法
    可以传递一个数组给:style,以应用多个样式对象。

    <template>
      <div :style="[baseStyles, overridingStyles]"></div>
    </template>
    
    <script>
    export default {
      data() {
        return {
          baseStyles: {
            color: 'blue',
            fontSize: '12px'
          },
          overridingStyles: {
            fontSize: '14px'
          }
        };
      }
    };
    </script>

    这将应用baseStylesoverridingStyles中的样式,后者的fontSize将覆盖前者的fontSize

  3. 自动添加前缀
    当使用需要浏览器前缀的CSS属性时,Vue会自动侦测并添加相应的前缀。

    <template>
      <div :style="{ display: '-webkit-box' }"></div>
    </template>

    Vue会根据浏览器自动处理前缀,无需手动添加。

  4. 使用变量
    可以在样式对象中使用变量,使得样式更加动态。

    <template>
      <div :style="styleObject"></div>
    </template>
    
    <script>
    export default {
      computed: {
        styleObject() {
          return {
            color: this.isActive ? 'green' : 'gray',
            fontWeight: this.isActive ? 'bold' : 'normal'
          };
        }
      },
      data() {
        return {
          isActive: true
        };
      }
    };
    </script>

    styleObject计算属性根据isActive的值动态返回不同的样式对象。

  5. 绑定内联样式的注意事项

    • CSS属性名可以使用驼峰式或短横线分隔(需要用引号包裹)。
    • 如果样式的值是空字符串、null或undefined,该样式将不会被渲染。
最后修改:2023 年 12 月 04 日
如果觉得我的文章对你有用,请随意赞赏