GithubHelp home page GithubHelp logo

[feature request] 组件隔代递归 about san HOT 5 CLOSED

baidu avatar baidu commented on May 2, 2024
[feature request] 组件隔代递归

from san.

Comments (5)

errorrik avatar errorrik commented on May 2, 2024

我觉得这个还是组件抽象的问题,绝大多数场景下,我们是可以有更好的抽象的。上面的场景,jsonnode和leaf、branch就不是一个层面的抽象。

就算你想达到这样的效果,san也没有办法增加任何feature来支持这一点。增加什么来支持呢?反正我是没想到。

但是,在现有san的功能下,依然是可以做到的,而且不止一种方法。

我们假设有个JSON视图功能,包含以下组件:JSONView、StringView、NumberView、ArrayView、ObjectView、BoolView、NullView。

方法1

如果这些组件都是从san.Component直接继承来的,他们之间没有继承关系,那components属性的设置可以走plain object。因为san的组件初始化的时候,发现components中的某项不是class(function),而是object时,会用它来defineComponent。

方法2

san的组件属性支持prototype property,也支持static property。所以,components的声明可以统一做。

JSONView.components = {
  'view-string': StringView
  // ......
};

ObjectView.components = {
  'view-string': StringView
  // ......
};

// ...

from san.

errorrik avatar errorrik commented on May 2, 2024

i prefer 2

from san.

Dafrok avatar Dafrok commented on May 2, 2024

其实这个方式我也考虑过,但是会产生一个问题,就是必须严格要求声明顺序,这个做法在 .san 组件中的体验是非常糟糕的,这么说主要出于两点原因:

  1. san-loader 输出的 .san 组件是通过 san.defineComponent 包装过的,如果要实现这个目的,首先要把 san-loader 的输出变为 plain object,并且我也尝试过这么做了。但这样一来就会导致在非 san 组件中使用 .san component 的时候需要手动 define component,比如在 san-router 中注册组件,或手动 attach 的时候就需要多做这一步,如果路由表较为复杂,维护起来显然有些麻烦。

  2. 使用 san-loader 打包 .san 组件时,如果依赖不变,那么声明组件的过程是依次且固定的,也就是说,没办法在独立的组件中声明自己依赖的组件,必须在最后声明的组件中给其它依赖项的 components 属性赋值,于是产生了一些不必要的耦合,无形增加了维护成本。

至于解决方案我也想了两种:

  1. 在 san-loader 上开刀,san-loader 输出 plain object ,编译阶段砍掉所有组件的 components 属性并放到文件末尾统一声明。这个做法有两个隐患:一是依赖关系变得复杂,webpack 打包时没办法把各个组件拆成 chunk 异步加载(或者说没有意义)了,二是牺牲了非 .san 组件环境的开发体验,需要手动 defineComponent。

  2. 把生成组件使用的 plain object 的引用保存在 san.defineComponent 返回值的某个属性里。当 san 探测到循环依赖的时候,去拿到这个 plain object 并重新 define 一个一模一样的新组件,愚以为这个方法看起来是没什么副作用的。

from san.

Dafrok avatar Dafrok commented on May 2, 2024

回过头来想了想,太过拘泥于 .san component 的开发体验了,事实上没必要,该内聚的事情就内聚去做并没有问题。

虽然能增强 .san 的开发体验也是极好的,不过这个事儿似乎应该由 san-loader 去完成,这里先 close 掉了。

from san.

Sheetaa avatar Sheetaa commented on May 2, 2024

目前在做 DSL 的解析渲染也遇到了类似的组件循环引用不能正常渲染的问题。个人认为循环引用是需要框架兼容的一种情况。这样可以做更好的代码拆分和组织。如果都放在一个组件里,是可以避免循环引用,顶多只需要引用自身(San 里使用self解决),但是这样会导致组件内部逻辑复杂,可读性和可维护性差。

参考上面的解决方案,目前使用起来还是比较复杂。是否可以参考 Vue 的解决方案

  1. 全局注册组件(考虑到组件的独立性,San 没有提供全局组件注册的方法,忽略)
  2. 在生命周期钩子beforeCreate里注册组件
  3. 异步import组件
    • San 中提供了类似的方法createComponentLoader,不过在实践时候循环引用内部组件无法渲染
    • 个人认为这种方法也不合理,浏览器可以渲染但是 ssr 无法渲染。ssr 还是要能够渲染出来的,而不是不渲染

from san.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.