【Vue】最新Vue3实战教程:全面掌握响应式数据、v-on事件、v-if_v-show条件渲染及更多核心技术

457 阅读9分钟

为什么选择Vue3?

在开始之前,让我们先了解一下为何选择Vue3作为你的前端框架。Vue3不仅在性能上有显著提升,尤其是在大规模应用上的表现更为出色,同时它还引入了诸如组合式API(Composition API)等新特性,使得代码更加简洁、可维护。与其他框架如React和Angular相比,Vue3在学习曲线和灵活性方面表现优异,适合多种开发场景。

更多实用工具

【OpenAI】获取OpenAI API Key的多种方式全攻略:从入门到精通,再到详解教程!!

【VScode】VSCode中的智能编程利器,全面揭秘ChatMoss & ChatGPT中文版

体验最新的GPT系列模型!支持Open API调用、自定义助手、文件上传等强大功能,助您提升工作效率!点击链接体验:CodeMoss & ChatGPT-AI中文版 在这里插入图片描述

快速上手Vue3

安装与配置

要开始使用Vue3,首先需要安装Node.js和npm。安装完成后,可以通过以下命令创建一个Vue3项目:

npm install -g @vue/cli
vue create my-vue3-app

在选择配置时,建议选择默认配置或根据项目需求自定义配置。创建完成后,进入项目目录并启动开发服务器:

cd my-vue3-app
npm run serve

浏览器打开http://localhost:8080,你将看到Vue3默认的欢迎页面。

项目结构

一个典型的Vue3项目结构如下:

my-vue3-app
├── node_modules
├── public
│   └── index.html
├── src
│   ├── assets
│   ├── components
│   ├── App.vue
│   └── main.js
├── package.json
└── vue.config.js
  • public/index.html:应用的入口HTML文件。
  • src/main.js:Vue应用的入口文件,负责创建和挂载Vue实例。
  • src/App.vue:根组件。
  • src/components/:存放各个组件的目录。

响应式数据处理

响应式数据是Vue的核心特性之一,使得数据变化能够自动反映到视图中。Vue3使用Proxy机制实现响应式,比Vue2的Object.defineProperty更加高效和强大。

创建响应式数据

在Vue3中,可以使用refreactive来创建响应式数据。

使用ref

ref用于创建基本数据类型的响应式引用。

<template>
  <div>
    <p>计数:{{ count }}</p>
    <button @click="increment">增加</button>
  </div>
</template>

<script>
import { ref } from 'vue'

export default {
  setup() {
    const count = ref(0)
    const increment = () => {
      count.value++
    }
    return { count, increment }
  }
}
</script>

使用reactive

reactive用于创建对象或数组的响应式状态。

<template>
  <div>
    <p>用户姓名:{{ user.name }}</p>
    <p>用户年龄:{{ user.age }}</p>
    <button @click="increaseAge">增龄</button>
  </div>
</template>

<script>
import { reactive } from 'vue'

export default {
  setup() {
    const user = reactive({
      name: '张三',
      age: 25
    })
    const increaseAge = () => {
      user.age++
    }
    return { user, increaseAge }
  }
}
</script>

计算属性与侦听器

除了简单的响应式数据,Vue3还提供了计算属性(computed)和侦听器(watch)来处理更复杂的逻辑。

计算属性

计算属性基于响应式数据自动计算并缓存结果,只有相关依赖变化时才重新计算。

<template>
  <div>
    <p>原始计数:{{ count }}</p>
    <p>双倍计数:{{ doubleCount }}</p>
    <button @click="increment">增加</button>
  </div>
</template>

<script>
import { ref, computed } from 'vue'

export default {
  setup() {
    const count = ref(0)
    const doubleCount = computed(() => count.value * 2)
    const increment = () => {
      count.value++
    }
    return { count, doubleCount, increment }
  }
}
</script>

侦听器

侦听器用于监听响应式数据的变化,并在数据变化时执行相应的操作。

<template>
  <div>
    <input v-model="name" placeholder="请输入姓名" />
    <p>姓名:{{ name }}</p>
  </div>
