1.vue体验

初体验 Vue 2

官网https://v2.cn.vuejs.org/v2/guide/

安装

首先,你需要在你的项目中安装 Vue 2。可以通过 CDN 引入,这对于学习和小规模项目来说非常方便:

复制代码
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
创建一个简单的 Vue 应用
  1. HTML 文件:在你的 HTML 文件中添加一个元素作为 Vue 实例的挂载点。

    复制代码
    <div id="app">
      {{ message }}
    </div>
  2. 初始化 Vue 实例 :接下来,在你的 JavaScript 文件中创建一个新的 Vue 实例,并指定 el 属性为你的挂载点,data 属性包含你想要绑定的数据。

    复制代码
    new Vue({
      el: '#app',
      data: {
        message: 'Hello Vue!'
      }
    });

当你运行这个简单的例子时,你应该能够在页面上看到 "Hello Vue!" 文本。这是与 Vue 进行交互的一个非常基本的例子。

vue指令

Vue 2 中的指令是带有 v- 前缀的特殊属性,它们用于在模板中直接应用 Vue 的响应式特性。指令的核心作用是在表达式执行后,对 DOM 进行操作。以下是一些常用的 Vue 2 指令及其详细解释:

1. v-text

  • 用途:更新元素内的文本内容。

  • 示例

    复制代码
    <span v-text="message"></span>
    <!-- 等同于 -->
    <span>{{ message }}</span>

2. v-html

  • 用途:更新元素的 innerHTML。注意,由于它会直接作为 HTML 进行渲染,因此使用时需谨慎处理不受信任的内容,以避免 XSS 攻击。

  • 示例

    复制代码
    <div v-html="rawHtml"></div>

3. v-show

  • 用途 :根据表达式的真假值来切换元素的显示或隐藏(通过 CSS 的 display 属性)。

  • 示例

    复制代码
    <h1 v-show="isShow">Hello!</h1>

4. v-if, v-else-if, v-else

  • 用途 :条件性地渲染一块内容。v-if 是"真正的"条件渲染,因为它确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。v-else-ifv-else 需与 v-ifv-else-if 配合使用。

  • 示例

    复制代码
    <div v-if="type === 'A'">A</div>
    <div v-else-if="type === 'B'">B</div>
    <div v-else>Not A/B</div>

5. v-for

  • 用途 :基于源数据多次渲染元素或模板块。此指令需要使用特定的语法形式,如 item in items

  • 示例

    复制代码
    <ul>
      <li v-for="(item, index) in items" :key="index">{{ item.name }}</li>
    </ul>

6. v-on

  • 用途:绑定事件监听器。

  • 示例

    复制代码
    <button v-on:click="doSomething">Click Me</button>
    <!-- 缩写 -->
    <button @click="doSomething">Click Me</button>

7. v-bind

  • 用途:动态地绑定一个或多个属性,或一个组件 prop 到表达式。

  • 示例

    复制代码
    <img v-bind:src="imageSrc">
    <!-- 缩写 -->
    <img :src="imageSrc">

8. v-model

  • 用途:创建双向数据绑定,在表单控件或者组件上使用。

  • 示例

    复制代码
    <input v-model="message" placeholder="edit me">

计算属性

计算属性定义在 Vue 实例的 computed 选项中,就像方法一样,但它们会自动追踪其依赖的数据,并且只在依赖数据发生变化时重新计算结果。

复制代码
var vm = new Vue({
  el: '#example',
  data: {
    message: 'Hello'
  },
  computed: {
    // 计算属性 getter
    reversedMessage: function () {
      return this.message.split('').reverse().join('');
    }
  }
});

在这个例子中,reversedMessage 是一个计算属性,它根据 message 的值动态计算出反转后的字符串。

计算属性 vs 方法

虽然你可以通过方法实现同样的功能,但是计算属性是基于它的依赖进行缓存的。只有当它的依赖发生变化时,才会重新求值。这对于性能优化非常有用,特别是在计算开销较大的情况下。

复制代码
<div id="demo">{{ reversedMessage }}</div>
<div>{{ result() }}</div>

<script>
new Vue({
  el: '#demo',
  data: {
    message: 'Hello Vue!'
  },
  computed: {
    reversedMessage: function () {
      console.log('计算属性被调用');
      return this.message.split('').reverse().join('');
    }
  },
  methods: {
    result: function () {
      console.log('方法被调用');
      return this.message.split('').reverse().join('');
    }
  }
});
</script>

当你多次访问 reversedMessage,只会看到一次 "计算属性被调用" 的日志,而每次访问 result() 都会打印 "方法被调用"。

计算属性的 setter

默认情况下,计算属性只有 getter,不过你也可以提供一个 setter:

复制代码
computed: {
  fullName: {
    // getter
    get: function () {
      return this.firstName + ' ' + this.lastName;
    },
    // setter
    set: function (newValue) {
      var names = newValue.split(' ');
      this.firstName = names[0];
      this.lastName = names[names.length - 1];
    }
  }
}

现在当你修改 fullName 时,setter 会被调用,相应的 firstNamelastName 也会更新。

定义方法

在 Vue 2 中,方法(methods)是定义在 Vue 实例的 methods 选项中的函数。它们可以被用来定义事件处理器、执行数据操作、发起异步请求等。与计算属性不同,方法不会基于其依赖进行缓存,每次调用都会执行函数体内的代码。

你可以像下面这样在 Vue 实例中定义方法:

复制代码
new Vue({
  el: '#example',
  data: {
    message: 'Hello Vue!'
  },
  methods: {
    reverseMessage: function () {
      return this.message.split('').reverse().join('');
    },
    greet: function (event) {
      // `this` 在方法里指向当前 Vue 实例
      alert('Hello ' + this.message + '!');
      // `event` 是原生 DOM 事件
      if (event) {
        alert(event.target.tagName);
      }
    }
  }
});

在这个例子中,我们定义了两个方法:reverseMessagegreet。前者简单地反转了 message 的值,后者则展示了如何处理一个事件,并使用了传递给它的参数(如 event)。

调用方法
  • 直接调用:你可以在 JavaScript 代码中直接调用这些方法。
  • 通过事件绑定调用 :也可以通过 v-on 指令将方法绑定到特定的 DOM 事件上。

例如,在 HTML 中通过点击按钮触发 greet 方法:

复制代码
<div id="example">
    <button v-on:click="greet">这个方法不带event</button>
        <br/><br/>
    <button v-on:click="greet()">这个方法不带event</button>
 <br/><br/>
    <button v-on:click="greet(event)">如果带参数,可以传递内置事件对象event</button>

    <!-- 使用插值表达式显示方法的返回值 (文本内容) -->
    <p>{{ reverseMessage() }}</p>

    <!-- 使用 v-text 显示方法的返回值 (文本内容) -->
    <p v-text="reverseMessage()"></p>
</div>

<button v-on:click="greet(event)">如果带参数,可以传递内置事件对象event</button>

参考 5.2.1 javascript 事件对象.内容补充.-CSDN博客

方法 vs 计算属性

虽然方法和计算属性都可以用于处理逻辑并返回结果,但它们之间有一些重要的区别:

  • 缓存:计算属性会基于它们的依赖进行缓存,只有当相关依赖发生改变时才会重新求值。而方法则没有这种缓存机制,每次调用都会执行函数体内的代码。
  • 用途:计算属性更适合用于根据其他数据的变化来计算值的情况,尤其是当你需要展示计算后的结果时。而方法则更适合用于处理事件、执行异步操作或其它不涉及展示逻辑的操作。

异步操作示例

方法非常适合处理异步操作,比如从服务器获取数据:

复制代码
new Vue({
  el: '#app',
  data: {
    message: 'Loading...',
    posts: []
  },
  methods: {
    fetchData: function() {
      var vm = this;
      setTimeout(function() {
        vm.message = 'Data loaded';
        vm.posts = [
          { id: 1, title: 'First Post' },
          { id: 2, title: 'Second Post' }
        ];
      }, 1000);
    }
  }
});

在这个例子中,fetchData 方法模拟了一个异步的数据获取过程,并更新了 messageposts 数据。

总结

  • 方法:用于定义可重复使用的函数,可以包含任意复杂的逻辑,包括异步操作。适合处理交互行为和动态响应用户输入。
  • 计算属性:更适合于基于其他数据的变化来计算值,并且能够利用缓存提升性能,特别适用于展示经过计算的结果。

综合案例

复制代码
<!DOCTYPE html>
<html lang="zh-cn">
<head>
  <meta charset="UTF-8">
  <title>Vue 2 Todo App</title>
  <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
  <style>
    .completed {
      text-decoration: line-through;
      color: #888;
    }
    .todo-item {
      margin: 5px 0;
    }
  </style>
</head>
<body>
  <div id="app">
    <h1>我的待办事项</h1>

    <!-- 输入框用于添加新任务 -->
    <input 
      v-model="newTodo" 
      @keyup.enter="addTodo" 
      placeholder="添加新任务..." 
      class="todo-input"
    >
    <button @click="addTodo">添加</button>

    <!-- 显示待办事项列表 -->
    <ul>
      <li 
        v-for="(todo, index) in todos" 
        :key="index" 
        :class="{ completed: todo.done }"
        class="todo-item"
      >
        <!-- 使用 v-model 创建双向绑定 -->
        <input 
          type="checkbox" 
          v-model="todo.done"
        >
        <!-- 使用 v-text 显示任务文本 -->
        <span v-text="todo.text"></span>
        <!-- 删除按钮 -->
        <button @click="removeTodo(index)">删除</button>
      </li>
    </ul>

    <!-- 使用 v-show 显示未完成任务数量 -->
    <p v-show="remainingCount > 0">
      还有 {{ remainingCount }} 项任务未完成。
    </p>
    <!-- 使用 v-if 显示所有任务已完成的消息 -->
    <p v-if="remainingCount === 0 && todos.length > 0">
      恭喜!所有任务都已完成。
    </p>
    <!-- 使用 v-else 显示没有任务时的消息 -->
    <p v-else-if="todos.length === 0">
      暂无待办事项。
    </p>
  </div>

  <script>
    new Vue({
      el: '#app',
      data: {
        newTodo: '', // 输入框中的新任务文本
        todos: []    // 存储所有待办事项的数组
      },
      computed: {
        // 计算属性:计算未完成任务的数量
        remainingCount() {
          return this.todos.filter(todo => !todo.done).length;
        }
      },
      methods: {
        // 添加新任务
        addTodo() {
          if (this.newTodo.trim()) {
            this.todos.push({
              text: this.newTodo,
              done: false
            });
            this.newTodo = ''; // 清空输入框
          }
        },
        // 删除指定索引的任务
        removeTodo(index) {
          this.todos.splice(index, 1);
        }
      }
    });
  </script>
</body>
</html>