用 Vue.js 替换 jQuery:无需构建步骤
已发表: 2022-03-10最近围绕 JavaScript 框架的所有炒作是不可能忽略的,但它们可能不适合您的项目。 也许你不想为一些你可以不用的小抽象建立一个完整的构建系统。 也许将项目转移到构建系统,因此,不同的部署方法将意味着您可能无法向客户收费的大量额外时间和精力。 也许您不想用 JavaScript 编写所有 HTML。 名单还在继续。
有些人可能不知道的是,您可以像合并 jQuery 一样将 Vue 合并到您的项目中,而无需构建步骤。 Vue 是灵活的,因为我们可以直接在 HTML 中使用它。
因此,如果您当前的页面结构如下所示:
<main> <div class="thing"> <p>Some content here</p> </div> </main> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <script> //some jquery code here </script>
您可以在这里更改脚本标记,并且仍然像以前一样串联使用 HTML 和 JS,只重构少量代码。 不必用 JavaScript 重写 HTML,不必使用 webpack,也不必搭建庞大的系统:
<main> <div class="thing"> <p>Some content here</p> </div> </main> <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.min.js"></script> <script> //some vue code here </script>
您可以替换标签并保持原样。 最好的部分是,您可能会认为代码会变得更加复杂,但在阅读本文并查看示例时,您可能会发现 Vue 非常简单、易读且易于维护和适应。 就大小而言,它们也相当可比——使用它们就像来自 CDN、缩小、Vue 版本 2.5.3 是86KB 。 jQuery 3.2.1 是87KB 。
让我们介绍一下 jQuery 中的一些常见用例,以及我们如何将它们切换到 Vue,以及我们甚至想要这样做的原因。
捕获用户输入
在网站上需要 JavaScript 的一个非常常见的用例是从表单中捕获用户输入,所以让我们从那里开始。 为了简单和清晰起见,我们实际上不会合并完整的表格,但我们会在最后完成它。
为了在用户类型中捕获信息,下面是我们在 jQuery 和 Vue 中如何做到这一点——并排:
<div> <label for="thing">Name:</label> <input type="text" /> <p class="formname"></p> </div>
// this is an alias to $(document).ready(function() { $(function() { //keypress wouldn't include delete key, keyup does. We also query the div id app and find the other elements so that we can reduce lookups $('#app').keyup(function(e) { var formname = $(this).find('.formname'); //store in a variable to reduce repetition var n_input = $(this).find('#thing').val(); formname.empty(); formname.append(n_input); }); });
<div> <label for="name">Name:</label> <input type="text" v-model="name" /> <!--v-model is doing the magic here--> <p>{{ name }}</p> </div>
//this is a vue instance new Vue({ //this targets the div id app el: '#app', data: { name: '' //this stores data values for 'name' } })
我使用这个例子是因为它揭示了 Vue 的一些优势。 Vue 是响应式的,这使得它特别能够响应变化。 你可以看到,当我们更新我们输入的内容时,它会立即改变——没有延迟。
您还可以看到,在 jQuery 版本中,DOM 处于控制之中——我们从 DOM 中获取内容、监听它并响应它。 这将我们与当前设置 DOM 的方式联系在一起,并迫使我们考虑如何遍历它。 如果要更改 HTML 元素的结构,我们必须调整代码以适应这些更改。
在 Vue 版本中,我们存储状态——我们跟踪一个我们想要更新和更改的属性,并通过一个称为指令的东西跟踪我们想要更改的元素。 这意味着它直接附加到我们需要定位的 HTML 元素上。 DOM 的结构可以改变,HTML 可以移动,这些都不会影响我们的性能或捕获这些事件。 在我们的例子中,我们使用输入上的 v-model 属性来连接到我们存储在 JavaScript 中的数据。
但! 这不像按回车键存储东西那样常见的用例,所以让我们接下来看看。
在单个事件上存储用户输入
Vue 工作方式的有趣之处在于,它无需在存储和检索数据时考虑特定的 DOM 事件。 本质上,我们已经知道我们想要捕捉什么; 我们通过选择一个用来改变它的事件来赋予它形状。 相比之下,jQuery 与 DOM 所做的事情紧密耦合,并依赖于那些 DOM 事件来构建它存储的变量,这些变量可以放置在任何地方,而不是一个一致的组(在数据中)进行检索。 我们可以在上一个示例的更新版本中看到这一点,其中信息是通过 Enter 键收集的:
<div> <label for="thing">Name:</label> <input type="text" /> <p class="formname"></p> </div>
// this is an alias to $(document).ready(function() { $(function() { //We query the div id app and find the other elements so that we can reduce lookups $('#app').change(function(e) { var n_input = $(this).find('#thing').val(); $(this).find('.formname').append(n_input); }); });
<div> <label for="name">Name:</label> <input type="text" v-model.lazy="name" /> <p>{{ name }}</p> </div>
new Vue({ el: '#app', data: { name: '' } });
在这个版本中,jQuery 稍微简化了一些,因为我们不必在每次击键时都捕捉内容,但我们仍在从 DOM 中提取内容并逐步响应这些变化。 我们在 jQuery 中的代码总是有点像这样:
“去获取这个元素,看看它在做什么,坚持这些变化,对这些变化做点什么。”
相比之下:在 Vue 中,我们可以控制正在发生的变化,并且 DOM 根据我们的命令响应这些变化。 我们将它直接附加到我们想要更新的东西上。 在我们的例子中,我们有一个称为修饰符的小抽象: v-model.lazy
。 Vue 现在知道在更改事件发生之前不要开始存储它。 很简约!
切换类
我们将介绍的下一件事是切换 CSS 类,因为正如万能的、经常观看的 Googly 告诉我的那样,它是最常见的 jQuery 功能。
<div> <button aria-pressed="false">Toggle me</button> <p class="toggle">Sometimes I need to be styled differently</p> </div>
.red { color: red; } JS $(function() { $('button').click(function(e) { $('.toggle').toggleClass('red'); $(this).attr('aria-pressed', ($(this).attr('aria-pressed') == "false" ? true : false)); }); });
<div> <button @click="active = !active" :aria-pressed="active ? 'true' : 'false'">Toggle me</button> <p :class="{ red: active }">Sometimes I need to be styled differently</p> </div>
.red { color: red; } JS new Vue({ el: '#app', data: { active: false } })
同样,我们在这里看到的是,在 jQuery 版本中,我们将状态存储在 DOM 中。 该元素具有类,jQuery 根据类的存在做出决定,它通过 ping DOM 来检查。 在 Vue 版本中,我们存储一个条件,并根据该状态对其进行样式设置。 我们不是向 DOM 询问这些信息,我们自己持有它。
我们将active
存储在数据中,按钮切换条件, .red
根据该条件进行更改。 甚至可访问性的状态aria-pressed
的表述也更快,因为我们不必在 Vue 的脚本中设置任何内容,我们可以根据 ' active
的状态直接在模板中内联的状态之间切换。
您还会注意到,在最后几个示例中,您可能认为开始使用 Vue.js 比使用 jQuery 需要更多的代码,但它们实际上相当可比。
隐藏和显示
另一个常见的 jQuery 用例是隐藏和显示某些东西。 jQuery 在使这项任务变得非常简单方面一直做得非常好,所以让我们来看看它与 Vue 并排的样子。
<div> <button type="button" aria-expanded="false"> Toggle Panel </button> <p class="hello">hello</p> </div>
$(function() { $('#toggle').on('click', function() { $('.hello').toggle(); $(this).attr('aria-expanded', ($(this).attr('aria-expanded') == "false" ? true : false)); }); });
<div> <button @click="show = !show" :aria-expanded="show ? 'true' : 'false'"> Toggle Panel </button> <p v-if="show">hello</p> </div>
new Vue({ el: '#app', data: { show: true } })
jQuery 和 Vue 都很好地保持了这个任务的简单性,但有几个原因让我真正使用 Vue 来完成类似切换之类的事情。 Vue 有一个名为 Vue devtools 的工具。 这与 Chrome 开发工具没有什么不同,但是当我们使用它时,我们会得到一些关于 Vue 发生了什么的特殊信息。
在 jQuery 和 Vue 版本中,我们可以看到元素隐藏和出现。 但是,如果出现问题怎么办? 如果我们的代码没有按照我们预期的方式工作怎么办? 为了开始使用 jQuery 进行调试,我们可能会添加一些console.log
或设置一些断点来尝试追踪出错的地方。
现在, console.log
没有什么问题,但是在 Vue 开发工具的帮助下,我们实际上可以亲身体验 Vue(无法抗拒)Vue 认为正在发生的事情。 在下面的这个 gif 中,你可以看到当我们切换按钮时,Vue 开发工具会相应地更新 true/false 的状态。 如果 DOM 没有按照我们预期的方式工作,我们可以在 Vue 中实时查看数据。 这使得调试变得容易得多; 它实际上非常棒。
我喜欢的另一件事是v-if
很容易扩展到其他条件。 如果我切换的东西会频繁显示和隐藏,我可以决定使用一个叫做v-show
的东西而不是v-if
: v-if
将完全卸载元素,而v-show
只会切换它的可见性。 这种区别非常重要,因为在样式中切换可见性而不是完全卸载/安装 DOM 节点的性能要高得多。 我可以根据很多条件显示或隐藏某些内容,甚至是用户输入或其他条件的存在。 这通常是 jQuery 可能会有点混乱的地方,它在多个位置 ping DOM 并协调它们。 以下是基于用户输入的存在协调显示某些内容的示例:
<div> <label for="textarea">What is your favorite kind of taco?</label> <textarea v-model="tacos"></textarea> <br> <button v-show="tacos">Let us know!</button> </div>
new Vue({ el: '#app', data() { return { tacos: '' } } })
<div> <label for="textarea">What is your favorite kind of taco?</label> <textarea></textarea> <br> <button v-show="tacos">Let us know!</button> </div>
$(function() { var button = $('.button'); var textarea = $('#textarea'); button.hide(); textarea.keyup(function() { if (textarea.val().length > 0) { button.show(); } else { button.hide(); } }) });
在这个例子中,你可以看到让 Vue 保持状态的价值——我们对变化的反应非常自然,而且代码更少。 一旦习惯了这种风格,理解起来会更快,因为您不必逐行跟踪逻辑。 很多人称这种差异为“命令式与声明式”。
提交表格
jQuery 的规范用例历来是通过 AJAX 调用提交表单,所以我们也应该看看它。 Vue 实际上并没有像 AJAX 这样的内置东西; 在 Vue 应用程序中,通常使用 Axios(用于发出 HTTP 请求的 JavaScript 库)之类的东西来帮助完成此任务。
这个例子比其他例子稍微复杂一些。 我们将在这里做一些事情:
- 在我们开始输入表单之前,该按钮将显示为灰色,然后它将接收一个“活动”类并变为蓝色;
- 当我们提交表单时,我们会阻止页面加载;
- 提交表单后,我们将在页面上显示响应数据。
<div> <form action="/"> <div> <label for="name">Name:</label><br> <input type="text" name="name" required/> </div> <div> <label for="email">Email:</label><br> <input type="email" name="email" required/> </div> <div> <label for="caps">HOW DO I TURN OFF CAPS LOCK:</label><br> <textarea name="caps" required></textarea> </div> <button class="submit" type="submit">Submit</button> <div> <h3>Response from server:</h3> <pre class="response"></pre> </div> </form> </div>
$(function() { var button = $("button"); var name = $("input[name=name]"); name.keyup(function() { if (name.val().length > 0) { button.addClass('active'); } else { button.removeClass('active'); } }); $("form").submit(function(event) { event.preventDefault(); //get the form data var formData = { name: $("input[name=name]").val(), email: $("input[name=email]").val(), caps: $("input[name=caps]").val() }; // process the form $.ajax({ type: "POST", url: "//jsonplaceholder.typicode.com/posts", data: formData, dataType: "json", encode: true }).done(function(data) { $(".response") .empty() .append(JSON.stringify(data, null, 2)); }); }); });
在这里,我们将看到第 2-10 行处理按钮类的处理,类似于我们之前的处理方式。 我们将一个名为 event 的参数传递给表单,然后说event.preventDefault()
以防止重新加载页面。 然后我们从表单输入中收集所有表单数据,处理表单,然后将响应放入来自 AJAX 请求的.done()
调用中。
<div> <form @submit.prevent="submitForm"> <div> <label for="name">Name:</label><br> <input type="text" v-model="name" required/> </div> <div> <label for="email">Email:</label><br> <input type="email" v-model="email" required/> </div> <div> <label for="caps">HOW DO I TURN OFF CAPS LOCK:</label><br> <textarea v-model="caps" required></textarea> </div> <button :class="[name ? activeClass : '']" type="submit">Submit</button> <div> <h3>Response from server:</h3> <pre>{{ response }}</pre> </div> </form> </div>
new Vue({ el: '#app', data() { return { name: '', email: '', caps: '', response: '', activeClass: 'active' } }, methods: { submitForm() { axios.post('//jsonplaceholder.typicode.com/posts', { name: this.name, email: this.email, caps: this.caps }).then(response => { this.response = JSON.stringify(response, null, 2) }) } } })
在 Vue 版本中,我们决定需要在表单中填充哪些字段,然后将它们与我们之前使用的 v-model 附加在一起。 我们检查名称是否存在以切换类。 无需传入事件并编写event.preventDefault()
,我们所要做的就是在我们的表单元素上编写@submit.prevent
,这已经为我们处理好了。 要提交帖子本身,我们使用 Axios,我们会将响应存储在 Vue 实例中作为响应。
我们仍然需要做很多事情来获得生产就绪的表单,包括验证、错误处理和编写测试,但是在这个小例子中,您可以看到 Vue 在处理大量事物更新和变化,包括用户输入。
结论
如果适合你,使用 jQuery 绝对没问题! 本文旨在展示 Vue 对于不需要大量开销的小型站点也是一个非常好的抽象。 Vue 在大小上相当,易于推理,并且如果您没有带宽,无需在 JavaScript 中重写您的 HTML 并采用构建系统,将小部分功能切换到 Vue 是相当简单的。 这一切都让人不得不考虑。
由于 Vue 的灵活性,如果您想随着时间的推移采用更复杂的结构,也很容易将此代码转换为构建步骤和组件结构。 尝试它实际上很有趣,所以当你准备好这样做时,请查看 vue-cli。 这个工具的作用是让你能够用几个终端命令搭建整个生产级的 Vue 和 webpack 构建。 这使您可以使用单文件组件,您可以在一个文件中串联使用 HTML、CSS 和脚本,从而构成单个可重用组件。 除非您想做一些特别的事情,否则您不必配置 webpack 构建,因此您可以节省大量设置时间。 他们甚至有一个内置命令来为生产部署做好一切准备。
灵活地选择将 Vue 合并到您的项目中的任何一种方式的好处意味着您不必一次改变工作风格,甚至可以随着时间的推移慢慢做出改变。 这就是为什么人们称 Vue 为渐进式框架的原因。