jquery.vue.js_一个Vue.js简介,面向只了解jQuery的人

杜弘伟
2023-12-01

jquery.vue.js

by Matt Rothenberg

马特·罗森伯格(Matt Rothenberg)

一个Vue.js简介,面向只了解jQuery的人 (A Vue.js introduction for people who know just enough jQuery to get by)

I’ve had a love-hate relationship with JavaScript for years.

我与JavaScript的恋爱关系已经很多年了。

I got to know the language by way of the design and development community’s favorite whipping boy, jQuery. You see, at the time I began learning JavaScript, as a “Designer who codes,” working with jQuery was a magical experience. I could make modals fadeIn and fadeOut. With a third-party library, I could add parallax scrolling to my portfolio with just a single function call. Nearly everything I could have possibly dreamed of was encapsulated in a single, ~100kb file

我是通过设计和开发社区最喜欢的鞭子jQuery来了解这种语言的。 您会发现,当我开始学习JavaScript时,作为一个“编码设计师”,使用jQuery是一种神奇的体验。 我可以使模式fadeIn fadeOut 。 使用第三方库,我可以仅通过一个函数调用就将视差滚动添加到我的产品组合中。 我可能梦dream以求的几乎所有内容都封装在一个〜100kb的文件中 ……

And then Angular came out. I had no choice but to redo my entire portfolio with the framework. And then React came out. I had no choice but to redo my entire portfolio with the library. And then Vue.js came out. I had no choice but to redo my entire portfolio with the library… You see where this is going.

然后Angular出来了。 我只好重做我的整个投资组合的框架。 然后React出来了。 我只好重做我的整个投资组合的库。 然后Vue.js出来了。 我只好重做我的整个投资组合与库......你看这是怎么回事。

All jokes aside, I have greatly enjoyed honing my JavaScript chops through building things here and there with these different frameworks and libraries. I have read countless articles and tutorials in the process, but none has stuck with me more than Shu Uesugi’s piece, “React.js Introduction For People Who Know Just Enough jQuery To Get By.”

撇开所有笑话,我非常喜欢通过使用这些不同的框架和库在各处构建事物来磨练我JavaScript技巧。 在此过程中,我阅读了无数的文章和教程,但是除了Shu Uesugi的文章“ React.js入门,这些人只了解足够的jQuery才能通过

Shu takes readers — who are presumed to have some level of proficiency with JavaScript fundamentals and jQuery — on a journey through the world of React as they build a clone of Twitter’s “compose tweet” component.

Shu使读者(假定他们对JavaScript基础和jQuery具有一定程度的熟练程度)在构建Twitter的“ compose tweet”组件的副本时经历了React的世界。

This conceptual frame was quite helpful to me as someone who learns best by doing. Indeed, any time a new JavaScript library comes out, I find myself going back to the example from this article to test the waters. And so, I would like to borrow this frame as I step you all through my recent experience of learning Vue.

作为一个从中学到东西的人,这个概念框架对我很有帮助。 确实,每当新JavaScript库问世时,我都会回到本文的示例中来进行测试。 因此,在我逐步学习Vue的最新经历中,我想借用这个​​框架。

Before you begin the steps below, I highly encourage you to read Shu’s article. He does a fantastic job of walking you through the jQuery code you might write in order to implement some of these features. Thus, and so as to mitigate the risk of redundancy, I will focus on showing you the ins-and-outs of Vue.

在您开始以下步骤之前,强烈建议您阅读Shu的文章。 他出色地完成了带您完成可能要实现这些功能的jQuery代码的工作。 因此,为了减轻冗余的风险,我将着重向您展示Vue的来龙去脉。

我们正在建设什么 (What We’re Building)

Most of us tweet (some more prolifically than others). So we are probably familiar with the User Interface component in the screenshot below.

我们大多数人发推文(有些人发的话比其他人发的话)。 因此,我们可能熟悉以下屏幕截图中的用户界面组件。

Believe it or not, this UI component is a great example of how Vue (and React, as per Shu) might improve your life as a JavaScript/jQuery developer. The elements of this component that we will focus on building today are:

信不信由你,这个UI组件是Vue(以及Shu所说的React)如何改善您作为JavaScript / jQuery开发人员的生活的一个很好的例子。 我们今天将重点关注的该组件的元素是:

  • The <textarea> where users can enter their tweet

    <textar ea>用户可以在其中输入其推文

  • The <button> that is enabled/disabled as a function of how long the tweet is

    启用/禁用<butt on>的功能取决于推文的持续时间

  • A counter that indicates how many characters (out of 140) remain, and changes color to warn the user of this limit

    一个计数器,指示剩余的字符数(共140个),并更改颜色以警告用户此限制
  • A camera icon that, when clicked, allows users to attach photos to their tweet

    单击相机图标后,用户可以将照片附加到其推文中
  • A list of photos that have been attached

    已附加的照片列表
  • A button (per each photo) to remove it from the tweet

    一个按钮(每张照片)可将其从推文中删除

如果你被困 (If You’re Stuck)

If at any point you come across something that is confusing or poorly explained, don’t hesitate to tweet me at @mattrothenberg. Keep in mind as you read this article: it’s not you, it’s definitely me.

如果您在任何时候遇到令人困惑或难以解释的事情,请随时通过@mattrothenberg推特给我。 阅读本文时请记住:不是您,肯定是我。

Let’s get started.

让我们开始吧。

我们如何建造它 (How We’re Building It)

Today, we will be using CodePen to build our “Compose Tweet” component. For the uninitiated, CodePen is an online HTML/CSS/JavaScript editor akin to JSBin or JSFiddle. For each step, I’ll embed a CodePen with the relevant code.

今天,我们将使用CodePen构建“ Compose Tweet”组件。 对于初学者,CodePen是类似于JSBinJSFiddle的在线HTML / CSS / JavaScript编辑器。 对于每一步,我都会在CodePen中嵌入相关代码。

步骤1:搭建项目 (Step 1: Scaffold The Project)

The first thing we need to do, before writing any JavaScript, is to write the markup for our “Compose Tweet” component. Today we will be using Tachyons for almost all of our stylistic needs (so that we don’t have to write extraneous CSS, and can focus on the markup and JavaScript).

在编写任何JavaScript之前,我们要做的第一件事是为“ Compose Tweet”组件编写标记。 今天,我们将使用Tachyons满足几乎所有的样式需求(这样我们就不必编写多余CSS,而可以专注于标记和JavaScript)。

I am running with the assumption that you are pretty CSS savvy, so I will not spend time walking you through the Tachyons approach to styling (tl;dr so style, much classes, very functional).

我假设您非常精通CSS,所以我不会花时间介绍Tachyons样式(tl这样的样式,很多类,非常实用)。

In this CodePen I have also gone ahead and pulled in Vue via CDN. Indeed, one of the main selling points of Vue is the simplicity by which it can be integrated into a new or existing codebase.

在此CodePen中,我还继续前进并通过CDN引入了Vue。 确实,Vue的主要卖点之一就是可以将其集成到新的或现有代码库中的简便性。

With everything in place, let us get started on some feature work.

一切就绪后,让我们开始进行一些功能工作。

步骤2:实施第一个功能-最初应禁用Tweet按钮 (Step 2: Implement the First Feature — Tweet Button Should Initially Be Disabled)

Feature Description: Disable the blue Tweet button until a user has entered at least one character in the textarea .

功能描述 :禁用蓝色的Tweet按钮,直到用户在textarea输入了至少一个字符为止。

First things first, let us set up our Vue instance. As mentioned above, Vue has won the hearts and minds of Developers by its simplicity of installation and ease of use. We can construct a Vue instance with the following code.

首先,让我们设置Vue实例。 如上所述,Vue以其安装简便和易用性赢得了开发人员的青睐。 我们可以使用以下代码构造Vue实例。

new Vue({  el: '#twitterVue',  data: {    tweet: ''  },  computed: {    tweetIsEmpty: function() {      return this.tweet.length === 0;    }  }})

Let me explain what is going on here —

让我解释一下这是怎么回事-

  • el refers to the DOM element to which we are attaching our Vue instance. This should feel similar to instantiating a jQuery plugin by passing in a given selector, be it a class name or ID.

    el表示我们要将Vue实例附加到的DOM元素。 这应该类似于通过传入给定的选择器实例化jQuery插件,无论是类名还是ID。

  • data is an object that describe’s our instance’s data model, or state. We can access the attributes specified within this model both in our HTML — via a special curly brace syntax {{tweet}}— and within the instance itself (hint, look at the body of the tweetIsEmpty function)

    data是描述我们实例的数据模型或状态的对象。 我们可以在HTML中(通过特殊的花括号语法{{tweet}} )和实例本身(在提示中,查看tweetIsEmpty函数的tweetIsEmpty )访问在模型中指定的属性。

  • computed is an object that describes, as you might guess, computed properties based on our data model. Instead of adding logic to our HTML, it is recommended to encapsulate this kind of state (or any derived value, for that matter) via functions defined on the computed key of our Vue instance.

    您可能会猜到, computed是一个对象,它描述了基于我们的数据模型的计算属性。 建议不要通过在Vue实例的computed键上定义的函数来封装这种状态(或任何派生值),而不是向HTML添加逻辑。

