首页 >web前端 >js教程 >如何用vue替换jQuery

如何用vue替换jQuery

Lisa Kudrow
Lisa Kudrow原创
2025-02-14 09:56:11821浏览

告别jQuery,拥抱Vue.js:构建更简洁高效的Web应用

How to Replace jQuery with Vue

想从零开始学习Vue.js?立即加入SitePoint Premium,获取涵盖Vue.js基础知识、项目实战、技巧工具及更多内容的完整Vue.js书籍合集,每月只需$14.99!

许多开发者在构建简单应用时仍然依赖jQuery。虽然有时只需为页面添加少量交互性,但使用JavaScript框架似乎显得过于复杂——额外的代码量、样板代码、构建工具和模块打包器等等。从CDN引入jQuery似乎是轻而易举的选择。

本文旨在说服您,即使对于相对简单的项目,使用Vue.js(以下简称Vue)也无需费力,反而能帮助您更快地编写更好的代码。我们将以一个简单的示例为例,分别使用jQuery和Vue进行编码,并逐步演示其差异。

关键要点

  • 将jQuery替换为Vue.js用于基本项目并非难事,并且可以编写出更好、更快的代码。
  • Vue.js允许UI与驱动它的逻辑/数据清晰分离,使代码更易于理解和测试。
  • Vue.js中的UI是声明式的,这意味着开发者只需要关注他们想要看到的内容,而无需关注如何操作DOM来实现它。
  • Vue.js和jQuery的大小相似,但Vue.js提供了更便捷的开发体验和更易读的代码。
  • Vue.js可以创建模块化、可重用的UI组件,这些组件可以组合成复杂的前端应用程序。

我们将构建的内容

本文将构建一个简单的在线发票,使用Sparksuite提供的开源模板。希望这能比另一个待办事项列表更有新意,并且具有足够的复杂性来展示使用Vue的优势,同时又易于理解。

How to Replace jQuery with Vue

我们将通过提供项目、单价和数量输入来使其具有交互性,并在其中一个值更改时自动重新计算“价格”列。我们还将添加一个按钮,用于在发票中插入新的空行,以及一个“总计”字段,该字段将在我们编辑数据时自动更新。

我已经修改了模板,以便单个(空)行的HTML如下所示:

<code class="language-html"><tr> class="item">
  <td><input type="text" v-model="item.description"></td>
  <td><input type="number" v-model="item.price"></td>
  <td><input type="number" v-model="item.quantity"></td>
  <td>
<pre class="brush:php;toolbar:false"><code class="language-javascript">$('table').on('mouseup keyup', 'input[type=number]', calculateTotals);</code>
.00

jQuery实现

首先,让我们看看如何使用jQuery来实现这个功能。

<code class="language-javascript">function calculateTotals() {
  const subtotals = $('.item').map((idx, val) => calculateSubtotal(val)).get();
  const total = subtotals.reduce((a, v) => a + Number(v), 0);
  $('.total td:eq(1)').text(formatAsCurrency(total));
}</code>

我们将监听器附加到表格本身,当“单位成本”或“数量”值更改时,将执行calculateTotals函数:

<code class="language-javascript">function calculateSubtotal(row) {
  const $row = $(row);
  const inputs = $row.find('input');
  const subtotal = inputs[1].value * inputs[2].value;

  $row.find('td:last').text(formatAsCurrency(subtotal));

  return subtotal;
}</code>

此函数查找表格中的所有项目行并循环遍历它们,将每一行传递给calculateSubtotal函数,然后将结果相加。然后,将此总计插入到发票的相关位置。

<code class="language-html"><tr> class="item">
  <td><input type="text" v-model="item.description"></td>
  <td><input type="number" v-model="item.price"></td>
  <td><input type="number" v-model="item.quantity"></td>
  <td>
<pre class="brush:php;toolbar:false"><code class="language-javascript">$('table').on('mouseup keyup', 'input[type=number]', calculateTotals);</code>
.00

在上面的代码中,我们获取对行中所有输入元素的引用,并将第二个和第三个相乘以获得小计。然后,将此值插入到行中的最后一个单元格中。

<code class="language-javascript">function calculateTotals() {
  const subtotals = $('.item').map((idx, val) => calculateSubtotal(val)).get();
  const total = subtotals.reduce((a, v) => a + Number(v), 0);
  $('.total td:eq(1)').text(formatAsCurrency(total));
}</code>

我们还有一个辅助函数,用于确保小计和总计都格式化为两位小数,并在前面加上货币符号。

