Composition API + <script setup> 多用好用!

40 阅读1分钟

使用 <script setup> 可以让代码变得更加精简,这也是现在开发 Vue 3 项目必备的写法。

Composition API

src/ components /Todolist.vue

<template>
<div>
<h2 @click="add">{{count}}</h2>
</div>
</template>

<script setup>
import { ref } from "vue";
let count = ref(1)
function add(){
count.value++
}
</script>
<style>
h2 {
color: red;
}
</style>

这样使用

<template>
<h1>这是首页</h1>
<TodoList />
</template>
<script setup>
import TodoList from '../components/TodoList.vue'
</script>

更新 Todolist

<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:'学习Vue3',done:false}])
function addTodo() {
todos.value.push({
title: title.value,
done: false,
});
title.value = "";
}
</script>

计算属性

可以写单独每一个的计算属性


<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>

Composition API 拆分代码

将功能相关的数据和方法放在一起 新建 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 }
}

使用时

<script setup>
import { ref, computed } from "vue";
let count = ref(1)
function add(){
count.value++
}
let { title, todos, addTodo, clear, active, all, allDone } = useTodos();
</script>

比如获取鼠标位置 可以这样

import {ref} from 'vue'
export function useMouse(){
const x = ref(0)
const y = ref(0)
return {x, y}
}

添加onMounted生命周期

import {ref, onMounted,onUnmounted} from 'vue'
export function useMouse(){
const x = ref(0)
const y = ref(0)
function update(e) {
x.value = e.pageX
y.value = e.pageY
}
onMounted(() => {
window.addEventListener('mousemove', update)
})
onUnmounted(() => {
window.removeEventListener('mousemove', update)
})
return { x, y }
}

使用它

import {useMouse} from '../ /mouse'
let {x,y} = useMouse()