Turning our attention now to the HTML, you will see that our markup has changed ever so slightly from the first CodePen. Specifically, we have made three changes.

现在将我们的注意力转向HTML,您会发现我们的标记与第一个CodePen相比已经发生了很小的变化。 具体来说,我们进行了三处更改。

  1. We added the id twitterVue to the outermost div so that we could construct our Vue instance.

    我们将id twitterVue添加到最外面的div以便我们可以构造Vue实例。

<div id="twitterVue">...</div>

2. We added the v-model directive to our textarea, thereby creating a two-way binding between user input and our instance’s data model. Now, any time a user types in the textarea, the tweet attribute on our instance’s data model is automagically updated.

2.我们将v-model指令添加到了textarea ,从而在用户输入和实例的数据模型之间创建了双向绑定 。 现在, textarea用户输入textarea ,实例数据模型上的tweet属性就会自动更新。

<textarea v-model="tweet"></textarea>

3. We added the :disabled attribute to our button. The colon preceding disabled denotes that we would like to evaluate the content inside the quotes as a JavaScript expression. If we were to omit the colon, the content would be treated as a string. You’ll also note that we’ve added a few lines of CSS to give the disabled button a distinct visual styling.

3.我们在button添加了:disabled属性。 之前的结肠disabled ,我们想引号为JavaScript表达式内的内容评价表示。 如果我们省略冒号,则内容将被视为字符串。 您还将注意到,我们添加了几行CSS,为禁用按钮提供了独特的视觉样式。

<button :disabled="tweetIsEmpty">Tweet</button>
...
button[disabled] {  cursor: not-allowed;  opacity: .5;}

4. We also added a computed property on our instance called tweetIsEmpty. Note that this property is actually a function that returns a boolean value based on the length of our data model’s tweet attribute. Vue makes it dead simple to access your data model both in the HTML (as shown above) and in the instance itself. Thanks to the magic of two-way data binding, this function is evaluated when the value of tweet is updated. When the function evaluates to true, our button is disabled, and vice-versa.

4.我们还在实例上添加了一个名为tweetIsEmpty的计算属性。 请注意,此属性实际上是一个函数 ,该函数根据数据模型的tweet属性的长度返回一个布尔值。 Vue使在HTML(如上所示)和实例本身中访问数据模型变得非常简单。 得益于双向数据绑定的魔力,当更新tweet的值时,将评估此功能。 当该函数的值为true时 ,我们的按钮将被禁用,反之亦然。

tweetIsEmpty: function() {  return this.tweet.length === 0;}

Admittedly, this felt like smoke and mirrors when I first got started with Vue. What helped me was to literally see what was happening to our data model under the hood as I interacted with the component. Since we can easily access our data model in our HTML via the aforementioned curly brace syntax, we can build a quick, visual feedback loop. Score!

不可否认,当我刚开始使用Vue时,这就像烟雾和镜子一样。 真正帮助我的是,在与组件进行交互时,真正了解了我们的数据模型的幕后情况。 由于我们可以通过上述大括号语法轻松地访问HTML中的数据模型,因此我们可以构建一个快速的视觉反馈循环。 得分!

<p>The value of <strong>tweet &lt;/strong>is: {{tweet}} </p><p>The value of <;strong>tweetIsEmpty</strong>is: {{ tweetIsEmpty}}</p>

Please feel free to repeat this step if anything along the way was confusing (either due to my poor writing or coding abilities, or due to Vue itself). Send a tweet or leave a comment if you have any particular questions.

如果途中发生任何混乱(由于我的写作或编码能力差,或由于Vue本身),请随时重复此步骤。 如果您有任何特殊问题,请发送推文或发表评论。

步骤3:实施第二个功能-显示剩余字符数 (Step 3: Implement the Second Feature — Show The Number of Characters Remaining)

