关于Sapper/Svelte,我有一些问题。

4
我刚刚开始第一次使用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>

在此输入图片描述

现在我有一些问题:

  1. 我注意到我不能通过对象进行循环遍历。我必须遍历其键。如果我可以像这样做那就太好了:

    {{#each info.attributes as attribute }}

    {{attribute.description}}

    {{/each}}

  2. 在使用 Sapper 之前, 我会使用 Angular-translate 模块基于给定的 JSON 文件对字符串进行翻译,是否有 Sapper/Svelte 的相应模块,或者我需要自己解决?

  3. 我不习惯使用导入。我更习惯于在 Angular 中使用依赖注入,它看起来更加简洁(没有路径)。我是否可以创建一个可在文件中随处使用的 COMPONENTS 常量,还是每次需要访问其数据时都需要导入 JSON 文件?

  4. 作为 #3 的后续,我想知道是否有更好的方法来包含文件,而不必依赖于使用 ../.. 导航到我的文件夹结构中?如果我更改其中一个文件的路径,我的终端将发出错误,这很好,但我想知道是否有更好的方法来导入我的文件。

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

  6. preload 方法提供了对 params 的访问。我想知道是否有一种方法可以在不使用 preload 函数的情况下访问 params.slug

最棒的方法是让一些专家以最佳方式重写我已经完成的部分,可能解答了一些我的问题。

1个回答

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}}
  1. 我不知道是否存在一个与angular-translate直接等价的解决方案,但一个简单的国际化解决方案是在preload中获取一些JSON:
preload({ params, query }) {
  return fetch(`/i18n/${locale}.json`)
    .then(r => r.json())
    .then(dict => {
      return { dict };
    });
}

然后,你可以在模板中使用像{{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;

导入并不是那么糟糕!对于模块的依赖关系明确说明是有好处的。

  1. 您可以在webpack配置中使用resolve.modules字段: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}}
  1. 是的,params对象总是在您的页面中可用(不包括嵌套组件,除非您将prop传递下去,但所有顶级组件如routes/whatever/[slug].html) - 因此您可以在模板中引用它为{{params.slug}},或在生命周期钩子和方法中内部引用为this.get('params').slug,无论给定组件是否使用preload

非常感谢您的回答。您会推荐 https://github.com/sveltejs/svelte/issues 作为我未来任何问题的解决之地吗? - Justin
2
Stack Overflow是提出此类问题的正确场所——我们更倾向于让问题追踪器专注于漏洞和功能讨论。 - Rich Harris
你好,第六点还有效吗?出现了一个关于我的组件中未定义params的错误。 - roshnet
这不是问题。如果你想将参数作为$page.params访问,或者从preload函数中获取它们,请执行import { stores } from '@sapper/app'; const { page } = stores(); - Rich Harris

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接