Vue 3 声明式渲染语法指南

本文将详细介绍 Vue 3 中的声明式渲染语法,涵盖所有核心概念,并通过一个完整的案例代码进行演示。案例代码中包含详细注释,帮助初学者更好地理解每个部分的功能和用法。

目录

  1. 简介
  2. 声明式渲染基础
  3. 指令
  4. 计算属性和侦听器
  5. 案例代码:简单的待办事项应用
  6. 总结

简介

Vue 3 是一个用于构建用户界面的渐进式 JavaScript 框架。它采用声明式渲染,使得开发者能够以简洁、直观的方式描述 UI 的状态和变化。本文将介绍 Vue 3 中声明式渲染的核心语法,并通过一个实际的案例帮助理解。

声明式渲染基础

文本插值

使用双大括号 {{ }} 可以将数据绑定到模板中的文本节点。

<template>
  <div>
    <p>你好,{{ username }}!</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      username: 'Vue 开发者'
    };
  }
};
</script>

属性绑定

使用 v-bind 指令(或其简写 :)将数据绑定到 HTML 属性上。

<template>
  <div>
    <img v-bind:src="imageUrl" alt="Vue Logo">
    <!-- 简写 -->
    <img :src="imageUrl" alt="Vue Logo">
  </div>
</template>

<script>
export default {
  data() {
    return {
      imageUrl: 'https://vuejs.org/images/logo.png'
    };
  }
};
</script>

使用 JavaScript 表达式

在模板中可以使用 JavaScript 表达式进行简单的计算或逻辑处理。

<template>
  <div>
    <p>1 + 1 = {{ 1 + 1 }}</p>
    <p>反转后的用户名: {{ username.split('').reverse().join('') }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      username: 'Vue 开发者'
    };
  }
};
</script>

指令

v-bind

用于动态绑定 HTML 属性或组件的 props。

<!-- 绑定属性 -->
<a v-bind:href="url">访问网站</a>
<!-- 简写 -->
<a :href="url">访问网站</a>

v-on

用于监听 DOM 事件。

<!-- 监听点击事件 -->
<button v-on:click="handleClick">点击我</button>
<!-- 简写 -->
<button @click="handleClick">点击我</button>

v-model

用于在表单控件元素或组件上创建双向数据绑定。

<template>
  <div>
    <input v-model="message" placeholder="输入内容">
    <p>你输入的内容是: {{ message }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: ''
    };
  }
};
</script>

v-if, v-else-if, v-else

根据条件渲染元素。

<template>
  <div>
    <p v-if="isLoggedIn">欢迎回来!</p>
    <p v-else>请登录。</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      isLoggedIn: true
    };
  }
};
</script>

v-for

用于渲染列表。

<template>
  <div>
    <ul>
      <li v-for="(item, index) in items" :key="index">
        {{ item }}
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  data() {
    return {
      items: ['苹果', '香蕉', '橘子']
    };
  }
};
</script>

v-show

根据条件显示或隐藏元素(通过 CSS 控制显示)。

<template>
  <div>
    <p v-show="isVisible">这是一个可见的段落。</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      isVisible: true
    };
  }
};
</script>

计算属性和侦听器

计算属性

计算属性是基于它们的依赖进行缓存的,只有在相关依赖发生改变时才会重新求值。

<template>
  <div>
    <p>原始消息: {{ message }}</p>
    <p>反转后的消息: {{ reversedMessage }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: 'Hello Vue!'
    };
  },
  computed: {
    reversedMessage() {
      return this.message.split('').reverse().join('');
    }
  }
};
</script>

侦听器

侦听器用于在数据变化时执行异步或开销较大的操作。

<template>
  <div>
    <input v-model="question" placeholder="输入问题">
    <p>{{ answer }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      question: '',
      answer: '等待输入...'
    };
  },
  watch: {
    question(newQuestion) {
      if (newQuestion.trim()) {
        this.answer = '正在思考...';
        // 模拟异步操作
        setTimeout(() => {
          this.answer = `你问的问题是: ${newQuestion}`;
        }, 2000);
      } else {
        this.answer = '等待输入...';
      }
    }
  }
};
</script>

案例代码:简单的待办事项应用

下面是一个简单的待办事项应用示例,展示了 Vue 3 的声明式渲染语法。该应用允许用户添加、删除和标记待办事项。

项目结构

src/
│
├── components/
│   └── TodoItem.vue
│
├── App.vue
│
└── main.js

完整代码

1. main.js
// main.js
import { createApp } from 'vue';
import App from './App.vue';

createApp(App).mount('#app');
2. App.vue
<!-- App.vue -->
<template>
  <div id="app">
    <h1>我的待办事项</h1>
    <input v-model="newTodo" @keyup.enter="addTodo" placeholder="添加待办事项" />
    <button @click="addTodo">添加</button>
    <ul>
      <TodoItem
        v-for="(todo, index) in todos"
        :key="index"
        :todo="todo"
        @delete="deleteTodo(index)"
        @toggle="toggleTodo(index)"
      />
    </ul>
    <p>{{ remaining }} 个待办事项未完成。</p>
  </div>
</template>

<script>
import TodoItem from './components/TodoItem.vue';

export default {
  components: {
    TodoItem
  },
  data() {
    return {
      newTodo: '',
      todos: []
    };
  },
  computed: {
    remaining() {
      return this.todos.filter(todo => !todo.completed).length;
    }
  },
  methods: {
    addTodo() {
      const trimmedTodo = this.newTodo.trim();
      if (trimmedTodo) {
        this.todos.push({ text: trimmedTodo, completed: false });
        this.newTodo = '';
      }
    },
    deleteTodo(index) {
      this.todos.splice(index, 1);
    },
    toggleTodo(index) {
      this.todos[index].completed = !this.todos[index].completed;
    }
  }
};
</script>

<style>
#app {
  font-family: Arial, sans-serif;
  max-width: 600px;
  margin: 0 auto;
  padding: 20px;
}
input {
  padding: 8px;
  width: 70%;
  margin-right: 10px;
}
button {
  padding: 8px;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  margin: 10px 0;
  display: flex;
  align-items: center;
}
.completed {
  text-decoration: line-through;
  color: gray;
}
</style>
3. TodoItem.vue
<!-- TodoItem.vue -->
<template>
  <li>
    <input type="checkbox" v-model="todo.completed" @change="toggle" />
    <span :class="{ completed: todo.completed }">{{ todo.text }}</span>
    <button @click="deleteItem">删除</button>
  </li>
</template>

<script>
export default {
  props: {
    todo: {
      type: Object,
      required: true
    }
  },
  methods: {
    deleteItem() {
      this.$emit('delete');
    },
    toggle() {
      this.$emit('toggle');
    }
  }
};
</script>

<style scoped>
.completed {
  text-decoration: line-through;
  color: gray;
}
button {
  margin-left: 10px;
  padding: 4px;
}
</style>

代码解析

  1. 主应用 (App.vue):

    • 数据 (data):
      • newTodo: 用于存储用户输入的新待办事项。
      • todos: 存储所有待办事项的数组。
    • 计算属性 (computed):
      • remaining: 计算未完成的待办事项数量。
    • 方法 (methods):
      • addTodo: 添加新的待办事项到 todos 数组中。
      • deleteTodo: 删除指定索引的待办事项。
      • toggleTodo: 切换指定索引的待办事项的完成状态。
    • 模板 (template):
      • 使用 v-model 实现输入框与 newTodo 的双向绑定。
      • 使用 @keyup.enter 监听回车键事件,调用 addTodo 方法。
      • 使用 v-for 指令遍历 todos 数组,渲染每个待办事项。
      • 使用 v-bind 动态绑定 TodoItem 组件的 todo prop。
      • 使用 @delete@toggle 监听子组件的 deletetoggle 事件,调用相应的方法。
      • 显示剩余的未完成待办事项数量。
  2. 子组件 (TodoItem.vue):

    • Props (props):
      • todo: 接收单个待办事项对象。
    • 方法 (methods):
      • deleteItem: 触发 delete 事件,通知父组件删除当前待办事项。
      • toggle: 触发 toggle 事件,通知父组件切换当前待办事项的完成状态。
    • 模板 (template):
      • 使用 v-model 实现复选框与 todo.completed 的双向绑定。
      • 使用 :class 动态绑定样式类 completed,根据 todo.completed 的值决定是否添加。
      • 使用 @click 监听删除按钮的点击事件,调用 deleteItem 方法。
  3. 样式 (style):

    • 使用 scoped 样式,确保样式只作用于当前组件。
    • .completed 类用于显示删除线,标识已完成的待办事项。

总结

本文详细介绍了 Vue 3 中的声明式渲染语法,涵盖了文本插值、属性绑定、指令、计算属性和侦听器等核心概念。通过一个简单的待办事项应用示例,展示了如何将这些概念应用到实际项目中。掌握这些基础知识后,开发者可以进一步探索 Vue 3 的其他高级特性,如组件化、路由管理、状态管理等,以构建更复杂和功能丰富的应用。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