Feature Description: As a user types, show the number of characters remaining (out of 140) in the tweet. If a user has entered more than 140 characters, disable the blue Tweet button.

功能描述 :当用户键入内容时,显示推文中剩余的字符数(共140个)。 如果用户输入的字符超过140个,请禁用蓝色的Tweet按钮。

So far we have learned about two-way data binding and computed properties, concepts that are at the very core of Vue. It is our lucky day, because we can leverage these concepts to build our next feature: showing the users how many characters (out of 140) remain, and disabling the button if this limit is eclipsed.

到目前为止,我们已经了解了双向数据绑定和计算属性,这些概念是Vue的核心。 这是我们的幸运日,因为我们可以利用这些概念来构建我们的下一个功能:向用户显示剩余的字符数(共140个),并且在超过此限制时禁用按钮。

Once again, I will step you through both the JavaScript and HTML changes required to implement this feature.

再一次,我将引导您完成实现此功能所需JavaScript和HTML更改。

In our JavaScript, we have done a few things.

在我们JavaScript中,我们做了一些事情。

  1. As a housekeeping measure, we enumerated the max length of a tweet (140 characters) as a constant, MAX_TWEET_LENGTH.

    作为整理措施,我们将一条tweet的最大长度(140个字符)枚举为常量MAX_TWEET_LENGTH

const MAX_TWEET_LENGTH = 140;

2. We added another computed property, charactersRemaining, which dynamically returns the difference between 140 and the length of the user-entered tweet.

2.我们添加了另一个计算出的属性charactersRemaining ,该属性动态返回140与用户输入的tweet的长度之间的差。

charactersRemaining: function() {  return MAX_TWEET_LENGTH - this.tweet.length;}

3. We renamed the old tweetIsEmpty property to tweetIsOutOfRange and updated the function’s logic accordingly. Note how we are using the computed charactersRemaining property to derive this value. Hooray for code reuse!

3.我们重命名了旧的tweetIsEmpty 属性为tweetIsOutOfRange 并相应地更新了函数的逻辑。 注意我们如何使用计算出的charactersRemaining 属性以得出值。 万岁代码重用!

tweetIsOutOfRange: function() {  return this.charactersRemaining == MAX_TWEET_LENGTH       || this.charactersRemaining < 0; }

On the HTML side of things, we only have to make a few changes, thanks to the power of Vue’s two-way data binding.

在HTML方面,由于Vue双向数据绑定的强大功能,我们只需要进行一些更改。

<div class="flex items-center">  <span class="mr3 black-70">{{ charactersRemaining }}</span>  <button :disabled="tweetIsOutOfRange" class="button-reset bg-blue bn white f6 fw5 pv2 ph3 br2 dim">Tweet</button></div>

For the visual learners out there, watch the magic:

对于在那里的视觉学习者,请注意魔术:

步骤4:实施第三个功能:“剩余字符”指示器的条件样式 (Step 4: Implement the Third Feature: Conditional Styling of “Characters Remaining” indicator)

Feature Description: When composing a Tweet, the color of the “characters remaining” indicator should change to dark red when only twenty characters remain, and light red when ten or fewer remain.

功能描述:编写Tweet时,“仅剩余字符”指示器的颜色应在仅剩余20个字符时变为深红色,而在剩余10个字符或更少时变为浅红色。

Manipulating an element’s style or class can be cumbersome with jQuery, and Vue offers a much cleaner way of doing so. Vue’s approach feels more declarative, in that you describe how you want something’s style to change (based, for example, on a given state) and you let Vue do the heavy lifting.

使用jQuery操纵元素的样式或类可能很麻烦,而Vue提供了一种更为简洁的方法。 Vue的方法更具声明性,因为您描述了如何更改某种样式(例如,基于给定状态),然后让Vue进行繁重的工作。

In the context of this feature, our “characters remaining” indicator has two such states, and a corresponding CSS class for each.

在此功能的上下文中,我们的“剩余字符”指示器具有两个这样的状态,并且每个状态都有一个对应CSS类。

  1. When between ten and twenty characters remain, the indicator should have the dark-red class

    当剩余十到二十个字符时,指示器应具有dark-red等级

  2. When fewer than ten characters remain, the indicator should have the light-red class

    当剩余的字符少于十个时,指示器应具有light-red等级

By now your Vue brain should be shouting “COMPUTED PROPERTIES!” So, let us oblige this brain and wire up those properties.

到现在为止,您的Vue大脑应该在喊“计算机性能!” 因此,让我们动脑筋,将这些属性联系起来。

underTwentyMark: function() {  return this.charactersRemaining <= 20     && this.charactersRemaining > 10;  },underTenMark: function() {  return this.charactersRemaining <= 10;}

With our logic in place, let us take a look at one of the ways in which Vue handles conditional styling: the v-bind:class directive. This directive expects an object whose keys are CSS classes, and whose values are the corresponding computed properties.

有了适当的逻辑,让我们看一下Vue处理条件样式的一种方式: v-bind:class指令。 该指令需要一个对象,其键是CSS类,其值是相应的计算属性。

{ 'dark-red': underTwentyMark, 'light-red': underTenMark }

By adding the directive to the span tag that encloses our “characters remaining” indicator, we have completed our feature.

通过将指令添加到包围“剩余字符”指示符的span标记中,我们完成了功能。

<span   v-bind:class="{ 'dark-red': underTwentyMark, 'light-red': underTenMark }">  {{ charactersRemaining }}</span>

Under the hood, and thanks to two-way data binding, Vue will handle the addition and removal of these classes as a function of the specified computed properties.

在后台,由于采用了双向数据绑定,Vue将根据指定的计算属性来处理这些类的添加和删除。

步骤5:实施第四个功能:“附加照片” UX (Step 5: Implement the Fourth Feature: “Attach Photo” UX)

Feature Description: Allow users to attach a single photo to their tweet via a file picker dialog. When the photo has been uploaded, show it beneath the textarea, and allow users to delete the attachment by clicking the image

功能描述:允许用户通过文件选择器对话框将单张照片附加到其推文中。 上传照片后,将其显示在textarea下方,并允许用户通过单击图像来删除附件

Fair warning: there is a lot going on in this section. The beauty is, despite this feature adding considerable functionality, we will not have to write that much code. So, let us start by breaking down the interaction design into steps.

合理的警告:本节中有很多事情要做。 美丽之处在于,尽管此功能添加了可观的功能,但我们不必编写那么多代码。 因此,让我们从将交互设计分解为几个步骤开始。

  1. User clicks the “Add Photo” button

    用户单击“添加照片”按钮
  2. User sees a file picker dialog and can select one photo to upload

    用户会看到一个文件选择器对话框,可以选择要上传的一张 照片

  3. Upon selecting the photo, a box appears underneath the textarea with the selected photo inside

    选择照片后, textarea下方会出现一个框,其中包含所选照片

  4. User clicks the circular X button to remove the photo

    用户单击圆形的X按钮以删除照片

  5. User sees initial state from step 1

    用户从步骤1中看到初始状态

Up to this point, we have not yet done any event handling (listening to button clicks, input changes, etc). As you might expect, Vue makes it easy to handle such events by affording us the v-on directive (@ for short). By passing a method as a value of this directive, we can effectively listen to DOM events and run JavaScript when they are triggered.

到目前为止,我们尚未进行任何事件处理(监听按钮单击,输入更改等)。 如您所料,Vue通过提供v-on指令(简称为@)使处理此类事件变得容易。 通过将方法作为此伪指令的值传递,我们可以有效地侦听DOM事件并在触发它们时运行JavaScript。

Before diving into our feature work, some rapid-fire practice.

在深入研究特色作品之前,请先进行一些快速射击练习。

Event handling is as easy as adding the @click directive to a given button and adding a corresponding method to the methods key on our Vue instance.

事件处理就像将@click指令添加到给定按钮并在Vue实例上的methods键中添加相应方法一样容易。

<button @click="logNameToConsole">Log User's Name<;/button>...methods: {  logNameToConsole: function() {    if( this.name !== 'Donald Trump' ) {      console.log(this.name);     } else {      console.warn('Sorry, I do not understand');    }  },}

Back to our feature work… In this step, our markup and JavaScript have changed in the following ways:

回到我们的功能工作…在这一步中,我们的标记和JavaScript已通过以下方式进行了更改:

  1. We added a button with an @click directive. When a user clicks this button, the triggerFileUpload method will get called.

    我们添加了带有@click指令的button 。 当用户单击此按钮时, triggerFileUpload方法将被调用。

<button @click="triggerFileUpload">...</button>

