我有一些关于 Sapper/Svelte 的问题

Jus*_*tin 4 javascript frameworks node.js svelte angular

我第一次开始使用 Sapper ( https://sapper.svelte.technology )。到目前为止我真的很喜欢它。我需要它做的一件事是显示我的应用程序中可用组件的列表并显示有关它们的信息。理想情况下,有一种方法可以根据页面上的动态绑定来更改组件的外观。

我有一些关于使用该框架的问题。

首先,我将提供我的代码片段,然后是屏幕截图:

[slug].html
-----------

<:Head>
<title>{{info.title}}</title>
</:Head>

<Layout page="{{slug}}">
    <h1>{{info.title}}</h1>

    <div class="content">
         <TopBar :organization_name />
    <br>
    <h3>Attributes</h3>
    {{#each Object.keys(info.attributes) as attribute}}
    <p>{{info.attributes[attribute].description}} <input type="text" on:keyup="updateComponent(this.value)" value="Org Name" /></p>
    {{/each}}
    </div>
</Layout>

<script>
import Layout from '../_components/components/Layout.html';
import TopBar from '../../_components/header/TopBar.html';

let COMPONENTS = require('../_config/components.json');

export default {
    components: {
        Layout, TopBar
    },

      methods: {
          updateComponent(value) {
            this.set({organization_name: value});
          }
      },

  data() {
      return {
        organization_name: 'Org Name'
      }
  },

  preload({ params, query }) {

    params['info'] = COMPONENTS.components[params.slug];

    return params;
  }

};
</script>
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

现在我的问题:

  1. 我注意到我无法#each通过我的对象。我必须遍历它的键。如果我能做这样的事情就好了:

    {{#each info.attributes 作为属性 }}

    {{attribute.description}}

    {{/每个}}

  2. 在 Sapper 之前,我会使用 Angular-translate 模块,该模块可以根据给定的 JSON 文件对字符串进行翻译。有谁知道是否存在 Sapper/Svelte 等价物,或者我可能需要自己想出什么?

  3. 我不习惯做进口。我更习惯于 Angular 中的依赖注入,它看起来更干净(没有路径)。有什么方法可以创建一个COMPONENTS可以在我的文件中使用的常量,或者我是否需要在每次需要访问其数据的情况下导入一个 JSON 文件?

  4. 作为#3 的后续行动,我想知道是否有一种方法可以更好地包含文件,而不必依赖于../..浏览我的文件夹结构?如果我要更改我的一个文件的路径,我的终端会抱怨并给出错误,这很好,但是,我想知道是否有更好的方法来导入我的文件。

  5. 我知道必须有更好的方法来实现我在示例中实现的内容。基本上,您会在属性旁边看到一个输入框,如果我在那里进行更改,我将调用一个updateComponent函数,该函数然后this.set()在当前范围内执行 a以覆盖绑定。这有效,但我想知道是否有某种方法可以避免该功能。我认为您可以绑定输入的值并让它自动更新我的<TopBar>组件绑定......也许吧?

  6. preload方法使我可以访问params. 我想知道是否有某种方法可以在params.slug没有预加载功能的情况下访问。

真正酷的是让一些专家以最好的方式重写我所做的事情,可能会解决我的一些问题。

Ric*_*ris 8

  1. Svelte 只会迭代类似数组的对象,因为无法保证与对象的行为一致——它会抛出各种最好在应用程序级别解决的边缘情况。你可以做这样的事情,只需要使用标准的 JavaScript 习惯用法:
{{#each Object.values(info.attributes) as attr}}
  <p>{{attr.description}} ...</p>
{{/each}}

<!-- or, if you need the key as well -->
{{#each Object.entries(info.attributes) as [key, value]}}
  <p>{{attr.description}} ...</p>
{{/each}}
Run Code Online (Sandbox Code Playgroud)
  1. 不知道直接的 angular-translate 等价物,但一个简单的 i18n 解决方案是在 中获取一些 JSON preload
preload({ params, query }) {
  return fetch(`/i18n/${locale}.json`)
    .then(r => r.json())
    .then(dict => {
      return { dict };
    });
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以参考{{dict["hello"]}}模板中的内容。更复杂的解决方案只会加载当前页面所需的字符串,并缓存所有内容等,但基本思想是相同的。

  1. 我想你可以这样做:
// app/client.js (assuming Sapper >= 0.7)
import COMPONENTS from './config/components.json';
window.COMPONENTS = COMPONENTS;

// app/server.js
import COMPONENTS from './config/components.json';
global.COMPONENTS = COMPONENTS;
Run Code Online (Sandbox Code Playgroud)

不过进口没那么糟糕!模块的依赖关系是显式的。

  1. 您可以resolve.modules在 webpack 配置中使用该字段:https ://webpack.js.org/configuration/resolve/#resolve-modules

  2. 这将是使用双向绑定的好地方:

{{#each Object.values(info.attributes) as attr}}
  <p>{{attr.description}} <input bind:value=organization_name /></p>
{{/each}}
Run Code Online (Sandbox Code Playgroud)
  1. params是的,该对象始终在您的页面中可用(不是嵌套组件,除非您向下传递 prop,而是所有顶级组件,例如routes/whatever/[slug].html)——因此您可以在模板中将其引用为{{params.slug}},或在生命周期钩子和方法中引用为this.get('params').slug,无论是或者给定的组件是否使用preload.

  • Stack Overflow 是解决此类问题的合适场所 - 我们更愿意让问题跟踪器专注于错误和功能讨论 (2认同)