1. 基础语法

1.1. 模板语法

1.1.1. 文本插值

通过Mustache语法(即{{ }})可以将普通文本绑定到DOM

<span>Message: {{ msg }}</span>

1.1.2. 原始HTML内容

默认情况下,双大括号将数据解释为纯文本。若要输出真正的HTML,使用v-html指令

<p>文本插值:{{ rawHtml }}</p>
  <p>使用v-html指令:<span v-html="rawHtml"></span></p>

1.1.3. 属性绑定

在HTML属性中不能使用双大括号。要响应式地绑定属性,使用v-bind指令

<div v-bind:id="dynamicId"></div>

简写

<div :id="dynamicId"></div>

1.1.4. 使用JavaScript表达式

Vue在所有数据绑定中支持完整的JavaScript表达式,包括算术运算、条件运算、函数调用等。这些表达式可以使用在双大括号及任何Vue指令(以v-开头的特殊属性)中

{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}
<div :id="`list-${id}`"></div>

1.2. 类与样式绑定

1.2.1. 绑定class

1.2.1.1. 绑定对象

通过:class绑定对象时,可以根据数据属性的布尔值动态切换CSS类的应用。这个对象可以直接在模板中定义,也可以通过响应式对象来实现

<div :class="{ active: isActive }"></div>

1.2.1.2. 多类操作

:class可以与常规的class属性共存,使得同时应用静态和动态类变得简单。这种方式在保留静态类的同时,根据组件状态添加或移除其他类

<div class="static" :class="{ active: isActive, error: hasError }"></div>

1.2.1.3. 绑定计算属性

对于更复杂的类名逻辑,可以绑定一个计算属性来动态计算所需的类名。这在类名的逻辑依赖多个状态时尤为有用

<div :class="computedClass"></div>

<!DOCTYPE html>
  <html lang="zh-CN">
  <head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Vue 3 动态Class绑定</title>
  <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
  <style>
  .active { color: green; }
.error { color: red; }
.text-danger { font-weight: bold; }
.static { background-color: lightgray; }
</style>
  </head>
  <body>
  <div id="app">
  <!-- 使用对象语法绑定类 -->
  <div :class="{ active: isActive, error: hasError }">Object Syntax
  </div>
  <!-- 使用计算属性绑定类 -->
  <div :class="classObject">Computed Property</div>
  <!-- 使用静态类和动态类结合 -->
  <div class="static" :class="{ active: isActive }">Static and Dynamic
Classes</div>
  </div>
  <script>
  const { createApp, ref, computed } = Vue;
createApp({
  setup() {
    // 响应式数据
    const isActive = ref(false);
    const hasError = ref(false);
    // 在模板中直接定义的对象
    const classObject = computed(() => ({
      active: isActive.value && !hasError.value,
      'text-danger': hasError.value
    }));
    // 切换类的方法
    function toggleClass() {
      isActive.value = !isActive.value;
      hasError.value = !hasError.value;
    }
    // 每隔一秒切换类状态
    setInterval(toggleClass, 1000);
    return { isActive, hasError, classObject };
  }
}).mount('#app');
</script>
  </body>
  </html>

在这个示例中,首先CSS样式被定义在<style>标签内,用于明显地显示不同类的视觉效果。

[插图] .active类设置文本颜色为绿色。

[插图] .error类设置文本颜色为红色。

[插图] .text-danger类加粗字体。

[插图] .static类为元素添加浅灰色背景。

然后在模板中,使用了三个<div>元素来演示三种不同的动态绑定方法。

(1)第一个<div>元素展示了如何使用对象语法绑定类。:class属性接收一个对象,对象的键是类名,值是布尔表达式。当isActive为true时,active类被应用;当hasError为true时,error类被应用。

(2)第二个<div>元素展示了如何使用计算属性确定要应用的类。classObject是一个计算属性,基于响应式数据isActive和hasError的值来计算最终应用的类。

(3)第三个<div>元素演示了如何将静态类与动态类结合使用。这个元素同时使用了静态类static和基于条件的动态类active。

最后通过setInterval定义了一个定时器,每隔一秒钟切换isActive和hasError的值,以动态展示类的变化效果。

打开浏览器后,可以观察到这些<div>元素的类和样式会根据isActive和hasError的值的变化而动态更新,效果如图4-4和图4-5所示。

1.2.2. 绑定style

1.2.2.1. :style可以绑定到一个响应式对象

<div :style="{ color: textColor, fontSize: fontSize + 'px' }"></div>
setup() {
  const textColor = ref('red');
  const fontSize = ref(16);
  return { textColor, fontSize };
}

1.2.2.2. :style也支持数组语法,允许合并多个样式源

<div :style="[baseStyles, overrideStyles]"></div>
setup() {
  const baseStyles = ref({
    color: 'blue',
    margin: '10px'
  });
  const overrideStyles = ref({
    fontSize: '20px',
    margin: '15px'
  });
  return { baseStyles, overrideStyles };
}

1.3. 条件渲染与列表渲染

1.3.1. 条件渲染

1.3.1.1. v-if

<div v-if="type === 'A'">类型 A</div>
<div v-else-if="type === 'B'">类型 B</div>
<div v-else>既不是类型 A 也不是类型 B</div>

setup() {
  const type = ref('A');
  // 根据需要修改type值
  return { type };
}

1.3.1.2. v-show

v-show指令仅切换元素的display属性,但不会从DOM中移除元素。这使得v-show非常适用于频繁切换显示状态的场景。

1.3.1.3. 区别

v-if与v-show的区别如下。

[插图] v-if是真正的条件渲染指令,它确保在初始渲染时条件为false时,元素不会被渲染到DOM中。当条件变为true时,元素才会被渲染。

[插图] v-show的优势在于性能。由于元素始终保留在DOM中,因此切换显示状态不需要重复进行DOM元素的添加和移除。这在频繁变更显示状态的场景下是一个显著的优势。

1.3.2. 列表渲染

1.3.2.1. v-for

<ul>
  <li v-for="item in items" :key="item.id">{{ item.name }}</li>
</ul>
<ul>
  <li v-for="(item, index) in items" :key="item.id">
    {{ index + 1 }}. {{ item.name }}
  </li>
</ul>
<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue 3 列表渲染</title>
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
  </head>
  <body>
    <div id="app">
      <ul>
        <li v-for="(constellation, index) in constellations" :key=
          "constellation.id">
          {{ index + 1 }} - {{ constellation.name }}
        </li>
      </ul>
    </div>
    <script>
      const { createApp, ref } = Vue;
      createApp({
        setup() {
          const constellations = ref([
            { id: 1, name: '狮子座' },
            { id: 2, name: '双子座' },
            { id: 3, name: '天秤座' }
          ]);
          return { constellations };
        }
      }).mount('#app');
    </script>
  </body>
</html>

在Vue中,列表渲染不仅可以用于静态显示,还可以用于动态地修改数组。Vue提供了对数组修改的响应式支持,能够侦听数组的变更方法,并在这些方法被调用时触发相关的更新。这些变更方法如下。

[插图] push():向数组的末尾添加一个或多个元素,如items.push(newItem)。

[插图] pop():移除数组的最后一个元素,并返回这个元素,如const lastItem = items.pop()。

[插图] shift():移除数组的第一个元素,并返回这个元素,如const firstItem = items.shift()。

[插图] unshift():向数组的开头添加一个或多个元素,如items.unshift(newItem)。

[插图] splice():通过删除现有元素或添加新元素来改变一个数组的内容,如items.splice(2,0, newItem),在索引2的位置添加一个新元素。

[插图] sort():对数组的元素进行排序,如items.sort((a, b) => a.value - b.value),基于值进行排序。

[插图] reverse():颠倒数组中元素的顺序,如items.reverse()。

1.4. 事件处理

1.4.1. 常用事件

1.4.1.1. click事件

click事件是最常见的事件类型,用于响应鼠标单击动作。

<button @click="handleClick">单击我</button>

1.4.1.2. submit事件

submit事件用于表单提交。

<form @submit.prevent="handleSubmit">
  <button type="submit">提交</button>
</form

1.4.1.3. input事件

input事件在输入字段的值发生变化时触发,常用于处理实时用户输入。

<input @input="handleInput" />

1.4.1.4. mouseover和mouseout事件

mouseover和mouseout事件在鼠标指针悬停或移出元素时触发。

<div @mouseover="handleMouseOver" @mouseout="handleMouseOut">悬停区域</div>

1.4.1.5. keydown、keypress、keyup事件

keydown、keypress、keyup用于处理键盘事件。

<input @keydown="handleKeyDown" />

1.4.2. 事件对象

在处理事件时,Vue会自动将原生事件对象作为事件处理函数的第一个参数传递。这允许在事件处理函数中直接访问并操作事件对象。

<button @click="handleClick">单击我</button>
function handleClick(event) {
  console.log(event.target);  // 访问事件的目标元素
}

要同时访问事件对象和自定义参数时,可以使用箭头函数。

<button @click="event => handleClick(event, 'Hello, Vue!')">单击我</button>
function handleClick(event, message) {
  console.log(event.target);  // 访问事件的目标元素
  console.log(message);            // 输出自定义信息
}

也可以使用Vue中特殊的$event变量来显式地传递原生事件对象。

<button @click="handleClick($event, '自定义信息')">单击我</button>

1.4.3. 事件修饰符

(1).stop:用于调用event.stopPropagation(),阻止事件继续传播。

<button @click.stop="handleClick">单击我</button>

(2).prevent:用于调用event.preventDefault(),阻止事件的默认行为。

<form @submit.prevent="handleSubmit">提交</form>

(3).once:事件只触发一次。

<button @click.once="handleClick">单击我</button>

(4).enter、.tab、.delete、.esc等,用于键盘事件。

<input @keyup.enter="onEnter">

(5). passive:改善滚动性能的事件处理,特别是在移动端。

<div @scroll.passive="handleScroll">…</div>

1.5. 双向绑定

(1)文本输入:对于<input>(文本类型)和<textarea>元素,v-model绑定到元素的value属性,并侦听input事件。

<input v-model="textValue" type="text">
  <textarea v-model="textAreaValue"></textarea>

(2)对于<input type="checkbox">和input type="radio">,v-model绑定到checked属性,并侦听change事件。

<input v-model="checkedValue" type="checkbox">
  <input v-model="radioValue" type="radio">

(3)下拉选择:对于<select>元素,v-model同样绑定到value属性,并侦听change事件。

<select v-model="selectedOption">
  <option value="option1">选项1</option>
  <option value="option2">选项2</option>
  </select>

1.6. 监听器

在Vue 3中,监听器通过watch()函数实现。watch()函数接收两个参数:要观察的响应式引用和当观察的数据变化时调用的回调函数。

<!DOCTYPE html>
  <html lang="zh-CN">
  <head>
  <meta charset="UTF-8">
  <title>Vue 3 应用</title>
  <script src="https://unpkg.com/vue@next"></script>
  </head>
  <body>
  <div id="app">
  <input v-model="inputText" />
  </div>
  <script>
  const { createApp, ref, watch } = Vue;
createApp({
  setup() {
    // 定义一个响应式引用
    const inputText = ref('');
    // 设置一个监听器
    watch(inputText, (newValue, oldValue) => {
      console.log(`新输入的文本是:${newValue}`);
    });
    // 返回模板中需要的数据
    return { inputText };
  }
}).mount('#app');
</script>
  </body>
  </html>

在这个示例中,使用watch函数来监听inputText的变化。每当inputText变化时,就会执行传递给watch的回调函数,这里是在控制台打印新的输入值。