So, in our JavaScript, let us add a methods key to our Vue instance with said method inside, as well as a data attribute for our photo.

因此,在我们JavaScript中,让我们在内部带有上述方法的Vue实例中添加一个methods键,以及照片的data属性。

data: { photo: null},computed: {},methods: {  triggerFileUpload: function() {    this.$refs.photoUpload.click(); // LOLWUT?  },}

2. It is notoriously difficult to style HTML5 file inputs. One workaround involves putting an input in the DOM and hiding it with CSS. In order for the browser to open the native file picker, this input must be clicked. How it gets clicked, and how the client handles what the user uploads, though, is a different matter.

2.众所周知,设置HTML5文件输入的样式很难。 一种解决方法是将input放入DOM并用CSS隐藏。 为了使浏览器打开本机文件选择器, 必须单击此input 。 但是,如何单击它以及客户端如何处理用户上传的内容则是另一回事。

In our markup, we’ve added one such input and hidden it with a special hide class. We have also added a few other attributes worth calling out:

在我们的标记中,我们添加了一个这样的input ,并使用特殊的hide类将其hide 。 我们还添加了一些值得一提的其他属性:

<input ref="photoUpload" @change="handlePhotoUpload" type="file" class="hide">
  • The ref attribute is used to register a reference to a given DOM element. Given this reference, we can access the DOM element in our JavaScript code with this.$refs.photoUpload. Which means we can programmatically trigger a click() event on this element, thereby circumventing the challenge described above.

    ref属性用于注册给定DOM元素的引用 。 有了此参考,我们可以使用this.$refs.photoUpload访问JavaScript代码中的DOM元素。 这意味着我们可以以编程方式触发此元素上的click()事件,从而规避了上述挑战。

  • Clicking on the input is one thing; handling the file that the user uploads is another. Luckily, Vue allows us to attach a handler to the input’s change event via the @change directive. The method that we pass to this directive will be invoked after a user selects a file from the file picker. That method, handlePhotoUpload, is fairly straightforward

    单击输入是一回事; 处理用户上传的文件是另一回事。 幸运的是,Vue允许我们通过@change指令将处理程序附加到输入的change事件。 用户通过文件选择器选择文件后,将调用传递给该指令的方法。 该方法handlePhotoUploa d非常简单

handlePhotoUpload: function(e) {  var self = this;  var reader = new FileReader();        reader.onload = function(e) {    // Set that base 64 string to our data model's 'photo' key    self.photo = (e.target.result);  }  // Read upload file as base 64  string  reader.readAsDataURL(e.target.files[0]); }

Take a deep breath, because we are almost done with this feature!

深呼吸,因为我们几乎已完成此功能!

Once a user has uploaded a photo, we need to show a box underneath the textarea with the selected photo inside. Just as the conditional styling of elements is a breeze with Vue, so too is the conditional rendering, or display of elements. You’ll note that in our HTML, we have added the following markup underneath the textarea.

用户上传照片后,我们需要在textarea下方显示一个框,其中包含所选照片。 正如元素的条件样式对Vue轻而易举一样,条件渲染或元素显示也是如此。 您会注意到,在我们HTML中,我们在textarea下方添加了以下标记。

<div v-if="photoHasBeenUploaded">  <figure>    &lt;button @click="removePhoto">      ...    &lt;/button>    <img v-bind:src="photo">  </figure></div>

Vue offers a handful of template helpers (v-if, v-show, v-else , etc) to help you show and hide content conditionally. When the JavaScript expression passed to this directive evaluates to true, the element is rendered, and vice-versa.

Vue提供了一些模板助手( v-ifv-show, v-else等)来帮助您有条件地显示和隐藏内容。 当传递给该指令JavaScript表达式的值为true时,将呈现元素,反之亦然。

In our case, we added a v-if statement that evaluates the computed property photoHasBeenUploaded .

在我们的例子中,我们添加了一个v-if语句,该语句评估计算出的属性photoHasBeenUploaded

photoHasBeenUploaded: function() {  return this.photo !== null;}

When that function evaluates to true — when the photo key of our data model is not equal to null — the entire div gets rendered. Voilà!

当该函数的值为true时(当我们的数据模型的照片键不等于null时),整个div就会被渲染。 瞧!

And inside that div we render two elements:

在该div内,我们呈现两个元素:

  1. The image that was attached, by passing the contents of our data model’s photo key to Vue’s v-bind:src directive

    通过将数据模型的photo密钥的内容传递给Vue的v-bind:src指令,从而附加了图像

  2. A delete button that features another example of the@click handler, this particular one invoking a function that “removes” the photo by setting our data model’s photo key to null.

    一个删除按钮,具有@click处理程序的另一个示例,该特定按钮调用一个通过将数据模型的photo键设置为null来“删除”照片的功能。

removePhoto: function() {  this.photo = null;}

We are almost there.

我们就快到了。

第6步:更正,用户可以附加“ 照片(Step 6: Correction, user can attach “photos)

So, we can effectively handle a user attaching one photo to the Tweet, but what if she would like to upload many photos?

因此,我们可以有效地处理用户在Tweet上附加一张照片的情况,但是如果她想上传多张照片怎么办?

By now, you should be thinking something to the effect of: “I guess the only significant change here is being able to show multiple images in that box that appears conditionally beneath the textarea, considering we have already wired up our event handlers…” And you are correct! Let us take a look at the steps we need to follow

到现在为止,您应该在考虑以下效果:“我想这里唯一的重大变化是,考虑到我们已经连接了事件处理程序,因此能够在有条件显示在文本区域下方的框中显示多个图像……”你是对的! 让我们看看我们需要遵循的步骤

  1. We need to update our data model by changing photo to photos, the new key being an array of base64 strings (not a single base64 string)

    我们需要通过将photo更改为photos来更新数据模型,新键是base64字符串数组 (而不是单个base64字符串)

data: {  photos: []},

2. We need to update our computed property photoHasBeenUploaded to check against the length of our new photos key, which is now an array.

2.我们需要更新计算的属性photoHasBeenUploaded以检查新的photos密钥(现在是数组)的长度。

photoHasBeenUploaded: function() {  return this.photos.length > 0;}

3. We need to update our input @change handler to loop over the uploaded files and push them onto our photos key.

3.我们需要更新输入@change处理程序以遍历上载的文件,并将其推入我们的photos键。

handlePhotoUpload: function(e) {  var self = this;  var files = e.target.files;
for(let i = 0; i < files.length; i++) {    let reader = new FileReader();
reader.onloadend = function(evt) {      self.photos.push(evt.target.result);    }
reader.readAsDataURL(files[i]);  }},

On the HTML side, however, we must embark into new territory. Iterating over data and rendering content with jQuery can be cumbersome.

但是,在HTML方面,我们必须踏入新的领域。 使用jQuery遍历数据并呈现内容可能很麻烦。

var array = [1, 2, 3, 4, 5];var newHTML = [];for (var i = 0; i < array.length; i++) {    console.log('UGHHHHHH');    newHTML.push('<span>' + array[i] + '</span>');}$(".element").html(newHTML.join(""));

Thankfully, Vue offers an abstraction over this procedure by way of the v-for directive. This directive expects you to provide an expression in the form of (thing, index) in collectionOfThings, where collectionOfThings is the source array, thing is an alias for the array element being iterated on, and index is, well, the index of that element.

值得庆幸的是,Vue通过v-for指令对该过程进行了抽象。 该指令希望您以(thing, index) in collectionOfThings 的形式 (thing, index) in collectionOfThings 提供一个表达式 ,其中collectionOfThings是源数组, thing是要迭代的数组元素的别名,而index是该元素的索引。

A prototypical example might look like this:

一个典型的示例可能如下所示:

Where before we had a singular figure element for the user-uploaded photo, we will now have N figure tags corresponding to the length of the photos source array.

在我们为用户上传的照片使用单数figure元素之前,现在将有N个 figure标签对应于photos源阵列的长度。

Lucky for us, our markup doesn’t have to change too drastically since the overall structure of the design is still the same.

对我们来说幸运的是,由于设计的总体结构仍然相同,因此我们的标记不必进行太大的更改。

<figure v-for="(photo, index) in photos">  &lt;button @click="removePhoto(index)">    ...  </button>  <img v-bind:src="photo" class="h3 w3"></figure>

The one change that we need to make revolves around the removePhoto method which, before, set the singular photo key on our data model to null. Now, since we have N number of photos, we must pass the element’s index to the removePhoto method and pull that element out of the array.

我们需要进行的一项更改涉及removePhoto方法,该方法之前将数据模型上的removePhoto photo键设置为null 。 现在,由于有N张照片,我们必须将元素的索引传递给removePhoto方法,然后将该元素从数组中拉出。

removePhoto: function(index) {  this.photos.splice(index, 1);}

步骤7:动画+额外信用 (Step 7: Animation + Extra Credit)

In Twitter’s UI, the “Compose Tweet” component opens in a modal. For our grand finale, I would like to apply all of the Vue techniques we have learned so far and introduce one more: transitions.

在Twitter的UI中,“组合推文”组件以模式形式打开。 对于大结局,我想应用到目前为止所学的所有Vue技术,并介绍一种: transitions

A word of caution, transitions are a vast subject in Vue land. We are going to examine and implement a thin slice of this functionality, namely integrating a 3rd party animation library, Velocity JS, with Vue.

请注意,过渡是Vue领域中的一个巨大主题。 我们将检查并实现此功能的一小部分,即将第3方动画库Velocity JS与Vue集成在一起。

In a nutshell, Vue provides a transition component that allows you to add enter/leave animations for the element contained within, provided the element is set to be displayed conditionally via, for example, a v-if or v-show directive.

简而言之,Vue提供了一个transition组件,允许您为其中包含的元素添加输入/离开动画,前提是该元素被设置为通过例如v-ifv-show指令有条件地显示。

<transition   name="modal-transition"  v-on:enter="modalEnter"   v-on:leave="modalLeave">    <div v-if="modalShowing">       <!-- Our modal contents goes here ! -->    </div></transition>

In our example, we have attached two methods that correspond with two events in the transition lifecycle: v-on:enter and v-on:leave. We have thusly added these method definitions to our Vue instance, deferring to Velocity JS to fade our modal in and out.

在我们的示例中,我们附加了与过渡生命周期中的两个事件相对应的两个方法: v-on:enterv-on:leave 。 因此,我们已将这些方法定义添加到我们的Vue实例中,顺应Velocity JS fade我们的模态。

methods: {  modalEnter: function(el, done) {    Velocity(el, 'fadeIn', { duration: 300, complete: done, display: 'flex' })  },  modalLeave: function(el, done) {    Velocity(el, 'fadeOut', { duration: 300, complete: done })  }}

As mentioned above, the transition will fire when the element contained within is conditionally set to display. So, on the inner div of our transition component, we have added a v-if declaration whose value is a boolean modalShowing. Let us update our instance’s data model accordingly.

如上所述,当包含在其中的元素被有条件地设置为显示时, transition将触发。 因此,在transition组件的内部div上,添加了一个v-if声明,该声明的值是boolean modalShowing 。 让我们相应地更新实例的数据模型。

data: {  modalShowing: false}

Now, when we want to show the modal, all we have to do is set that boolean to true!

现在,当我们想要显示模态时,我们要做的就是将boolean设置为true!

<button @click="showModal">Compose Tweet</button>

And write a method to match.

并编写一个匹配的方法。

hideModal: function() {  this.modalShowing = false;},showModal: function() {  this.modalShowing = true;},

With some CSS trickery, we have also attached a click event handler to the backdrop, so users can hide the modal. Score!

借助一些CSS技巧,我们还将click事件处理程序附加到了背景上,以便用户可以隐藏模式。 得分!

<div   @click="hideModal"  class="backdrop"></div>

结论 (Conclusion)

Well, I hope that was not too painful (and that you learned a thing or two along the way). We only took a look at a small sliver of what Vue has to offer, though, as mentioned above, these concepts are crucial to unlocking the potential of Vue.

好吧,我希望那不是太痛苦(并且您在一路上学到了一两个东西)。 我们只看了一小部分Vue提供的功能,但是,如上所述,这些概念对于释放Vue的潜力至关重要。

I admit, it is unfair to compare Vue to jQuery. They are products of different times, with quite different use cases. However, for those who have struggled their way to learn DOM manipulation and event handling through jQuery, I hope these concepts are a breath of fresh air that you can apply to your workflow.

我承认,将Vue与jQuery比较是不公平的。 它们是不同时期的产品,具有完全不同的用例。 但是,对于那些为通过jQuery学习DOM操作和事件处理而苦苦挣扎的人,我希望这些概念能给您带来新鲜的气息,您可以将其应用于您的工作流。

翻译自: https://www.freecodecamp.org/news/vue-js-introduction-for-people-who-know-just-enough-jquery-to-get-by-eab5aa193d77/

jquery.vue.js

 类似资料: