Vue 进阶之路(三)
之前的文章我们已经对 vue 有了初步认识,这篇文章我们通过一个例子说一下 vue 的方法 methods,计算属性 computed 和监听器 watch。
现在我们有一个需求,变量 firstName = "hello",变量 lastName = "world",我们需要将这两个变量拼接到在前端展示,最基本的我们可以想到的就是:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>vue</title>
- <script src="https://cdn.jsdelivr.net/npm/vue"></script>
- </head>
- <body>
- <div id="app">
- <p>{{firstName + " " + lastName}}</p>
- <p>{{firstName}} {{lastName}}</p>
- </div>
- <script>
- var app = new Vue({
- el: '#app',
- data: {
- firstName: 'hello',
- lastName: 'world',
- },
- })
- </script>
- </body>
- </html>
以上两种写法很明显是可以这么做的,但是第一种我们在 {{ }} 插值表达式内进行了代码的计算,这是我们不建议使用方式,第二种是写两个 {{ }} 插值表达式,看起来效果不错,但是如果我们要再拼接多个的话在 HTML 代码中就显得冗余了,后期也不好维护。接下来我们看一下如何在方法内实现:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>vue</title>
- <script src="https://cdn.jsdelivr.net/npm/vue"></script>
- </head>
- <body>
- <div id="app">
- <p>{{fullName()}} {{time}}</p>
- </div>
- <script>
- var app = new Vue({
- el: '#app',
- data: {
- firstName: 'hello',
- lastName: 'world',
- time: 1
- },
- methods:{
- fullName(){
- console.log("计算了一次");
- return this.firstName + " " + this.lastName
- }
- }
- })
- </script>
- </body>
- </html>
上面的代码我们在 methods 里定义了一个 fullName 的方法,然后通过 {{ }} 插值表达式放在 HTML 里,当页面加载的时候直接调用,运行结果如下:
我们在页面加载的时候同时定义了一个 time 的数据,当我们更新这个 time 数据的时候,结果如下:
我们发现当我们更新 time 数据的时候,fullName 方法也调用了一次。这显然不是很理想的。
我们再来看一下利用监听器 watch 方法:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>vue</title>
- <script src="https://cdn.jsdelivr.net/npm/vue"></script>
- </head>
- <body>
- <div id="app">
- <p>{{fullName}} {{time}}</p>
- </div>
- <script>
- var app = new Vue({
- el: '#app',
- data: {
- firstName: 'hello',
- lastName: 'world',
- fullName: 'hello world',
- time: 1
- },
- watch: {
- firstName() {
- console.log("firstName 更改了");
- this.fullName = this.firstName + " " + this.lastName;
- },
- lastName() {
- console.log("lastName 更改了");
- this.fullName = this.firstName + " " + this.lastName;
- }
- }
- })
- </script>
- </body>
- </html>
结果如下:
我们在 Vue 实例的 watch 属性里定义了两个方法 firstName 和 lastName,watch 属性中方法名和 data 属性里的数据变量名相同,表示会实时监听该数据的变化,如果监听到变化时会实时更新 DOM。
我们先来看一下当跟 methods 方法那样更新 time 数据时的变化:
我们可以看出当 time 数据更新时并没有调用 firstName 和 lastName 里的数据。当我们更新 firstName 和 lastName 的数据时,结果如下:
我们可以看出当我们更新 firstName 或者 lastName 的数据时,fullName 数据才会更新,这说明当数据挂载到 DOM 上的时候会缓存起来,如果数据不更新,则还会继续使用缓存的数据,当数据更新时才会调用 watch 里面的方法,这就比 methods 的方法要好很多。
我们再来看一下计算属性 computed:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>vue</title>
- <script src="https://cdn.jsdelivr.net/npm/vue"></script>
- </head>
- <body>
- <div id="app">
- <p>{{fullName}} {{time}}</p>
- </div>
- <script>
- var app = new Vue({
- el: '#app',
- data: {
- firstName: 'hello',
- lastName: 'world',
- time: 1
- },
- computed:{
- fullName(){
- console.log("计算了一次");
- return this.firstName + " " + this.lastName;
- }
- }
- })
- </script>
- </body>
- </html>
运行结果如下:
我们可以看出跟 watch 比,我们并没有在 data 里定义 fullName 数据,而是在 computed 属性里直接定义 fullName 然后 return 出 firstName 和 lastName 的拼接结果,当页面呈现时,从输出结果可以看出会走一次计算属性,当我们改变 time 数据时:
可以看出 computed 里的方法没有被调用,当我们改变 firstName 或者 lastName 的数据时,结果如下:
从上面的结果可以看出 computed 里面的方法被调用了,这是我们想要的结果,当跟 fullName 有关的 firstName 和 lastName 数据改变时计算属性才会重新计算,当跟 fullName 无关的 time 数据变化时会用之前缓存的数据,这正是我们想要的结果。
以上三种方法进行比较我们可以得知 methods 方法是最不理想的,监听器 watch 和 计算属性 computed 两种方法的运行结果是一样的,但是 计算属性 computed 方法更简单一些。所以在 watch 和 computed 两种方法都能实现的时候我们更推荐使用 computed 方法。
但是上面的 watch 和 computed 两个方法里有个问题,就是 watch 里我们在 data 里定义了一个 fullName 的数据,当我们在更改 fullName 的值时 DOM 会跟着改变,这个跟 firstName 和 lastName 数据更改是一样的。但是当我们在 computed 里我们并没有定义 fullName,当我们更改 fullName 的数据时,如下:
我们发现 DOM 并没有更新,这跟 watch 比起来就显得不友好了,其实在 computed 里有 get 和 set 两个属性,我们 computed 的 fullName 方法改成如下:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>vue</title>
- <script src="https://cdn.jsdelivr.net/npm/vue"></script>
- </head>
- <body>
- <div id="app">
- <p>{{fullName}} {{time}}</p>
- </div>
- <script>
- var app = new Vue({
- el: '#app',
- data: {
- firstName: 'hello',
- lastName: 'world',
- time: 1
- },
- computed: {
- fullName: {
- get() {
- console.log("计算了一次");
- return this.firstName + " " + this.lastName;
- },
- set(value) {
- console.log(value);
- var result = value.split(" ");
- this.firstName = result[0];
- this.lastName = result[1];
- }
- }
- }
- })
- </script>
- </body>
- </html>
运行结果如下:
可以看出当我们通过 get 和 set 就可以改变 fullName 的值使 DOM 更新了。当页面更新的时候先触发 fullName 中的 get 方法,并返回 fullName,当我们改变 time 时,fullName 所依赖的 firstName 和 lastName 并没有更改,所以就 fullName 就会去取缓存的值,在 fullName 的 set 方法里可以传一个 value 的参数,通过打印我们可以看出 value 值就是我们直接改变 fullName 的值,我们就可以通过该值来赋值改变 firstName 和 lastName,这样 fullName 所依赖的 firstName 或 lastName 改变时 DOM 就会实时更新了。
Vue 进阶之路(三)的更多相关文章
- Vue 进阶之路(九)
之前的文章我们介绍了 vue 中父组件之间的传值,本章我们再来看一下父子组件间传值的参数校验和非 Props 特性. <!DOCTYPE html> <html lang=" ...
- Vue 进阶之路(八)
之前的文章我们对组件 component 进行了简单的介绍,本章我们将深入了解一下组件,并实现父子组件间的传值. <!DOCTYPE html> <html lang="e ...
- Vue 进阶之路(七)
之前的文章我们对 vue 的列表输出做了介绍,本章我们来看一下 vue 的组件 component. <!DOCTYPE html> <html lang="en" ...
- Vue 进阶之路(六)
上篇文章我们分析了一下 vue 中的条件渲染,本篇我们说一下 vue 中的列表渲染和 set 方法. <!DOCTYPE html> <html lang="en" ...
- Vue 进阶之路(五)
之前的文章我们说了一下 vue 的样式绑定,这篇文章来介绍一下 vue 中的条件渲染,先看下面的代码: <!DOCTYPE html> <html lang="en&quo ...
- Vue 进阶之路(四)
之前的文章我们已经对 vue 有了初步认识,这篇文章我们通过一个例子说一下 vue 的样式绑定. 现在我们想要是想这样一个需求,页面上有个单词,当我们点击它的时候颜色变为红色,再点击一次变为原来的颜色 ...
- Vue 进阶之路(二)
之前的文章我们初识了 vue,对其原理,数据绑定和方法进行了简单的演示,本篇将对 vue 插值表达式,v-text,v-html 进行讲解. <!DOCTYPE html> <htm ...
- Vue 进阶之路(一)
vue 3.x 马上就要问世了,显然尤大大是不想让我们好好活了,但是转念一想,比你优秀的人都还在努力,那我们努力还有什么用,开个玩笑而已,本人对于 vue 的接触时间不长,对其也没有深入地去研究源码, ...
- Vue 进阶之路(十)
之前的文章介绍了 vue 的组件化,本章我们来看一下 vue 中组件的原生事件. <!DOCTYPE html> <html lang="en"> < ...
随机推荐
- Java 锁机制 synchronized
转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/75126630 本文出自[赵彦军的博客] 1.前言 在多线程并发编程中Synchro ...
- JSF-页面导航
页面导航 1)导航处理涉及的术语: -动作值:触发动作事件的组件的action:EL方法表达式.字符串文字. -结果值:动作组件的action属性的:EL方法表达式的返回值.字符串文字:或结果组件的o ...
- JS中$含义和用法
原博客:https://www.cnblogs.com/jokerjason/p/7404649.html$在JS中本身只是一个符号而异,在JS里什么也不是.但在JS应用库JQUERY的作者将之做为一 ...
- ScalaPB(3): gRPC streaming
接着上期讨论的gRPC unary服务我们跟着介绍gRPC streaming,包括: Server-Streaming, Client-Streaming及Bidirectional-Streami ...
- python 编码形式简单入门
为什么使用Python 假设我们有这么一项任务:简单测试局域网中的电脑是否连通.这些电脑的ip范围从192.168.0.101到192.168.0.200. 思路:用shell编程.(Linux通常是 ...
- 原生javascript写自己的运动库(匀速运动篇)
网上有很多JavaScript的运动库,这里和大家分享一下用原生JavaScript一步一步写一个运动函数的过程,如读者有更好的建议欢迎联系作者帮助优化完善代码.这个运动函数完成后,就可以用这个运动函 ...
- arcEngine开发之加载栅格数据
加载数据思路 在Engine中加载各种各样的数据都是通过这样的格式 IWorkspaceFactory pWorkspace = new IWorkspaceFactory(); IWorkspace ...
- PAT1037:Magic Coupon
1037. Magic Coupon (25) 时间限制 100 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue The magi ...
- 【转】spring cloud eureka 参数配置
eureka.client.registry-fetch-interval-seconds 表示eureka client间隔多久去拉取服务注册信息,默认为30秒,对于api-gateway,如果要迅 ...
- Nginx虚拟主机
[root@Nginx-server ~]# tar zxvf nginx-1.11.2.tar.gz [root@Nginx-server ~]# useradd -M -s /sbin/nolog ...