</template>

<script>
import { ref, watch } from 'vue'

export default {
  setup() {
    const name = ref('')
    watch(name, (newName, oldName) => {
      console.log(`姓名从 ${oldName} 修改为 ${newName}`)
    })
    return { name }
  }
}
</script>

事件绑定与处理(v-on)

在Vue中,事件处理是前端开发中不可或缺的一部分。v-on指令用于绑定事件监听器,简化了传统的JavaScript事件处理方式。

基本用法

使用v-on绑定一个点击事件:

<template>
  <button v-on:click="handleClick">点击我</button>
</template>

<script>
export default {
  methods: {
    handleClick() {
      alert('按钮被点击了!')
    }
  }
}
</script>

简写语法

Vue提供了@作为v-on的简写:

<template>
  <button @click="handleClick">点击我</button>
</template>

事件修饰符

Vue提供了多种事件修饰符,用于简化事件处理逻辑,如.prevent防止默认行为、.stop阻止事件传播等。

<template>
  <form @submit.prevent="handleSubmit">
    <input v-model="inputText" />
    <button type="submit">提交</button>
  </form>
</template>

<script>
export default {
  data() {
    return {
      inputText: ''
    }
  },
  methods: {
    handleSubmit() {
      console.log('表单提交,输入内容:', this.inputText)
    }
  }
}
</script>

绑定多个事件

可以在一个元素上绑定多个事件监听器:

<template>
  <div>
    <input @focus="handleFocus" @blur="handleBlur" />
  </div>
</template>

<script>
export default {
  methods: {
    handleFocus() {
      console.log('输入框获得焦点')
    },
    handleBlur() {
      console.log('输入框失去焦点')
    }
  }
}
</script>

条件渲染(v-if与v-show)

在前端开发中,根据不同的条件展示不同的内容是常见的需求。Vue提供了v-ifv-show两种指令来实现条件渲染。

v-if

v-if根据条件真伪来决定是否渲染DOM元素,如果条件为假,DOM元素不会存在于页面中。

<template>
  <div>
    <button @click="toggle">切换显示</button>
    <p v-if="isVisible">现在你看到我了!</p>
  </div>
</template>

<script>
import { ref } from 'vue'

export default {
  setup() {
    const isVisible = ref(true)
    const toggle = () => {
      isVisible.value = !isVisible.value
    }
    return { isVisible, toggle }
  }
}
</script>

v-show

v-show通过CSS的display属性来控制元素的显示与隐藏,而不涉及DOM的插入与移除。

<template>
  <div>
    <button @click="toggle">切换显示</button>
    <p v-show="isVisible">现在你看到我了!</p>
  </div>
</template>

<script>
import { ref } from 'vue'

export default {
  setup() {
    const isVisible = ref(true)
    const toggle = () => {
      isVisible.value = !isVisible.value
    }
    return { isVisible, toggle }
  }
}
</script>

v-if与v-show的区别

  • 渲染机制v-if是真正的条件渲染,能根据条件动态地添加或移除DOM元素;v-show始终会渲染DOM元素,只是通过CSS控制其显示与隐藏。
  • 性能考虑v-if在条件切换频繁时性能较低,因为每次条件变化都会触发DOM的添加与移除;v-show适用于频繁切换显示状态的场景,因为隐藏与显示仅涉及CSS样式的改变。
  • 初始渲染v-if在初始渲染时会根据条件决定是否渲染;v-show则会始终渲染元素。

列表渲染(v-for)

在需要展示动态列表数据时,v-for指令可以高效地遍历数组或对象,并生成对应的DOM元素。

基本用法

遍历数组展示列表项:

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

<script>
import { ref } from 'vue'

export default {
  setup() {
    const items = ref(['苹果', '香蕉', '橙子'])
    return { items }
  }
}
</script>

使用对象遍历

遍历对象的键值对:

<template>
  <ul>
    <li v-for="(value, key) in user" :key="key">{{ key }}: {{ value }}</li>
  </ul>
</template>

<script>
import { reactive } from 'vue'

export default {
  setup() {
    const user = reactive({
      name: '李四',
      age: 30,
      occupation: '工程师'
    })
    return { user }
  }
}
</script>

在循环中使用索引

有时候需要在循环中使用当前项的索引:

<template>
  <ol>
    <li v-for="(item, index) in items" :key="index">
      {{ index + 1 }}. {{ item }}
    </li>
  </ol>
</template>

<script>
import { ref } from 'vue'

export default {
  setup() {
    const items = ref(['学习Vue3', '编写实战项目', '掌握核心技术'])
    return { items }
  }
}
</script>

动态添加与删除列表项

结合事件处理,实现动态管理列表:

<template>
  <div>
    <input v-model="newItem" placeholder="添加新项" />
    <button @click="addItem">添加</button>
    <ul>
      <li v-for="(item, index) in items" :key="index">
        {{ item }}
        <button @click="removeItem(index)">删除</button>
      </li>
    </ul>
  </div>
</template>

<script>
import { ref } from 'vue'

export default {
  setup() {
    const items = ref(['学习Vue3', '编写实战项目', '掌握核心技术'])
    const newItem = ref('')
    const addItem = () => {
      if (newItem.value.trim()) {
        items.value.push(newItem.value.trim())
        newItem.value = ''
      }
    }
    const removeItem = (index) => {
      items.value.splice(index, 1)
    }
    return { items, newItem, addItem, removeItem }
  }
}
</script>

属性绑定(v-bind)

v-bind指令用于动态绑定HTML属性,简化了动态属性赋值的过程。

基本用法

动态绑定元素的href属性:

<template>
  <a v-bind:href="url">点击访问</a>
</template>

<script>
import { ref } from 'vue'

export default {
  setup() {
    const url = ref('https://www.example.com')
    return { url }
  }
}
</script>

简写语法

使用冒号(:)作为v-bind的简写:

<template>
  <img :src="imageSrc" :alt="imageAlt" />
</template>

<script>
import { ref } from 'vue'

export default {
  setup() {
    const imageSrc = ref('https://via.placeholder.com/150')
    const imageAlt = ref('示例图片')
    return { imageSrc, imageAlt }
  }
}
</script>

绑定多个属性

可以使用对象语法一次性绑定多个属性:

<template>
  <button v-bind="buttonProps">点击我</button>
</template>

<script>
import { reactive } from 'vue'

export default {
  setup() {
    const buttonProps = reactive({
      id: 'submit-btn',
      class: 'btn btn-primary',
      disabled: false
    })
    return { buttonProps }
  }
}
</script>

绑定类与样式

动态绑定CSS类和内联样式:

<template>
  <div :class="{ active: isActive }" :style="{ color: textColor }">
    动态样式示例
  </div>
  <button @click="toggleActive">切换激活状态</button>
</template>

<script>
import { ref } from 'vue'

export default {
  setup() {
    const isActive = ref(false)
    const textColor = ref('black')
    const toggleActive = () => {
      isActive.value = !isActive.value
      textColor.value = isActive.value ? 'green' : 'black'
    }
    return { isActive, textColor, toggleActive }
  }
}
</script>

<style>
.active {
  font-weight: bold;
}
</style>

实战项目:构建一个Todo应用

通过前述介绍的核心技术,本节将带你一步步构建一个简单但功能完善的Todo应用,涵盖响应式数据管理、事件处理、条件渲染、列表循环和属性绑定等。

项目结构

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

TodoItem组件

用于展示单个Todo项。

<!-- src/components/TodoItem.vue -->
<template>
  <li :class="{ completed: todo.completed }">
    <input type="checkbox" v-model="todo.completed" @change="toggleComplete" />
    <span>{{ todo.text }}</span>
    <button @click="removeTodo">删除</button>
  </li>
</template>

<script>
export default {
  props: {
    todo: Object,
    index: Number
  },
  methods: {
    toggleComplete() {
      this.$emit('toggle-complete', this.index)
    },
    removeTodo() {
      this.$emit('remove-todo', this.index)
    }
  }
}
</script>

<style scoped>
.completed {
  text-decoration: line-through;
  color: gray;
}
</style>

TodoList组件

用于展示Todo列表及添加新Todo项。

<!-- src/components/TodoList.vue -->
<template>
  <div>
    <h2>Todo List</h2>
    <input v-model="newTodo" @keyup.enter="addTodo" placeholder="添加新任务" />
    <button @click="addTodo">添加</button>
    <ul>
      <TodoItem
        v-for="(todo, index) in todos"
        :key="index"
        :todo="todo"
        :index="index"
        @toggle-complete="toggleComplete"
        @remove-todo="removeTodo"
      />
    </ul>
    <p v-if="todos.length === 0">当前没有任务。</p>
  </div>
</template>

<script>
import { ref } from 'vue'
import TodoItem from './TodoItem.vue'

export default {
  components: { TodoItem },
  setup() {
    const todos = ref([
      { text: '学习Vue3', completed: false },
      { text: '构建实战项目', completed: false },
      { text: '掌握核心技术', completed: false }
    ])
    const newTodo = ref('')

    const addTodo = () => {
      if (newTodo.value.trim()) {
        todos.value.push({ text: newTodo.value.trim(), completed: false })
        newTodo.value = ''
      }
    }

    const toggleComplete = (index) => {
      todos.value[index].completed = !todos.value[index].completed
    }

    const removeTodo = (index) => {
      todos.value.splice(index, 1)
    }

    return { todos, newTodo, addTodo, toggleComplete, removeTodo }
  }
}
</script>

<style scoped>
input {
  padding: 8px;
  width: 200px;
  margin-right: 10px;
}
button {
  padding: 8px 12px;
}
ul {
  list-style-type: none;
  padding: 0;
}
</style>

App组件

将TodoList集成到主应用中。

<!-- src/App.vue -->
<template>
  <div id="app">
    <h1>我的Todo应用</h1>
    <TodoList />
  </div>
</template>

<script>
import TodoList from './components/TodoList.vue'

export default {
  components: {
    TodoList
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  text-align: center;
  margin-top: 50px;
}
</style>

通过上述步骤,我们成功构建了一个功能完善的Todo应用,涵盖了Vue3的核心技术。你可以根据需求进一步扩展功能,如添加任务优先级、分类、搜索过滤等。

优化与最佳实践

在实际开发中,遵循最佳实践和优化策略能够大幅提升应用的性能和可维护性。以下是一些Vue3开发中的优化建议:

使用组合式API(Composition API)

组合式API通过函数组合来组织组件逻辑,提高代码的复用性和可读性。相比于选项式API,组合式API更适合复杂组件的开发。

import { ref, computed } from 'vue'

export default {
  setup() {
    const firstName = ref('John')
    const lastName = ref('Doe')
    const fullName = computed(() => `${firstName.value} ${lastName.value}`)

    return { firstName, lastName, fullName }
  }
}

按需引入

在大型项目中,按需引入组件和库可以减少打包体积,提升加载速度。例如,使用Vue的异步组件加载:

import { defineAsyncComponent } from 'vue'

export default {
  components: {
    AsyncComponent: defineAsyncComponent(() =>
      import('./components/AsyncComponent.vue')
    )
  }
}

代码分割与懒加载

利用Webpack或Vite等构建工具进行代码分割,将不同模块的代码分开打包,减少初始加载时间。

使用v-bind避免不必要的DOM更新

在列表渲染中,使用唯一的key属性可以帮助Vue更高效地更新DOM。

<li v-for="item in items" :key="item.id">{{ item.text }}</li>

优化响应式数据结构

避免在响应式对象中频繁添加或删除属性,因为这可能导致性能问题。可以预先定义所需的属性,或使用reactive的另一种形式。

避免不必要的计算属性和侦听器

只有在确实需要时才使用计算属性和侦听器,避免过度使用它们导致性能下降。

使用Vue DevTools调试

Vue DevTools是一个强大的调试工具,可以帮助你实时查看组件结构、响应式数据变化以及性能问题。合理使用DevTools可以大大提高开发效率和代码质量。