指南
基础
- 安装
- 介绍
- Vue 实例
- 模板语法
- 计算属性和侦听器
- 类和样式绑定
- 条件渲染
- 列表渲染
- 事件处理
- 表单输入绑定
- 组件基础
组件深入
- 组件注册
- Props
- 自定义事件
- 插槽
- 动态和异步组件
- 处理边缘情况
过渡和动画
- 进入/离开和列表过渡
- 状态过渡
可重用性和组合
- 混入
- 自定义指令
- 渲染函数和 JSX
- 插件
- 过滤器
工具
- 单文件组件
- 测试
- TypeScript 支持
- 生产部署
扩展
- 路由
- 状态管理
- 服务器端渲染
- 安全
内部机制
- 深入响应式
迁移
- 从 Vue 1.x 迁移
- 从 Vue Router 0.7.x 迁移
- 从 Vuex 0.6.x 迁移到 1.0
- 迁移到 Vue 2.7
元数据
- 与其他框架的比较
- 加入 Vue.js 社区!
- 认识团队
组件基础
基本示例
这是一个 Vue 组件的示例
|
组件是具有名称的可重用 Vue 实例:在本例中,<button-counter>
。我们可以使用此组件作为自定义元素,在使用 new Vue
创建的根 Vue 实例中使用。
|
|
由于组件是可重用 Vue 实例,因此它们接受与 new Vue
相同的选项,例如 data
、computed
、watch
、methods
和生命周期钩子。唯一的例外是 el
等一些根特定选项。
重用组件
组件可以根据需要重用多次。
|
请注意,当单击按钮时,每个按钮都保持其自己的独立 count
。这是因为每次使用组件时,都会创建一个它的新 **实例**。
data
必须是函数
当我们定义 <button-counter>
组件时,您可能已经注意到 data
没有直接提供一个对象,就像这样
|
相反,**组件的 data
选项必须是一个函数**,以便每个实例都可以维护返回的数据对象的独立副本。
|
如果 Vue 没有这个规则,单击一个按钮会影响所有其他实例的数据,如下所示。
组织组件
应用程序通常被组织成嵌套组件的树结构。
例如,您可能拥有用于页眉、侧边栏和内容区域的组件,每个组件通常包含用于导航链接、博客文章等的其他组件。
要在模板中使用这些组件,必须注册它们,以便 Vue 知道它们。组件注册有两种类型:**全局** 和 **局部**。到目前为止,我们只使用 Vue.component
全局注册组件。
|
全局注册的组件可以在任何随后创建的根 Vue 实例 (new Vue
) 的模板中使用 - 甚至可以在该 Vue 实例的组件树的所有子组件中使用。
现在您只需要了解注册即可,但是,在您阅读完本页并对内容感到满意后,我们建议您稍后回来阅读有关 组件注册 的完整指南。
使用 Props 将数据传递给子组件
之前,我们提到过为博客文章创建组件。问题是,除非您可以向它传递数据(例如要显示的特定文章的标题和内容),否则该组件将毫无用处。这就是 Props 的作用。
Props 是您可以注册在组件上的自定义属性。当将值传递给 prop 属性时,它将成为该组件实例上的一个属性。要将标题传递给我们的博客文章组件,我们可以将其包含在该组件接受的 props 列表中,使用 props
选项。
|
组件可以拥有任意数量的 props,默认情况下,任何值都可以传递给任何 prop。在上面的模板中,您将看到我们可以访问组件实例上的此值,就像使用 data
一样。
注册 prop 后,您可以像这样将数据作为自定义属性传递给它。
|
但是,在典型的应用程序中,您可能在 data
中有一个文章数组。
|
然后想要为每个文章渲染一个组件。
|
在上面,您将看到我们可以使用 v-bind
动态传递 props。当您事先不知道要渲染的确切内容时(例如,当 从 API 获取文章 时),这特别有用。
现在您只需要了解 props 即可,但是,在您阅读完本页并对内容感到满意后,我们建议您稍后回来阅读有关 Props 的完整指南。
单个根元素
在构建 <blog-post>
组件时,您的模板最终将包含的不仅仅是标题。
|
至少,您需要包含文章的内容。
|
但是,如果您在模板中尝试这样做,Vue 会显示一条错误消息,说明 **每个组件都必须有一个单个根元素**。您可以通过将模板包装在父元素中来修复此错误,例如
|
随着组件的增长,我们可能不仅需要文章的标题和内容,还需要发布时间、评论等等。为每个相关信息定义一个 prop 会变得非常烦人。
|
因此,现在可能是将 <blog-post>
组件重构为接受单个 post
prop 的好时机。
|
|
上面的示例和一些将来的示例使用 JavaScript 的 模板字面量 使多行模板更易读。这些不受 Internet Explorer (IE) 支持,因此,如果您必须支持 IE 并且没有进行转译(例如,使用 Babel 或 TypeScript),请改用 换行符转义。
现在,每当向 post
对象添加新属性时,它都会自动在 <blog-post>
中可用。
监听子组件事件
在开发 <blog-post>
组件时,某些功能可能需要与父组件进行通信。例如,我们可能决定添加一个辅助功能,以放大博客文章的文本,同时保持页面其余部分的默认大小。
在父组件中,我们可以通过添加 postFontSize
数据属性来支持此功能。
|
它可以在模板中使用,以控制所有博客文章的字体大小。
|
现在,让我们在每篇文章内容之前添加一个按钮来放大文本。
|
问题是,此按钮没有任何作用。
|
当我们单击按钮时,我们需要向父组件传达它应该放大所有文章的文本。幸运的是,Vue 实例提供了一个自定义事件系统来解决此问题。父组件可以使用 v-on
监听子组件实例上的任何事件,就像我们处理原生 DOM 事件一样。
|
然后,子组件可以通过调用内置的 $emit
方法 在自身上发出事件,并传递事件的名称。
|
由于 v-on:enlarge-text="postFontSize += 0.1"
监听器,父组件将接收事件并更新 postFontSize
值。
使用事件发出值
有时,使用事件发出特定值很有用。例如,我们可能希望 <blog-post>
组件负责放大文本的程度。在这些情况下,我们可以使用 $emit
的第二个参数来提供此值。
|
然后,当我们在父组件中监听事件时,我们可以使用 $event
访问发出的事件的值。
|
或者,如果事件处理程序是一个方法。
|
那么该值将作为该方法的第一个参数传递。
|
在组件上使用 v-model
自定义事件也可以用来创建与 v-model
配合使用的自定义输入。请记住,
|
与
|
的作用相同。当在组件上使用时,v-model
反而会这样做。
|
但是,要使这真正起作用,组件内的 <input>
必须
- 将
value
属性绑定到value
prop。 - 在
input
上,使用新值发出自己的自定义input
事件。
以下是实际操作。
|
现在,v-model
应该与该组件完美配合。
|
现在您只需要了解自定义组件事件即可,但是,在您阅读完本页并对内容感到满意后,我们建议您稍后回来阅读有关 自定义事件 的完整指南。
使用插槽进行内容分发
就像使用 HTML 元素一样,能够将内容传递给组件通常很有用,例如这样。
|
它可能会渲染类似于以下内容。
幸运的是,Vue 的自定义 <slot>
元素使此任务变得非常简单。
|
如您在上面看到的,我们只需在想要放置插槽的位置添加它 - 就这样。我们完成了!
现在您只需要了解插槽即可,但是,在您阅读完本页并对内容感到满意后,我们建议您稍后回来阅读有关 插槽 的完整指南。
动态组件
有时,在选项卡式界面中,动态切换组件很有用。
上面是通过 Vue 的 <component>
元素以及 is
特殊属性实现的。
|
在上面的示例中,currentTabComponent
可以包含
- 注册组件的名称,或者
- 组件的选项对象。
查看这个例子来尝试完整的代码,或者这个版本来查看一个绑定到组件选项对象的例子,而不是它的注册名称。
请记住,此属性可以与常规 HTML 元素一起使用,但是它们将被视为组件,这意味着所有属性将被绑定为 DOM 属性。对于某些属性,例如value
,要按预期工作,您需要使用.prop
修饰符绑定它们。
现在您只需要了解动态组件,但是,在您读完本页并熟悉其内容后,我们建议您稍后回来阅读有关动态和异步组件的完整指南。
DOM 模板解析注意事项
某些 HTML 元素,例如<ul>
、<ol>
、<table>
和 <select>
对其内部可以出现的元素有限制,而某些元素,例如<li>
、<tr>
和 <option>
只能出现在某些其他元素内部。
这将在使用具有此类限制的元素的组件时导致问题。例如
|
自定义组件<blog-post-row>
将被提升为无效内容,导致最终渲染输出中的错误。幸运的是,is
特殊属性提供了一种解决方法
|
需要注意的是,如果您使用以下来源之一的字符串模板,则不适用此限制
- 字符串模板(例如
template: '...'
) - 单文件(
.vue
)组件 <script type="text/x-template">
现在您只需要了解 DOM 模板解析注意事项 - 实际上,这是 Vue 的Essentials的结尾。恭喜!还有更多内容要学习,但首先,我们建议您休息一下,自己玩玩 Vue 并构建一些有趣的东西。
一旦您对刚刚吸收的知识感到满意,我们建议您回来阅读有关动态和异步组件的完整指南,以及侧边栏中“组件深入”部分的其他页面。