Appearance
组合式 API (Composition Api)
Vue组件将组件和功能封装为按需重用的代码段,方便维护的同时,也增加了灵活性(个人理解是同一功能的差异部分可以切换不同组件或参数实现)。
但是,实际项目中,经常可以看到一个Vue组件动不动就几千行代码,还要小心地维持 options-api 的结构 ({ props, date, computed, methods, ... })。
组件相互间引用,一些重复的逻辑散落在各处,给维护带来了较大的难题。
需要尽量减少这种无序和重复、帮助我们共享或重用代码。
现在 可以 通过setup来使用 组合式 API (Composition Api) 以尝试让编码变得轻松一些
@/pages/40-lrn/20-vue3/10-composition-api/components/InvaluableAI.vue
vue
<template>
<div>{{ answer }}</div>
<input
v-model="question"
@keyup.enter="ask"
@dblclick="ask"
placeholder="ask sth..."
v-if="!loading"
autofocus
/>
</template>
<script lang="ts">
import { defineComponent } from "vue"
import { useInvaluableAI } from "./invaluable-ai"
export default defineComponent({
setup() { return { ...useInvaluableAI(), } }
})
</script>
@/pages/40-lrn/20-vue3/10-composition-api/components/invaluable-ai.ts
ts
// @ts-check
import { ref, reactive, computed, toRefs, nextTick } from "vue"
export function useInvaluableAI() {
const loading = ref(false);
const formState = reactive({
question: '',
answer: '',
});
const isResolvableQuestion = computed(() => /^(.*)([??=])$/.test(formState.question))
let resolveQuestion = (q: string) => q.replace(/^(.*)([??=])$/, ($, $1, $2) => {
if ($2 === '?') return $1 + '!';
if ($2 === '?') return $1 + '!';
if ($2 === '=') return '=' + $1;
return $;
});
let fetchAnswer = (q: string) : Promise<{ question: string, answer: string; }> => {
return new Promise((ok, ko) => {
setTimeout(() => {
if (isResolvableQuestion.value) {
return ok({ question: q, answer: resolveQuestion(q) });
} else {
return ko(new Error(`unknown`));
}
}, parseInt(String(Math.random() * 3000)));
});
};
let ask = async ($event) => {
loading.value = true;
let result = await (fetchAnswer(formState.question)).catch(err => {
return { question: formState.question, answer: `err: ${err.message}` };
});
formState.answer = result.answer;
nextTick(() => {
loading.value = false;
$event && $event.target && $event.target.tagName === 'INPUT' && $event.target.select();
});
}
const { question, answer, } = toRefs(formState);
return { question, answer, ask, loading };
}