如果要总结我对 Vue 的体验,我可能会说类似“它非常合理”或“它在我需要时提供我想要的工具,并且从不阻碍我”的话。在学习 Vue 的过程中,我一次又一次地对自己微笑。它非常合理,优雅。
这是我个人对 Vue 的入门介绍。这是我初学 Vue 时希望拥有的文章。如果您想了解更多中立的介绍,请访问 Vue 非常精心设计且易于理解的 指南。

文章系列
- 渲染、指令和事件 (您当前所在位置!)
- 组件、Props 和插槽
- Vue-cli
- Vuex
- 动画
我最喜欢 Vue 的一点是,它汲取了其他框架的所有成功之处,并将它们融入其中,而不会变得杂乱无章。一些让我印象深刻的例子
- 具有响应式组件的虚拟 DOM,仅提供视图层,类似 React 的 props 和 Redux 式存储。
- 类似 Angular 的条件渲染和服务。
- Vue 部分受到 Polymer 的启发,在简洁性和性能方面,Vue 提供了类似 HTML 的开发风格,HTML、样式和 JavaScript 协同组成。
与 Vue 的竞争对手相比,我享受的一些优势:更简洁、语义更强的 API 提供,比 React 略好的性能,不使用像 Polymer 这样的 polyfill,以及与 Angular(MVC)相比,更孤立、更少意见的视图。
我可以继续说下去,但您最好阅读他们全面且社区驱动的 与其他框架的比较。值得一读,但如果您想深入研究代码,可以稍后再返回。
开始吧!
在我们开始之前,不能不先来个必备的“Hello, world!”示例。让我们来做一下,这样您就可以开始使用了。
<div id="app">
{{ text }} Nice to meet Vue.
</div>
new Vue({
el: '#app',
data: {
text: 'Hello World!'
}
});
查看 Sarah Drasner 在 CodePen 上的笔 Vue Hello World(@sdras)。
如果您熟悉 React,就会发现两者有一些相似之处。我们使用 mustache 模板在内容中间转义到 JavaScript 中并使用了变量,但不同之处在于我们使用的是纯 HTML,而不是 JSX。JSX 非常易于使用,但我认为不必花费时间将 class
更改为 className
等也很不错。您还会注意到,这样可以非常轻松地启动并运行。
现在让我们尝试使用我最喜欢的功能之一:循环和条件渲染来体验 Vue。
条件渲染
假设我有一组项目,例如导航,我知道我将重复使用它们。将它们放在数组中以动态且一致地在几个地方更新它们可能是有意义的。在原生 JS(使用 Babel)中,我们可能会这样做:创建数组,然后创建一个空字符串,在其中添加用 <li>
包裹的每个项目,然后将所有这些项目用 <ul>
包裹起来,并使用 innerHTML 将其添加到 DOM 中。
<div id="container"></div>
const items = [
'thingie',
'another thingie',
'lots of stuff',
'yadda yadda'
];
function listOfStuff() {
let full_list = '';
for (let i = 0; i < items.length; i++) {
full_list = full_list + `<li> ${items[i]} </li>`
}
const contain = document.querySelector('#container');
contain.innerHTML = `<ul> ${full_list} </ul>`;
}
listOfStuff();
查看 Sarah Drasner 在 CodePen 上的笔 e699f60b79b90a35401cc2bcbc588159(@sdras)。
这可以正常工作,但对于如此标准的事情来说有点混乱。现在让我们使用 Vue 的 v-for
循环实现相同的功能。
<div id="app">
<ul>
<li v-for="item in items">
{{ item }}
</li>
</ul>
</div>
const app4 = new Vue({
el: '#app',
data: {
items: [
'thingie',
'another thingie',
'lots of stuff',
'yadda yadda'
]
}
});
查看 Sarah Drasner 在 CodePen 上的笔 Vue 中的条件渲染(@sdras)。
非常简洁且声明式。如果您熟悉 Angular,这很可能很熟悉。我发现这是一种非常简洁易读的条件渲染方式。如果您跳入代码并需要更新它,您可以非常轻松地做到。
另一个非常棒的功能是使用 v-model 进行动态绑定。看看这个
<div id="app">
<h3>Type here:</h3>
<textarea v-model="message" class="message" rows="5" maxlength="72"></textarea><br>
<p class="booktext">{{ message }} </p>
</div>
new Vue({
el: '#app',
data() {
return {
message: 'This is a good place to type things.'
}
}
});
查看 Sarah Drasner 在 CodePen 上的笔 Vue Book v-model 基础(@sdras)。
您可能会注意到此演示中的两件事。首先,直接在书中键入并动态更新文本实际上不需要任何操作。Vue 使我们能够使用 v-model
在 <textarea>
和 <p>
之间非常轻松地设置双向绑定。
您可能注意到的另一点是,我们现在将数据放在一个函数中。在此示例中,即使不这样做也可以正常工作。我们可以像之前的示例一样将其放在对象中。但这仅适用于 Vue 实例,并且在整个应用程序中完全相同(因此,对于单个组件来说不太好)。对于一个 Vue 实例来说是可以的,但它也会在所有子组件之间共享数据。最好从将数据放在函数中开始,因为当我们开始使用组件并希望它们各自拥有自己的状态时,我们需要这样做。
这些并不是唯一可用的简单输入绑定,甚至 v-if
也有一个替代方案 v-show
,它不会挂载/卸载组件,而是保留在 DOM 中并切换可见性。
还有 许多其他指令 可供您使用,以下是一些我经常使用的指令示例。许多指令也提供了快捷方式,因此我将同时展示两者。从这里开始,我们将主要使用快捷方式,因此至少在表中熟悉一下它们会很好。
名称 | 快捷方式 | 用途 | 示例 |
---|---|---|---|
v-if、v-else-if、v-else |
无 | 条件渲染 | <g v-if="flourish === 'A'"></g> |
v-bind |
: | 动态绑定属性或传递 props | <div :style="{ background: color }"></div> |
v-on |
@ | 将事件侦听器附加到元素 | <button @click="fnName"></button> |
v-model |
无 | 创建双向绑定 | <textarea rows="5" v-model="message" maxlength="72"></textarea> |
v-pre |
无 | 跳过编译以获取原始内容,可以提高性能 | <div v-pre>{{ 没有方法的原始内容 }}</div> |
v-once |
无 | 不要重新渲染 | <div class="v-once">阻止我重新渲染</div> |
v-show |
无 | 根据状态显示或隐藏组件/元素,但不会卸载它(与 v-if 不同) | <child v-show="showComponent"></child> (当 showComponent 为 true 时切换可见性) |
还有一些非常棒的事件修饰符和其他 API 功能可以加快开发速度,例如
@mousemove.stop
可与e.stopPropogation()
相媲美@mousemove.prevent
这类似于e.preventDefault()
@submit.prevent
这将不再在提交时重新加载页面@click.once
不要与 v-once 混淆,此 点击事件 将触发一次。v-model.lazy
不会自动填充内容,它将等待事件发生后绑定。
您甚至可以 配置您自己的键码。
我们将在接下来的示例中更多地使用这些功能!
事件处理
绑定数据很好,但如果没有事件处理,它只能让我们走这么远,所以接下来让我们来了解一下!这是我最喜欢的部分之一。我们将使用上面的绑定和监听器来监听 DOM 事件。
在我们的应用程序中创建可用方法的方法有几种。就像在原生 JS 中一样,您可以选择函数名称,但方法直观地称为,嗯,方法!
new Vue({
el: '#app',
data() {
return {
counter: 0
}
},
methods: {
increment() {
this.counter++;
}
}
});
<div id="app">
<p><button @click="increment">+</button> {{ counter }}</p>
</div>
我们正在创建一个名为 increment
的方法,您可以看到它会自动绑定到 this
,并且将引用此实例和组件中的数据。我喜欢这种自动绑定,不用 console.log
就能看到 this
指的是什么,这真是太好了。我们在这里使用快捷方式 @click
来绑定到 click 事件。
方法并不是创建自定义函数的唯一方法。您还可以使用 watch
。主要区别在于,方法适用于小型同步计算,而 watch
则有助于响应数据变化执行更耗时或异步或昂贵的操作。我倾向于最常在动画中使用 watch。
让我们更进一步,看看如何传入事件本身并进行一些动态样式绑定。如果您还记得上面表格中的内容,则无需编写 v-bind
,可以使用快捷方式 :
,因此我们可以通过使用 :style
并传入状态或 :class
来非常轻松地绑定到样式(以及其他属性)。这种绑定确实有很多用途。
在下面的示例中,我们使用了hsl()
,其中色相计算为一个颜色度数圆圈,它会环绕整个圆圈。这对于我们的用途来说很好,因为它永远不会失败,因此当我们在屏幕上用像素跟踪鼠标时,背景样式会相应地更新。我们在这里使用的是ES6 模板字面量。
new Vue({
el: '#app',
data() {
return {
counter: 0,
x: 0
}
},
methods: {
increment() {
this.counter++;
},
decrement() {
this.counter--;
},
xCoordinate(e) {
this.x = e.clientX;
}
}
});
<div id="app" :style="{ backgroundColor: `hsl(${x}, 80%, 50%)` }" @mousemove="xCoordinate">
<p><button @click="increment">+</button> {{ counter }} <button @click="decrement">-</button></p>
<p>Pixels across: {{ x }}</p>
</div>
查看 CodePen 上 Sarah Drasner (@sdras) 编写的笔 显示简单的事件处理。
您可以看到,我们甚至不需要将事件传递给@mousemove
处理程序,Vue 会自动为您传递它,以便作为方法的参数可用。(此处显示为e
)。
此外,还可以使用原生方法,例如event.clientX
,并且可以轻松地将它们与this
实例配对。在元素上的样式绑定中,带连字符的 CSS 属性使用驼峰命名法。在这个例子中,您可以看到 Vue 使用起来多么简单和声明式。
我们甚至不需要创建方法,如果事件足够简单,我们也可以直接在组件内增加计数器。
<div id="app">
<div class="item">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/28963/backpack.jpg" width="235" height="300"/>
<div class="quantity">
<button class="inc" @click="counter > 0 ? counter -= 1 : 0">-</button>
<span class="quant-text">Quantity: {{ counter }}</span>
<button class="inc" @click="counter += 1">+</button>
</div>
<button class="submit" @click="">Submit</button>
</div><!--item-->
</div>
new Vue({
el: '#app',
data() {
return {
counter: 0
}
}
});
查看 CodePen 上 Sarah Drasner (@sdras) 编写的笔 背包商店计数器。
您可以看到,我们直接在@click
处理程序中更新状态,根本没有使用方法——您还可以看到我们也可以在其中添加一些逻辑(因为在购物网站上商品数量不会低于零)。但是,一旦这种逻辑变得过于复杂,可读性就会降低,因此最好将其移到方法中。不过,能够选择两者中的任何一种都很好。
文章系列
- 渲染、指令和事件 (您当前所在位置!)
- 组件、Props 和插槽
- Vue-cli
- Vuex
- 动画
现在……发布了很多框架……所以很难选择哪个更好学习?哪个更容易学习?Angular/React 或 Vue?任何建议都将不胜感激……
您好!
您刚刚提出了一个永恒的问题!我认为这实际上取决于您的需求,文章的第一部分旨在对此进行一些解答。但话虽如此,我想说如果您正在寻找一个完整的 MVC,Angular 2 是一个非常不错的选择(Vue 和 React 仅为视图层)。如果您正在寻找一个拥有出色社区的东西,React 非常棒。如果您想要一个功能强大但优雅易读且简单的工具,Vue 非常出色。也就是说,每个人都会对这个问题给出不同的答案,因此最好查看 Todo.mvc,它在代码中比较了每个框架,或者在进行生产投入之前尝试一下每个框架。希望这有帮助!
哇,酷
关于备受喜爱的 Vue.js 的精彩讨论,请继续努力……
谢谢!明天见!并且本周的每一天:)
太棒了!特别期待动画文章。酷毙了!
嗨,Sarah,您使用 Vue 构建了哪些项目?您能否提供一些链接?谢谢!
期待您的下一篇文章。
嗨,Lars!
我的 GitHub 个人资料上有一些示例存储库,我们将在后续文章中使用它们作为示例,这将为现实生活中的构建过程提供更多细节。
https://github.com/sdras/vue-wine-label
https://github.com/sdras/vue-weather-notifier
我与 Vue 的所有其他工作都是专有的,无法发布,因此希望这些示例和其他文章对您有所帮助。
我真的很喜欢 Vue 的务实方法——非常易于上手并与其他库和工具连接,而且这一切都无需过度规定。这使得将 Vue 添加到现有项目变得很容易,而无需进行重大代码重写。
我同意!
很棒的介绍!非常有帮助。在您的色相饱和度示例中,您可以通过将其放入模板字面量 ${x} 中来访问您的“x”,而不是使用八字胡 {{ }}。这是因为 :bind 方法会自动访问 data 函数内部的所有项吗?
对于您的事件处理代码示例,您只是缺少一个“}”来关闭 methods 对象。
谢谢
嗨,Alex!
很高兴您觉得它有帮助。是的,您说对了,我使用的 :style 属性使用了 v-bind 的简写形式,因此我能够访问状态。您可以通过简单地将 :style 更改为 style 来检查这一点,并且 hsla 背景将不再起作用。感谢您发现我的打字错误!已修复。
非常棒的介绍!对于喜欢并说西班牙语的人,我在https://www.jaimeolmo.com/2016/02/primeros-pasos-usando-vue-js/ 发表了类似的文章。
干杯!
非常好。谢谢!
Vue 是否适用于具有 5-15 个组件/页面的多页(例如 10 页/选项卡)应用程序?复杂度是否呈指数增长?
是的,当然可以!为了清楚起见,我们从这里开始从小处着手。在未来的文章中,我们将讨论一些实际的构建,并提供一些示例以及 Vuex 用于更复杂的状态管理。
这是我的第一个框架,与 React 和 Angular 相比,Vue 看起来更容易学习。
关于事件处理程序 @mousemove 的一个问题?为什么 Vue 文档中没有提到它?:( 我已经搜索了一段时间……
顺便说一句,干得好,期待后续内容 ^^
嗨,Can——关于 @mousemove,基本上使用 Vue 事件,您可以使用任何原生 JavaScript DOM 事件名称,因此只要将“on”替换为“@”,所有常用的事件名称都将起作用。
例如 onmousemove –> @mousemove
onkeydown –> @keydown
onblur –> @blur
等等……
天哪,别告诉我我们可以用 @ 使用任何 js 事件处理?xD 被击中了 QQ
谢谢,就像您写的那样
好文章 :)
在考虑将应用程序从 Angular 1 迁移时,我确实“喝了 Vue 的水”——但 Angular 2 并不真正适合我的[现有]工作流程。Vue 易于学习,以及它兼具两者的氛围,这一点颇具吸引力。我有点支持它,所以我很高兴看到您将 CSS-Tricks 的索伦之眼引向它。
这听起来非常不祥,但让我们假设索伦之眼的灯光温暖而舒适。
感谢您的精彩文章。此外,字符串“@mousemove.prevent 这就像 e.preventDelegation()”中似乎有一个错别字。
应该是 preventDefault 吧?
哈哈,抱歉,打错了,现在已经修复了,谢谢!
到目前为止,我读过的关于 Vue.js 最好的介绍。非常棒。谢谢!
嗨,Sarah,
您缺少一些内容来演示此事件部分。
关于如何在独立的自定义组件上创建自定义事件
The
1. this.$emit(‘custom-name-of-event’, data)
2. this.$dispatch(‘custom-name-of-event’, data)
3. this.$broadcast(‘custom-name-of-event’, data)
好文章!
观点很棒!这可能应该放在我们转到第 3 节中的真实组件部分时进行讨论,但你完全正确,我忽略了这一点。在我完成整个系列后,我会进行修改并将其包含在内。感谢你的提醒。
嗨,Sarah,看起来你已经使用过 Vue 和 Angular 了。我想了解一下你对 Vue.js 是否适合大型应用程序的看法(背景:一个后端使用 Java 并且需要调用/请求 RESTful API 服务的应用程序)。
我认为它非常适合大型应用程序,特别是因为它“站在了”其他替代方案(如 Angular 和 React)的肩膀上,例如包含 Vuex,它提供了一个类似 Redux 的状态管理库,我认为这对管理具有大量状态的应用程序非常重要。
关于 $broadcast 和 $dispatch - 我认为它们在 Vue2 中已被弃用。
https://github.com/vuejs/vue/issues/2873
这是一个很棒的 Vue.js 入门教程。奇怪的是,Vue 没有像 React 或 Angular 那样获得那么多关注,这可能是因为它没有得到两家互联网巨头的支持。我认为,在从 Backbone 应用程序迁移时,Vue 提供了比 React 更好的替代方案。