在运行时分配/添加mixin或子组件?

时间:2018-04-18 07:53:05

标签: vue.js vuejs2 vue-component

我可以动态添加mixin吗?我想我读过不支持并且永远不会支持mixins的运行时插入。以下运行时插入是否可行?

我的用例是;我们所有的页面都存储在一个数据库中,每个页面的标准属性都像;标题,内容和模板。我们为每个模板都有组件。每个模板组件以不同方式显示标题和内容。所以我需要构建路由并说这个页面使用这个(模板)组件。也许我可以使用子组件来实现这一目标?我可以在运行时动态添加子组件吗?

最简单的解决方案是执行以下操作:

路由器:

// myPages retrieved by REST call
const routes = _.map(myPages, page => {
    return {
        path: `/${page.url}`,
        name: page.name,
        component: DefaultPage  // make all pages use DefaultPage component
    }
});

DefaultPage.vue

<template>

</template>

<script>
import mixins from './mixins';

export default {

  mixins: [mixins.Base]

  beforeMount() {
    // I dont think this is possible?
    let templateMixin = mixins[ this.page.template ]
    this.mixins.push( templateMixin );
  }

}
</script>

也许可以在运行时分配子组件?

<template>
    // Somehow call the sub-component (template)?
    <template></template>
</template>

<script>
import templates from './templates';

export default {

  components: {},

  beforeMount() {
    // Is this possible?

    let templateCmp = templates[ this.page.template ]
    this.components = {
      templateCmp
    }
  }

}
</script>

1 个答案:

答案 0 :(得分:0)

不幸的是,网络上有很多错误信息,称“由于用户空间风险,加载动态或“运行时”组件不安全或不安全”,并且这样做是“安全风险”。

这源于 Vue 在编译组件时使用 eval 语句的推理。然而,React 和 Angular 也是如此。事实上,没有这个就没有办法编译组件。虽然 eval 是一把锋利的刀,但任何 JavaScript 也是如此。说锋利的刀不安全是错误的,只要你能保证锋利的刀本身安全。

运行时组件不安全的观点是完全错误的。如果您控制源,则有大量官方支持的方法可以做到这一点。事实上,即使你控制源(!!)

,甚至还有一个官方支持的 Vue 支持的“userland”方法来加载动态/异步组件

异步组件

从数据库(它本身可能有自己的子组件、mixin 和依赖项)加载页面的最简单方法可能是使用 async components

这是 Vue 的官方部分,我已经在数十个生产应用程序中使用了它。它的工作原理完全符合预期;在满足所有条件之前,您的应用程序不会调用任何内容,并且当满足加载条件时,您可以随意获取您认为合适的组件。

注意:必须控制这些组件的来源,否则 XSS 注入和其他黑客攻击是可能的。

如果您使用 webpack,很容易将所有组件依赖项放入一个文件中。在上面的 URL 中是具体的操作方法文章,包括如何为不属于主应用程序的页面依赖项生成单个 js 文件的视频教程。

以这种方式加载多个子组件的一个警告是您可能会重叠/重复加载(即页面 ​​A 可能加载 5 个没有其他静态页面加载的子组件,而页面 B 可能加载 5 个子组件,其中 3 个与A 页,其中 2 个特定于 B 页)。如果您不仔细考虑,像这样的警告可能会弄乱您的优化技术。这可能是不可避免的并且很好,但仍然比一次加载整个应用程序要快得多。

用户空间中的异步组件

如果您只想从数据库加载自定义模板(即,如果您不想让用户加载他们自己的自定义组件、mixin、过滤器、指令等),那么您很幸运; Vue 甚至官方支持异步模板,这些模板被锁定为只允许模板更改。这足以为您的组件构建者提供用于创建应用程序的脚手架,但会阻止他们执行任意 JavaScript 代码(例如,此方法不会让他们设置数据部分或挂钩组件生命周期)。

v-runtime-template 被 Vue.js 团队正式认可为创建用户空间安全的 Vue 模板的官方方法。

我已经在行业内一些知名人士使用的平台中使用了 v-runtime-template,这些平台有数千万用户,没有发生过一次安全漏洞,因为这种方法只暴露您认为没问题的组件。

>

使用 JSON 模式进一步锁定模板

如果您只需要生成表单,或者您可以进一步简化您的组件,并且您只需要以查询等简单方式推理数据(即,如果您正在构建调查生成器、分析或其他小部件仪表板) ,您可以使用 vue-form-json-schema 从 JSON 模式构建组件。此方法采用 2 种模式:一种用于您的数据,一种用于您的表单。您加载的父组件指定架构可访问的所有组件,因此您必须将用户可以访问的组件列入白名单,此外,表单不能运行任意 JavaScript,它们只能调用您在父组件中提供的函数,哪些是您的 JavaScript 白名单。

对任意数据的用户安全查询

您可以让用户查询特定的 JSON 对象,以用于完全安全的用户空间查询,公众可以使用 JSONata 提供这些查询。 JSONata 由 IBM 开发,是一种安全查询方式,通过公开一些功能,您的用户甚至可以以经过验证的安全方式操作数据。

虽然 JSONata 在逻辑上被证明在 unserland 中是安全的,但它也是没有函数的图灵完备,这意味着您的用户可以通过输出技术上可以做任何事情的新数据来操作 Schema 提供的数据;即您的用户可以使用 JSONata 查询创建 Doom 3。人们已经用 JSONata 制作了像 Pong 这样的游戏和其他有趣的东西。

JSONata 的力量不容小觑。它为几乎所有无代码/低代码平台(如开源 Node-RED)背后的魔力提供了动力,并且是许多其他封闭源代码的专有无代码/低代码平台的背后,包括谷歌、微软、亚马逊和 IBM 平台。

他们使用 JSONata 在平台之间转换数据模式,并且在数据操作上需要业务逻辑时,操作必须留在用户空间(即需要操作数据的应用程序,但您想运行该应用程序在您的平台上,而不必担心 QA 或人们能够破解或编写恶意应用程序来入侵您的平台)。