【问题标题】:Clean separation of view and code with Vue using templates使用 Vue 模板清晰地分离视图和代码
【发布时间】:2017-11-01 10:42:38
【问题描述】:

我希望这对某人来说是一个微不足道的问题,我只是错过了一小段神奇的代码:我正在从 knockout.js 迁移到 vue.js,我想知道是否有一种简单的方法来使用相同的模板vue.jsknockout.js 一样。以下代码片段使用knockout.js 并按预期工作:

function viewmodel() {
    this.person = ko.observable(new person());
}
function person() {
    this.first = ko.observable('hello');
    this.last = ko.observable('world');
}
ko.applyBindings(new viewmodel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<script type="text/html" id="person-template">
    <p data-bind="text: first"/>
    <p data-bind="text: last"/>
</script>
<div>
    <div data-bind="template: { name: 'person-template', data: person }"/>
</div>

但是,我不知道如何在vue.js 中实现相同的目标。我知道vue.js 中的组件以及所有这些,但我想保持结构不变,而不是将更多特定于视图的代码放入我的 JavaScript 文件中。 (我已经对el: '#app' 不满意,但这是我目前最不关心的问题)当然这段代码不起作用:

var app = new Vue({
    el: '#app',
    data: {
        person: {
            first: 'hello',
            last: 'world'
        }
    }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.3/vue.js"></script>

<script type="text/x-template" id="person-template">
    <p v-text="first"/>
    <p v-text="last"/>
</script>
<div id="app">
    <div><!-- how? is this even possible? --></div>
</div>

有没有办法只通过更改代码的 HTML 部分来实现此功能?最好只有 &lt;div&gt;-Element。

【问题讨论】:

    标签: javascript mvvm knockout.js vue.js


    【解决方案1】:

    因此,这并不是更改模板,而是可以在此处使用单个附加属性。在 Vue 中指定模板。

    var app = new Vue({
        el: '#app',
        template: "#person-template",
        data: {
            person: {
                first: 'hello',
                last: 'world'
            }
        }
    });
    

    我还稍微修改了您的模板,因为任何 Vue 或组件的模板都需要一个根元素。我建议您在 Vue 中 not 使用自闭合标签,因为我已经看到这会导致问题。 Vue 需要有效的 HTML5 和 self closing tags are not valid HTML5

    <script type="text/x-template" id="person-template">
      <div>
        <p v-text="person.first"></p>
        <p v-text="person.last"></p>
      </div>
    </script>
    

    工作example

    此外,以这种方式指定模板的一种非常常见的方法是使用 HTML5 template element,而不使用那种 hacky script 标签。

    <template id="person-template">
      <div>
        <p v-text="person.first"></p>
        <p v-text="person.last"></p>
      </div>
    </template>
    

    最后,知道您对 el:"#app" 有点不满意,您可以el 属性从 Vue 定义中移除,并使用 $mount 将 Vue 安装在您选择的元素上方法。因此,如果您想完全专注于关注点分离,您可以这样做。

    const renderer = Vue.compile(document.querySelector("#person-template").innerHTML)
    const example = {
        data: {
            person: {
                first: 'hello',
                last: 'world'
            }
        }
    }
    const app = new Vue(Object.assign({}, example, renderer))
    app.$mount("#app")
    

    Example.

    我应该提到没有人真正这样做(手动编译他们的模板,使用 $mount 很常见),我知道。它还取决于使用包含编译器的 Vue 版本(例如,如果您使用 webpack 或其他一些构建工具,则可能没有)。你也可以这样做:

    const app = new Vue(Object.assign({}, example, {template: "#person-template"}))
    app.$mount("#app")
    

    这基本上允许您指定模板、组件和安装它的位置all separately

    【讨论】:

    • @NumLock 所以,我还有一些想法,并在您接受答案后添加了它们。仅供参考。
    • 谢谢。我真的感谢所有的努力。我目前正试图掌握在模板中直接引用person 而不仅仅是它的属性的含义。使用我的 KO 示例,我可以将模板重用于基本上具有这两个属性的所有内容。现在(至少从我目前的理解来看)我只是卸载了如何渲染人而不是定义一个(可重用的)模板
    • @NumLock 你总是可以定义一个只渲染人物的人物组件。
    • 这里有一个用户 @RoyJ,他回答了很多 Vue 和 Knockout 问题。如果您有任何从 Knockout 过渡到 Vue 的问题,您可能还想联系他。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-22
    • 2018-02-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多