最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • Vesselize - 一个可以与 Vue.js 及 React 无缝集成的 JavaScript IoC 容器

    正文概述 掘金(felixpy)   2020-11-30   419

    笔者目前是一个 Vue.js 和 React 都在用的前端打工人,像 Vue Composition API 和 React Hooks 这些技术真的是拯救人生啊,感觉前端的开发体验越来越像丝绸般顺滑。

    另一方面呢,由于目前的项目里面有着非常复杂的数据处理逻辑,所以我们封装了很多可复用的 Service 类。但是有一点不太方便的是,必须在业务组件或者 Service 里面手动创建它们所依赖的 Service 实例。受 Angular、Nest 以及 Spring 这些框架的启发,开始尝试在 Vue.js 和 React 应用中通过依赖注入的方式解决这个问题。

    Vesselize (文档:vesselize.js.org)就是笔者最近业余时间写的一个 JavaScript IoC 容器,目前已经在项目中正式使用。可以直接在 Vue.js 或 React 应用中,直接通过类似 useInstance('ServiceName') 的 API 来解决对服务实例的依赖。这次造轮子的过程中学到了不少新知识,分享出来希望对大家有所帮助。

    下面的内容是它的基本概念级入门指南。

    Vesselize 核心概念

    Providers

    Provider 通常是可以被实例化的 JavaScript 构造器函数,此外也可以是任意的工厂方法及已经声明好的值。它们会被注册到容器里面,用于依赖注入及查找。

    Container

    Container 的职责是用于初始化实例并解决他们的依赖关系。

    Context

    默认情况下,容器创建的实例都是单例的。通过指定一个 Context 对象,我们可以创建一个跟该上下文绑定的实例。

    Vue.js 应用集成 Vesselize 入门指南

    下面我们通过代码的形式展示如何在 Vue.js 应用中集成 Vesselize。

    安装

    yarn add @vesselize/vue
    # OR
    npm i @vesselize/vue
    

    创建 Providers

    假设应用中需要以下三个服务:

    • UserAPI 用于请求接口数据
    • UserService 调用 UserAPI 获取数据并进行业务逻辑的处理
    • AuthService 用于判断用户的角色,比如是否为管理员
    // file: api/UserAPI.js
    class UserAPI {
      async fetchUser(id) {
        return fetch(`/path/to/user/${id}`).then(res => res.json());
      }
    }
    
    // file: services/UserService.js
    class UserService {
      userAPI = null;
    
      async getUser(id) {
        const user = await this.userAPI.fetchUser(id);
    		
        // 数据处理逻辑...
    		
        return user;
      }
    	
    	// 通过 Vesselize 容器注入 userAPI 实例
      setVesselize(vesselize) {
        this.userAPI = vesselize.get('UserAPI');
      }
    }
    
    // file: services/AuthService.js
    class AuthService {
      constructor(maxAdminUserId) {
        this.maxAdminUserId = maxAdminUserId;
      }
    
      isAdmin(user) {
        return user.id <= this.maxAdminUserId;
      }
    }
    

    创建 VueVesselize 插件

    下面的代码通过 createVesselize 方法创建 Vue.js 插件,同时它也是一个容器实例。

    import { createVesselize } from '@vesselize/vue';
    import UserAPI from './api/UserAPI';
    import UserService from './services/UserService';
    import RoleAuthService from './services/RoleAuthService';
    
    const vesselize = createVesselize({
      providers: [
        {
          token: 'UserAPI',
          useClass: UserAPI
        },
        {
          token: 'UserService',
          useClass: UserService
        },
        {
          token: 'AuthService',
          useFactory() {
            const maxAdminUserId = 1;
    
            return new AuthService(maxAdminUserId);
          }
        }
      ]
    });
    

    注册 VueVesselize 插件

    import { createApp } from 'vue';
    import router from './router';
    import store from './store';
    import vesselize from './vesselize';
    import App from './App.vue';
    
    const app = createApp(App)
      .use(store)
      .use(router)
      .use(vesselize);
    
    app.mount('#app');
    

    在组件中获取服务实例

    通过 useInstance 这个 Composition API,我们可以在组件中很方便地获取组件实例。

    <template>
      <div>Profile</div>
      <p>{{ JSON.stringify(user) }}</p>
      <p>Role: {{ isAdmin ? 'Administrator' : 'User' }}</p>
    </template>
    
    <script>
    import { computed, ref, watchEffect } from 'vue';
    import { useRoute } from 'vue-router';
    import { useInstance } from '@vesselize/vue';
    
    export default {
      setup() {
        const route = useRoute();
        const userId = computed(() => route.params.id);
        const user = ref({});
        const isAdmin = ref(false);
        // 通过 Vue Composition API 获取组件实例
        const userService = useInstance('UserService');
        const authService = useInstance('AuthService');
    
        watchEffect(() => {
          if (userId.value) {
            userService.getUser(userId.value).then((data) => {
              user.value = data;
              isAdmin.value = authService.isAdmin(data);
            });
          }
        });
    
        return {
          user,
          isAdmin,
        };
      },
    };
    </script>
    

    最后,如果你想直接在项目中尝试,可以看一下这个示例项目:vesselize-vue-starter.

    React 应用集成 Vesselize 入门指南

    还是上面的例子,我们看一下如何在 React 中实现。

    安装

    yarn add @vesselize/react
    # OR
    npm i @vesselize/react
    

    创建 Providers

    与上面一样也是需要 UserAPI, UserService, AuthService 三个服务。

    组合 Providers

    我们先将所有的 Provider 组合为一个数组:

    import UserAPI from './api/UserAPI';
    import UserService from './services/UserService';
    import RoleAuthService from './services/RoleAuthService';
    
    const providers = [
      {
        token: 'UserAPI',
        useClass: UserAPI
      },
      {
        token: 'UserService',
        useClass: UserService
      },
      {
        token: 'AuthService',
        useFactory() {
          const maxAdminUserId = 1;
    
          return new AuthService(maxAdminUserId);
        }
      }
    ];
    
    export default providers;
    

    添加组件 VesselizeProvider

    通过 Vesselize 提供的 VesselizeProvider 来包裹项目的 App 组件,同时传入组合好的所有 Provider。

    import { VesselizeProvider } from '@vesselize/react';
    import providers from './providers';
    import UserProfile from './components/UserProfile';
    
    function App() {
      return (
        <VesselizeProvider providers={providers}>
          <UserProfile />
        </VesselizeProvider>
      );
    }
    
    export default App;
    

    在组件中获取服务实例

    通过 useInstance 这个 hook, 可以非常便捷地获取到服务实例。

    import { useParams }  from 'react-router-dom'
    import { useState, useEffect } from 'react';
    import { useInstance } from '@vesselize/react';
    
    function UserProfile() {
      const { id } = useParams();
      const [user, setUser] = useState({});
      const [isAdmin, setIsAdmin] = useState(false);
      // 通过 hook 获取组件实例
      const userService = useInstance('UserService');
      const authService = useInstance('AuthService');
    
      useEffect(() => {
        userService.getUser(id).then((data) => {
          setUser(data);
          setIsAdmin(authService.isAdmin(data));
        });
      }, [id, userService, authService]);
    
      return (
        <div>
          <span>{JSON.stringify(user)}</span>
          <p>Role: {isAdmin ? 'Administrator' : 'User'}</p>
        </div>
      );
    }
    
    export default UserProfile;
    

    最后,如果你想直接在项目中尝试,可以看一下这个通过 create-react-app 创建的示例项目: vesselize-react-starter.

    写在最后

    在创造 Vesselize 的过程中,我学习到了很多东西。本文将它分享出来,也希望对你有所帮助。

    感谢你的阅读,祝你生活愉快!

    附录

    Github 代码仓库: github.com/vesselize

    文档及使用指南: vesselize.js.org

    项目示例:

    • vesselize-vue-starter
    • vesselize-react-starter

    起源地下载网 » Vesselize - 一个可以与 Vue.js 及 React 无缝集成的 JavaScript IoC 容器

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元