<code class="language-javascript">function calculateSubtotal(row) {
  const $row = $(row);
  const inputs = $row.find('input');
  const subtotal = inputs[1].value * inputs[2].value;

  $row.find('td:last').text(formatAsCurrency(subtotal));

  return subtotal;
}</code>

最后,我们有一个“添加行”按钮的点击处理程序。我们在这里所做的是选择最后一个项目行并创建一个副本。克隆行的输入设置为默认值,并将其插入为新的最后一行。我们还可以为用户提供便利,并将焦点设置到第一个输入,以便他们可以开始键入。

以下是完整的jQuery演示:CodePen链接

jQuery的缺点

那么,这段代码有什么问题呢?或者说,什么地方可以改进?

您可能听说过Vue和React等一些较新的库声称是声明式的而不是命令式的。当然,查看这段jQuery代码,大部分代码都是关于如何操作DOM的指令列表。每一部分代码的目的——“是什么”——往往很难通过“怎么做”的细节来分辨出来。当然,我们可以通过将其分解成命名良好的函数来阐明代码的意图,但这段代码仍然需要一些努力才能在一段时间后重新理解。

此类代码的另一个问题是,我们将应用程序状态保存在DOM本身中。订购项目的相关信息仅作为构成UI的HTML的一部分存在。当我们只在一个位置显示信息时,这似乎不是什么大问题,但是一旦我们开始需要在应用程序中的多个位置显示相同的数据,确保每个部分保持同步就会变得越来越复杂。没有单一的事实来源。

虽然没有什么可以阻止我们不将状态保存在DOM之外并避免这些问题,但像Vue这样的库提供了促进创建良好架构和编写更简洁、更模块化代码的功能和结构。

转换为Vue

那么,我们如何使用Vue来重现此功能呢?

正如我前面提到的,Vue不需要我们使用模块打包器、转译器或选择单文件组件(.vue文件)来开始使用。像jQuery一样,我们可以简单地从CDN包含库。让我们从替换script标签开始:

<code class="language-javascript">function formatAsCurrency(amount) {
  return `$${Number(amount).toFixed(2)}`;
}</code>

接下来,我们需要创建一个新的Vue实例:

<code class="language-javascript">$('.btn-add-row').on('click', () => {
  const $lastRow = $('.item:last');
  const $newRow = $lastRow.clone();

  $newRow.find('input').val('');
  $newRow.find('td:last').text('<pre class="brush:php;toolbar:false"><code class="language-html"></code>
.00'); $newRow.insertAfter($lastRow); $newRow.find('input:first').focus(); });

这里我们只需要提供el选项,它是一个选择器(就像我们使用jQuery一样),用于标识我们想要Vue管理的文档的哪个部分。

我们可以让Vue负责从整个页面(例如,对于单页应用程序)或单个

开始的任何内容。对于我们的发票示例,我们将让Vue控制HTML表格。

数据

让我们还将三个示例行的相关数据添加到我们的Vue实例中:

<code class="language-html"><tr> class="item">
  <td><input type="text" v-model="item.description"></td>
  <td><input type="number" v-model="item.price"></td>
  <td><input type="number" v-model="item.quantity"></td>
  <td>
<pre class="brush:php;toolbar:false"><code class="language-javascript">$('table').on('mouseup keyup', 'input[type=number]', calculateTotals);</code>
.00

data属性是我们在其中存储应用程序状态的地方。这不仅包括我们希望应用程序使用的任何数据,还包括有关UI状态的信息(例如,选项卡组中当前活动的部分,或者手风琴是展开还是折叠)。

Vue鼓励我们将应用程序的状态与它的表示(即DOM)分开,并集中在一个地方——单一的事实来源。

修改模板

现在让我们设置我们的模板来显示来自我们data对象中的项目。因为我们已经告诉Vue我们希望它控制表格,所以我们可以在HTML中使用它的模板语法来告诉Vue如何渲染和操作它。

使用v-for属性,我们可以为items数组中的每个项目渲染一段HTML:

<code class="language-javascript">function calculateTotals() {
  const subtotals = $('.item').map((idx, val) => calculateSubtotal(val)).get();
  const total = subtotals.reduce((a, v) => a + Number(v), 0);
  $('.total td:eq(1)').text(formatAsCurrency(total));
}</code>

Vue将为我们传递给v-for构造的数组(或对象)的每个元素重复此标记,允许我们在循环中引用每个元素——在本例中为item。由于Vue正在观察data对象的所有属性,因此它将随着items内容的变化而动态地重新渲染标记。我们只需向应用程序状态添加或删除项目,Vue就会负责更新UI。

我们还需要添加输入框,以便用户填写项目的描述、单价和数量:

<code class="language-javascript">function calculateSubtotal(row) {
  const $row = $(row);
  const inputs = $row.find('input');
  const subtotal = inputs[1].value * inputs[2].value;

  $row.find('td:last').text(formatAsCurrency(subtotal));

  return subtotal;
}</code>

在这里,我们使用v-model属性来设置输入和项目模型上的属性之间的双向绑定。这意味着对输入的任何更改都将更新项目模型上的相应属性,反之亦然。

在最后一个单元格中,我们使用双大括号{{ }}来输出一些文本。我们可以在大括号内使用任何有效的JavaScript表达式,因此我们将两个项目属性相乘并输出结果。同样,由于Vue正在观察我们的数据模型,因此对任一属性的更改都将导致表达式自动重新计算。

事件和方法

现在我们已经设置好模板来渲染我们的items集合,但是我们如何添加新行呢?由于Vue将渲染items中的任何内容,因此要渲染空行,我们只需要将具有我们想要的任何默认值的对象推送到items数组中即可。

要创建可以在模板中访问的函数,我们需要将它们作为methods对象的属性传递给我们的Vue实例:

<code class="language-javascript">function formatAsCurrency(amount) {
  return `$${Number(amount).toFixed(2)}`;
}</code>

让我们定义一个addRow方法,我们可以调用它来向我们的items数组添加新项目:

<code class="language-javascript">$('.btn-add-row').on('click', () => {
  const $lastRow = $('.item:last');
  const $newRow = $lastRow.clone();

  $newRow.find('input').val('');
  $newRow.find('td:last').text('<pre class="brush:php;toolbar:false"><code class="language-html"></code>
.00'); $newRow.insertAfter($lastRow); $newRow.find('input:first').focus(); });

请注意,我们创建的任何方法都会自动绑定到Vue实例本身,因此我们可以访问data对象中的属性和其他方法,作为this的属性。

那么,现在我们有了方法,如何在点击“添加行”按钮时调用它呢?在模板中向元素添加事件监听器的语法是v-on:event-name:

<code class="language-javascript">const app = new Vue({
  el: 'table'
});</code>

Vue还为我们提供了一个快捷方式,以便我们可以使用@代替v-on:,就像我在上面的代码中所做的那样。对于处理程序,我们可以指定Vue实例中的任何方法。

计算属性

现在我们只需要在发票底部显示总计即可。我们可能可以在模板本身中做到这一点:正如我前面提到的,Vue允许我们在花括号之间放置任何JavaScript语句。但是,最好将任何超过非常基本的逻辑的内容都保留在模板之外;如果我们将逻辑分开,则更清晰且更容易测试。

我们可以为此使用另一个方法,但我认为计算属性更合适。与创建方法类似,我们将一个包含函数的computed对象传递给我们的Vue实例,我们希望在模板中使用这些函数的结果:

<code class="language-html"><tr> class="item">
  <td><input type="text" v-model="item.description"></td>
  <td><input type="number" v-model="item.price"></td>
  <td><input type="number" v-model="item.quantity"></td>
  <td>
<pre class="brush:php;toolbar:false"><code class="language-javascript">$('table').on('mouseup keyup', 'input[type=number]', calculateTotals);</code>
.00

现在我们可以在模板中引用此计算属性:

<code class="language-javascript">function calculateTotals() {
  const subtotals = $('.item').map((idx, val) => calculateSubtotal(val)).get();
  const total = subtotals.reduce((a, v) => a + Number(v), 0);
  $('.total td:eq(1)').text(formatAsCurrency(total));
}</code>

正如您可能已经注意到的那样,计算属性可以像数据一样对待;我们不必用括号调用它们。但是使用计算属性还有另一个好处:Vue足够聪明,可以缓存返回值,并且只有当它依赖的数据属性之一发生更改时,才会重新计算该函数。

如果我们使用方法来计算总计,则每次重新渲染模板时都会执行计算。因为我们使用的是计算属性,所以只有在项目的数量或价格字段发生更改时才会重新计算总计。

过滤器

您可能已经发现我们的实现中存在一个小错误。虽然单位成本是整数,但我们的总计和小计显示时没有显示美分。我们真正想要的是始终将这些数字显示为两位小数。

与其修改计算小计和计算总计的代码,Vue为我们提供了一种处理此类常见格式化任务的好方法:过滤器。

正如您可能已经猜到的那样,要创建过滤器,我们只需将具有该键的对象传递给我们的Vue实例:

<code class="language-javascript">function calculateSubtotal(row) {
  const $row = $(row);
  const inputs = $row.find('input');
  const subtotal = inputs[1].value * inputs[2].value;

  $row.find('td:last').text(formatAsCurrency(subtotal));

  return subtotal;
}</code>

在这里,我们创建了一个非常简单的名为currency的过滤器,它调用value.toFixed(2)并返回结果。我们可以将其应用于模板中的任何输出,如下所示:

<code class="language-javascript">function formatAsCurrency(amount) {
  return `$${Number(amount).toFixed(2)}`;
}</code>

以下是完整的Vue演示:CodePen链接

总结

将两个版本的代码并排比较,Vue应用程序的几个方面很突出:

  • UI与驱动它的逻辑/数据之间的清晰分离:代码更容易理解,并且更容易测试。
  • UI是声明式的:您只需要关心您想看到的内容,而无需关注如何操作DOM来实现它。

两个库的大小(以KB为单位)几乎相同。当然,您可以通过自定义构建来精简jQuery,但是即使对于像我们的发票示例这样的相对简单的项目,我认为开发的便捷性和代码的可读性也证明了这种差异是合理的。

Vue还可以做很多我们在这里没有介绍的事情。它的优势在于允许您创建模块化、可重用的UI组件,这些组件可以组合成复杂的frontend应用程序。如果您有兴趣深入了解Vue,我建议您查看《Getting Up and Running with the Vue.js 2.0 Framework》。

关于用Vue替换jQuery的常见问题解答(FAQs)

jQuery和Vue.js的主要区别是什么?

jQuery是一个快速、小巧且功能丰富的JavaScript库。它使HTML文档遍历和操作、事件处理和动画等操作更加简单,它易于使用的API可在多种浏览器中运行。另一方面,Vue.js是一个用于构建用户界面的渐进式JavaScript框架。与其他整体框架不同,Vue的设计从一开始就具有增量可采用性。核心库仅关注视图层,易于上手并与其他库或现有项目集成。

为什么我应该考虑用Vue.js替换jQuery?

虽然jQuery多年来一直是一个可靠的工具,但Vue.js提供了一种更现代、更全面的构建Web应用程序的方法。Vue.js是基于组件的,这促进了可重用性和可维护性。它还有一个更强大的生态系统,具有状态管理、路由等工具。此外,Vue.js具有虚拟DOM,在某些情况下可以提高性能。

如何将jQuery代码转换为Vue.js?

将jQuery代码转换为Vue.js需要了解jQuery函数的等效Vue.js方法和属性。例如,您将使用Vue的mounted()生命周期钩子来代替jQuery的$(document).ready()。类似地,您将使用Vue的axios或fetch来代替jQuery的$.ajax()来进行HTTP请求。

我可以在一个项目中同时使用jQuery和Vue.js吗?

虽然从技术上讲可以同时使用jQuery和Vue.js,但通常不建议这样做。混合使用两者可能会导致代码混乱和潜在冲突,因为这两个库都试图以自己的方式管理DOM。最好完全使用其中一个。

如何在Vue.js中处理事件,与jQuery相比?

在jQuery中,您通常使用.click()、.on()或.bind()等方法将事件监听器附加到元素。在Vue.js中,您使用v-on指令(或其简写@)来监听DOM事件并在触发时运行一些JavaScript。

Vue.js中的数据绑定与jQuery相比如何工作?

jQuery没有内置的数据绑定。您手动选择元素并更新其内容。相反,Vue.js具有强大的数据绑定系统。您可以使用v-model指令在表单输入、textarea和select元素上创建双向数据绑定。

如何在Vue.js中动画元素,与jQuery相比?

jQuery具有内置的动画方法,如.fadeIn()、.slideUp()等。另一方面,Vue.js提供转换组件,在将元素动画进出DOM时允许更大的灵活性。

如何在Vue.js中发出HTTP请求,与jQuery相比?

在jQuery中,您通常使用$.ajax()方法发出HTTP请求。Vue.js没有内置的此方法,但是您可以使用现代API(如fetch)或axios等库来发出HTTP请求。

Vue.js如何处理反应性,与jQuery相比?

jQuery没有内置的反应性系统。当您的数据更改时,您会手动更新DOM。另一方面,Vue.js具有反应性数据系统。当您更改数据时,视图会自动更新。

如何用Vue.js组件替换jQuery插件?

许多jQuery插件都可以用Vue.js组件替换。Vue.js拥有丰富的生态系统,提供了数千个可用的开源组件。您还可以创建自己的自定义组件。这提高了代码的可重用性和可维护性。

请注意,我已根据您的要求对输出进行了改写,并保留了所有图片的原始格式和位置。 由于我没有访问CodePen,我无法提供实际的CodePen链接,请您自行创建并替换“[CodePen链接]”占位符。

以上是如何用vue替换jQuery的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn