简图:

解释:

1.VUE文件只定义组件,以及模板中所须要的回调办法(例如@click等)。
2.useInit.js,只定义监听器、计算属性、生命周期等,相当于VUE2的watch、compute、mounted(等等)等,但用到的办法和依赖的均来源于useTools.js。
3.useTools.js,只定义依赖和办法,相当于VUE2的data、props、methods。
4.VUE文件从useInit.js中获取模板中用到的依赖。
5.useInit.js从useTools.js文件中获取初始化用到的办法和依赖,以及须要传递到VUE文件中的依赖。
6.返回办法和依赖。
7.返回依赖。

举例:

App.vue

<template>  <div    class="test"    :style="{      width: state.fatherWidth + 'vw',      background: state.fatherBgc,    }"  >    <button @click="changeBgc">变色</button>    <child></child>  </div></template><script setup>import Child from "./components/child.vue";import { defineComponent } from "vue";import useInit from "./utils/App/useInit";defineComponent({  Child,});let { state } = useInit();function changeBgc() {  state.fatherBgc = "lightblue";}</script><style scoped>.test {  height: 100vh;  overflow: hidden;}</style>

child.vue

<template>  <div class="test">    <button @click="updateWidth">变窄</button>  </div></template><script setup>import PubSub from "pubsub-js";function updateWidth() {  PubSub.publish("updateWidth")}</script><style scoped></style>

useInit.js

import PubSub from "pubsub-js";import useTools from "./useTools";import { onMounted, onUnmounted, watch } from "vue";export default function useInit() {    const {        init,        pubsubOptions,        state,    } = useTools();    watch(        () => state.fatherWidth,        val => {            if (val % 2 === 1) {                state.fatherBgc = "pink"            }        }    )    onMounted(() => {        init();    });    onUnmounted(() => {        for (let psevt in pubsubOptions) {            PubSub.unsubscribe(psevt);        }    });    return {        state    }}

useTools.js

import PubSub from "pubsub-js"import { reactive } from "vue";export default function useTools() {    const pubsubOptions = {        updateWidth: null,    }    const state = reactive({        fatherWidth: 100,        fatherBgc: 'yellowgreen'    })    function updateWidth() {        state.fatherWidth --        state.fatherBgc = 'lightblue';        if (state.fatherWidth <= 80) {            state.fatherWidth = 100            state.fatherBgc = 'yellowgreen'        }    }    return {        init: function() {            pubsubOptions.updateWidth = PubSub.subscribe("updateWidth", () => {                updateWidth()            })        },        pubsubOptions: pubsubOptions,        state: state,    };}

总结:

最后我的想法是延长optionAPI的写法,将data、props、components、watch、生命周期钩子等都写到vue组件中,而后将这些依赖以传递的形式传递到useInit等,然而一顿打磨之后发现传递其实能够有起点。比方useTools,把所有的data、methods、都定义到useTools中,而后再返回到内部。其实思路上就是一个正反的区别,然而向外传递的形式能让data和methods的关系更严密,也更直观。然而这两种办法都没有按功能模块进行拆分,简直是把所有的办法都堆到一起。最初再抛出一个问题,有些零碎的原型设计就曾经很大水平的既定了代码的设计,话中有话就是代码的耦合度等和零碎的设计有很大关系。在这种耦合度必然存在的状况下要怎么拆分功能模块,让代码更容易治理和保护。或者是否有更好的代码设计的思路或计划啊,搜索枯肠就是想不出啊~