Vue3实战06-CompositionAPI+<script setup>好在哪?
Vue 3 的Composition API +
<script setup> 标签内定义的变量和函数,都可以在模板中直接使用。
### 1.2 显示清单应用
实现累加器后,回到src/pages/Home.vue 组件,使用如下代码显示清单应用。
直接import TodoList.vue组件,然后<script setup>会自动把组件注册到当前组件,这样我们就可以直接在template中使用 来显示清单的功能。
```vue
<template>
<h1>这是首页</h1>
<TodoList />
</template>
<script setup>
import TodoList from '../components/TodoList.vue'
</script>
这就把清单功能独立出来,可在任意需要的地方复用。
基于组件去搭建应用,可实现对业务逻辑的复用。如有其他页面也需要用到这功能,直接复用。
然后,就可基于新语法实现清单应用。
把之前的代码移植过来后,使用ref包裹的响应式数据。修改title和todos时,注意修改响应式数据的value属性。
<template>
<div>
<input type="text" v-model="title" @keydown.enter="addTodo" />
<ul v-if="todos.length">
<li v-for="todo in todos">
<input type="checkbox" v-model="todo.done" />
<span :class="{ done: todo.done }"> {{ todo.title }}</span>
</li>
</ul>
</div>
</template>
<script setup>
import { ref } from "vue";
let title = ref("");
let todos = ref([{title:'学习Vue',done:false}])
function addTodo() {
todos.value.push({
title: title.value,
done: false,
});
title.value = "";
}
</script>
2 计算属性
Composition API语法中,计算属性和生命周期等功能,都可脱离Vue的组件机制单独使用 。
向TodoList.vue加入:
<template>
<div>
<input type="text" v-model="title" @keydown.enter="addTodo"/>
<button v-if="active < all" @click="clear">清理</button>
<ul v-if="todos.length">
<li v-for="todo in todos">
<input type="checkbox" v-model="todo.done"/>
<span :class="{ done: todo.done }"> {{ todo.title }}</span>
</li>
</ul>
<div v-else>暂无数据</div>
<div>
全选<input type="checkbox" v-model="allDone"/>
<span> {{ active }} / {{ all }} </span>
</div>
</div>
</template>
<script setup>
import {ref, computed} from "vue";
let title = ref("");
let todos = ref([{title: '学习Vue', done: false}])
function addTodo() {
...
}
function clear() {
todos.value = todos.value.filter((v) => !v.done);
}
let active = computed(() => {
return todos.value.filter((v) => !v.done).length;
});
let all = computed(() => todos.value.length);
let allDone = computed({
get: function () {
return active.value === 0;
},
set: function (value) {
todos.value.forEach((todo) => {
todo.done = value;
});
},
});
</script>
具体的计算属性的逻辑和02讲一样,区别仅在computed用法。
02讲的computed是组件的一个配置项,而这的computed的用法是单独引入使用。
3 Composition API 拆分代码
之前的累加器和清单,虽功能简单,但也属于两个功能模块。如在一个页面有俩功能,就需在data和methods里分别配置。但如此,数据和方法相关的代码会写在一起,在组件代码行数多了后难维护。
所以,要使用Composition API 逻辑拆分代码,把一个功能相关的数据和方法维护在一起。
但所有功能代码都写在一起,也有问题:随功能复杂,script内部代码越来越多。因此,可进步对代码拆分,把功能独立的模块封装成一个独立函数,做到按需拆分。
新建函数 useTodos:
function useTodos() {
let title = ref("");
let todos = ref([{ title: "学习Vue", done: false }]);
function addTodo() {
todos.value.push({
title: title.value,
done: false,
});
title.value = "";
}
function clear() {
todos.value = todos.value.filter((v) => !v.done);
}
let active = computed(() => {
return todos.value.filter((v) => !v.done).length;
});
let all = computed(() => todos.value.length);
let allDone = computed({
get: function () {
return active.value === 0;
},
set: function (value) {
todos.value.forEach((todo) => {
todo.done = value;
});
},
});
return { title, todos, addTodo, clear, active, all, allDone };
}
就是把和清单相关的所有数据和方法,都放在函数内部定义并返回,这个函数就可放在任意地方维护。
而组件入口即