先来看一段vue2代码(选项式 API )
new Vue({
data() {
return {
arr: [],
obj: {},
}
},
methods: {
handleArr() { },
handleObj() { }
},
computed: {
getArr: () => { },
getObj: () => { }
}
})
缺点:与 arr 相关的代码分散在不同的配置项中,并没有集中起来,不方便写代码:你往往需在不同配置项中跳转。例如:添加一个数据要去data中,添加对应的操作方法要在methods中.....。
在vue3,我们可以这样写(组合式 API)
const getArr = function () {
const arr = reactive({})
const arrComputed = computed(() => { })
const handleArr = () => { }
return { arr, arrComputed, handleArr }
}
const getObj = function () {
const obj = reactive({})
const objComputed = computed(() => { })
const handleObj = () => { }
return { obj, objComputed, handleObj }
}
const App = {
setup(props, context) {
const { arr, arrComputed, handleArr } = getArr();
const { obj, objComputed, handleObj } = getObj();
return {
arr, arrComputed, handleArr,
obj, objComputed, handleObj
}
}
}
const app = createApp(App)
app.mount("#app");
它的典型特点是,可以把业务相关的代码在放在同一个位置来写。将同一个逻辑关注点相关代码收集在一起会更好阅读和维护。
放一个完整的例子
<template>
<div id="app">
<div>{{obj.name}}</div>
<div>{{num}}</div>
<div @click="add" class="btn">小李</div>
<div @click="subtract" class="btn">小网</div>
</div>
</template>
<script>
const {
createApp,
ref,
reactive,
toRefs,
watch,
} = Vue;
const subtractFun = function (state) {
const subtract = () => {
state.obj.name = "小网";
state.num--;
};
return {
subtract
}
}
const addFun = function (state) {
const add = () => {
state.obj.name = "小李";
state.num++;
};
return {
add
}
}
const App = {
setup(props, context) {
const state = reactive({
obj: { name: "小白" },
num: 0,
});
//逻辑一
const { add } = addFun(state);
//逻辑二
const { subtract } = subtractFun(state);
watch(state, () => {
console.log("发生了变化", state.num);
})
return {
...toRefs(state), //为什么这里要用toRefs,因为使用展开运算符把state内部的值全部拆开放在返回中,那么这些值就不在是响应式数据了!!!
subtract,
add,
};
},
},
};
const app = createApp(App)
app.mount("#app");
</script>