computed 和 watch 有什么区别?一般你都在什么地方使用?
时间: 2023-12-11 10:02:37 浏览: 94
`computed` 和 `watch` 都是 Vue.js 中用于响应式数据的处理方式,但它们的应用场景是不同的:
- `computed` 是计算属性,它会根据依赖的数据自动计算出一个新的值,并且缓存这个值,只有当依赖的数据变化时才重新计算;
- `watch` 监听一个特定的数据,当这个数据变化时执行一些操作,可以用来响应数据的变化并执行异步或开销较大的操作。
一般来说,当需要根据数据的变化计算出一个新的值时,使用 `computed`;当需要在数据变化时执行一些操作时,使用 `watch`。
在实际开发中,`computed` 通常用于模板中需要多次使用计算结果的情况,而 `watch` 通常用于监听某个数据的变化并执行一些操作的情况,例如网络请求或其他异步操作。
相关问题
要求用到技术1:Vue数据绑定 + [methods,computed,watch,filters,Vue事件] 技术2:Vue组件 技术3:Vue路由
好的,那就让我们来一步步实现一个简单的Vue小作品吧。我们可以实现一个简单的待办事项应用,用户可以添加待办事项、标记已完成的事项、删除待办事项等功能。这个应用将会用到Vue数据绑定、组件、路由等技术。我们先来安装Vue和Vue CLI。
1. 安装Vue和Vue CLI
首先,你需要在本地安装Node.js和npm。然后,在命令行中运行以下命令安装Vue CLI:
```
npm install -g @vue/cli
```
安装完成后,你可以在命令行中运行以下命令创建一个新的Vue项目:
```
vue create my-todo-app
```
根据提示选择你需要的配置,Vue CLI 将会自动生成一个基础的 Vue 项目。
2. 创建一个待办事项组件
接下来,我们要创建一个待办事项组件。在项目根目录下的 `src/components` 中创建一个新的文件 `TodoItem.vue`。在这个文件中,我们将创建一个单个待办事项的组件。
```html
<template>
<div class="todo-item">
<input type="checkbox" v-model="todo.completed" @change="toggleCompleted">
<span :class="{ 'completed': todo.completed }">{{ todo.text }}</span>
<button @click="$emit('remove')">删除</button>
</div>
</template>
<script>
export default {
props: ['todo'],
methods: {
toggleCompleted() {
this.$emit('toggle', this.todo.id);
}
}
}
</script>
<style>
.completed {
text-decoration: line-through;
}
</style>
```
在这个组件中,我们有一个单选框来标记待办事项是否已经完成,如果待办事项已经完成,它的文本将会有删除线。我们还有一个删除按钮来删除待办事项。
3. 创建一个待办事项列表组件
接下来,我们要创建一个待办事项列表组件,它将会用来显示所有的待办事项。在项目根目录下的 `src/components` 中创建一个新的文件 `TodoList.vue`:
```html
<template>
<div class="todo-list">
<div v-for="todo in filteredTodos" :key="todo.id">
<TodoItem :todo="todo" @toggle="toggleTodo" @remove="removeTodo"></TodoItem>
</div>
</div>
</template>
<script>
import TodoItem from './TodoItem.vue';
export default {
components: {
TodoItem
},
props: ['todos'],
computed: {
filteredTodos() {
return this.todos.filter(todo => {
return !this.showCompleted || todo.completed === false;
});
}
},
data() {
return {
showCompleted: false
};
},
methods: {
toggleTodo(id) {
const todo = this.todos.find(todo => todo.id === id);
todo.completed = !todo.completed;
},
removeTodo() {
this.$emit('remove');
}
}
}
</script>
<style>
.todo-list {
margin-top: 20px;
}
</style>
```
在这个组件中,我们使用了 `v-for` 指令来循环渲染每一个待办事项。我们还引入了之前创建的待办事项组件 `TodoItem`。我们还有一个切换已完成待办事项的开关。
4. 创建一个添加待办事项的组件
现在,我们要创建一个添加待办事项的组件。在项目根目录下的 `src/components` 中创建一个新的文件 `AddTodo.vue`:
```html
<template>
<div class="add-todo">
<input type="text" v-model="newTodo" placeholder="添加新的待办事项">
<button @click="addTodo">添加</button>
</div>
</template>
<script>
export default {
data() {
return {
newTodo: ''
};
},
methods: {
addTodo() {
if (this.newTodo) {
this.$emit('add', this.newTodo);
this.newTodo = '';
}
}
}
}
</script>
<style>
.add-todo {
margin-top: 20px;
}
</style>
```
在这个组件中,我们有一个文本输入框和一个添加按钮。当用户点击添加按钮时,我们将会触发一个事件来添加新的待办事项。
5. 创建一个根组件
最后,我们要创建一个根组件,它将会包含所有的子组件,并且处理待办事项的数据和状态。在项目根目录下的 `src` 中创建一个新的文件 `App.vue`:
```html
<template>
<div class="app">
<h1>待办事项</h1>
<AddTodo @add="addTodo"></AddTodo>
<div v-if="todos.length">
<TodoList :todos="todos" @remove="removeTodo"></TodoList>
<div>
<label>
<input type="checkbox" v-model="showCompleted">
显示已完成
</label>
</div>
</div>
<div v-else>
没有待办事项
</div>
</div>
</template>
<script>
import TodoList from './components/TodoList.vue';
import AddTodo from './components/AddTodo.vue';
export default {
components: {
TodoList,
AddTodo
},
data() {
return {
todos: [],
showCompleted: false,
nextId: 1
};
},
methods: {
addTodo:text=> {
this.todos.push({
id: this.nextId++,
text,
completed: false
});
},
removeTodo() {
this.todos = this.todos.filter(todo => !todo.completed);
}
}
}
</script>
<style>
.app {
max-width: 600px;
margin: 0 auto;
padding: 20px;
font-family: 'Arial';
}
</style>
```
在这个组件中,我们引入了之前创建的添加待办事项组件和待办事项列表组件。我们还有一个 `data` 对象来存储待办事项的数据和状态。我们还有一些方法来添加、删除和切换待办事项的状态。
6. 添加路由
最后,我们要添加路由来让用户能够访问我们的待办事项应用。在项目根目录下的 `src` 中创建一个新的文件 `router.js`:
```js
import Vue from 'vue';
import VueRouter from 'vue-router';
import App from './App.vue';
Vue.use(VueRouter);
const routes = [
{
path: '/',
name: 'home',
component: App
}
];
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
});
export default router;
```
在这个文件中,我们首先引入了 Vue 和 Vue Router,并使用 Vue.use 注册 Vue Router。我们还定义了一个路由对象,它将会指向我们的根组件。最后,我们创建了一个 VueRouter 实例,并把路由对象传递进去。
7. 启动应用
到这里,我们的待办事项应用已经完成了。现在,我们可以在命令行中运行以下命令启动应用:
```
npm run serve
```
应用将会运行在 http://localhost:8080 上,你现在可以在浏览器中访问它了。如果你想要构建一个生产环境的应用,可以运行以下命令:
```
npm run build
```
这个命令将会生成一个可以部署的静态文件,你可以将它部署到任何能够托管静态文件的地方。
以上是一个简单的待办事项应用的实现过程,它涉及到了 Vue 数据绑定、组件、路由等技术。当然,这只是一个简单的例子,你可以根据自己的需要添加更多的功能和交互效果。
vue3 什么时候出发computed
Vue 3 中的 `Computed` 属性会在以下几个情况下自动更新:
1. 当依赖的数据改变时:如果 `Computed` 计算属性的计算表达式依赖于 `watch` 对象、响应式数据或函数返回的结果,只要这些基础数据发生变化,`Computed` 就会重新计算。
2. 当组件实例被重新渲染时:无论是通过数据变化触发的视图更新,还是组件自身的销毁重建,都会导致 `Computed` 的重新计算。
3. 调用 `this.$set()` 或者手动修改响应式数据的底层值时:虽然直接操作 `data` 的普通属性不会触发 `Computed` 的更新,但如果使用 `$set` 来更改响应式路径,或者影响到计算属性的基础数据结构,则会引发 `Computed` 更新。
4. 如果 `Computed` 的返回值是一个异步操作,那么当异步操作完成并改变了结果,`Computed` 也会重新计算。
需要注意的是,只有在 `get` 方法中对响应式数据进行了读取或计算的地方,才会监视到这些变更,而 `set` 方法本身并不自动更新 `Computed`,除非你在 `set` 的处理逻辑中实现了需要。
阅读全文