【问题标题】:How to build a simple Vue.js application using a separate template file?如何使用单独的模板文件构建简单的 Vue.js 应用程序?
【发布时间】:2019-06-09 20:44:54
【问题描述】:

我是 Vue.js 的新手,我对文件结构以及如何构建简单的应用程序感到困惑。

我已经使用这个命令在我的 Mac 上安装了 Vue CLI:

npm install -g @vue/cli

然后我创建了一个计数器项目并使用了默认选项:

vue create counter

然后我启动了应用程序:

cd counter

npm run serve

默认应用程序代码让我感到困惑,所以我想创建自己的简单应用程序,对我来说更有意义:

我在公共文件夹中创建了 counter.html:

 <html lang="en">
  <body>
  <div id="counter"></div>
  </body>
  <script src="../src/counter.js" type="text/javascript"></script>
</html> 

我在 src 文件夹中创建了 counter.js 文件:

import Vue from 'vue';
import Counter from './components/counter.vue';

new Vue({
  render: h => h(Counter),
}).$mount('#counter')

我在 components 文件夹中创建了 counter.vue 文件:

<template>
    <button v-on:click="count++">You clicked me {{ count }} times.</button>
</template>
<script type="text/javascript">
    export default {
        name: 'Counter',
        props: [
            'count'
         ],
      }
</script>

然后我运行:

npm run build

当我访问我的页面时:http://localhost:8080/counter.html 我得到一个空白页,控制台显示以下错误:Uncaught SyntaxError: Unexpected token

非常感谢任何有关我做错的帮助。

【问题讨论】:

  • 还有其他信息吗?代码中的位置行数? npm run serve 显示带有完整堆栈跟踪的详细统计信息。
  • counter.vue 中的模板有一个浮动撇号
  • 我删除了浮动撇号,但仍然是相同的空白页和控制台日志错误。 npm run serve 显示已编译成功应用程序运行的标准消息:localhost:8080
  • 如果将 id 更改为“app”并将挂载更改为“#app”会发生什么。我很确定这是默认 Vue CLI 安装所必需的。
  • 另外,您的脚本标签位于counter.html 中的无效位置。它需要进入headbody,但不能在结束body标签之后。

标签: javascript vue.js vuejs2 vue-component


【解决方案1】:

首先,正如@Dan所说,脚本标签应该在&lt;body&gt;,而不是之后。

也就是说,您的代码存在根本缺陷:您的按钮正在改变 Count 组件中接收到的属性。

假设您在一个更大的应用程序中使用 Counter,并且您想用一个计数值对其进行初始化。你会写:&lt;Counter count="3" /&gt;,但随后点击会将这个“3”变异变成“4”,即使count="3" 是静态写入的;由于按钮的属性突变,count属性的public声明与实际值会不一致。

在这里,您有多种选择:

  1. 不要使用道具,只使用计数组件的内部状态。这种结构的优点是组件是独立的;缺点是在创建组件时无法使用自定义值初始化“count”。
<template>
    <button v-on:click="count++">You clicked me {{ count }} times.</button>
</template>
<script type="text/javascript">
    export default {
        name: 'Counter',
        data: function() { return { count: 0 } },
      }
</script>
  1. 改用事件,并将计数值保存在计数器组件外部。这可能是在组件中最容易实现的,但随后需要在父组件中添加额外的代码。这样做的好处是值保存在组件之外,因此可以进行自定义;缺点是,如果没有适当的绑定来更新值,它将无法工作。
<template>
    <button v-on:click="$emit('increment')">You clicked me {{ count }} times</button>
</template>
<script type="text/javascript">
    export default {
        name: 'Counter',
        props: [
            'count'
         ],
      }
</script>

然后在你的应用程序中:

<template>
  <counter :count="count" @increment="count++" />
</template>

<script>
export default {
  data: () => ({ count: 0 })
}
</script>
  1. 前两种解决方案的组合。保持一个内部状态,以便按钮可以自行管理,但也可以使用观察者与外部世界正确同步。
<template>
    <button v-on:click="internal_count++">You clicked me {{ internal_count }} times</button>
</template>
<script type="text/javascript">
    export default {
        name: 'Counter',
        props: [
            'count'
        ],
        watch: {
            count(val) { this.internal_count = val },
            internal_count(val) { this.$emit('update', val) },
        },
      }
</script>

然后在您的应用中:

<template>
  <counter :count="count" @update="v => count = v" />
</template>

<script>
export default {
  data: () => ({ count: 0 })
}
</script>

基本上,经验法则是:

  1. 不要改变道具并将其视为唯一的事实来源
  2. 如果你想改变一个道具,请发送一个事件并希望接收者会为你更新道具,然后你可以收到更新的道具。

希望得到帮助,

【讨论】:

    猜你喜欢
    • 2011-04-06
    • 2017-05-14
    • 2021-10-23
    • 2018-12-25
    • 1970-01-01
    • 1970-01-01
    • 2016-01-02
    • 2014-01-08
    • 2013-05-05
    相关资源
    最近更新 更多