Vue响应式编程

Time: 20190911

到本篇文章为止,我们在前面的文章中学习了如何将JS中的数据传到HTML模板中,最终转化为DOM在浏览器显示。

Vue在这个过程中扮演了怎样的角色呢?

Vue会时刻监视着data对象的变化。下面看一个例子:


<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Documenttitle>
    <script src="https://cdn.jsdelivr.net/npm/vue">script>
    
head>
<body>
    <div id="app">
        <p>自从打开网页,已经过去{{ seconds }}秒。p>
    div>

    <script>
        var app = new Vue(
            {
                el: '#app',
                data: {
                    seconds: 0
                },

                created() {
                    // 应用启动时执行
                    console.log("应用启动...")
                    setInterval(() => {
                        this.seconds++
                    }, 1000)
                }
            }
        )
    script>
body>
html>

执行效果

就是个网页计数器,每一秒数字变化一次。

这里用到了created生命周期钩子函数,这也是Vue框架的核心内容,会在后面继续展开。this.seconds会指向data对象中的变量,改变这个变量,相应的模板也会变化。

非常简洁的语法。

到目前为止,写Vue的代码都给人一种非常灵活的感觉。

上面这个例子展示的是Vue的响应式能力,用的是数值,也可以对v-bind的属性进行操作:


<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Documenttitle>
    <script src="https://cdn.jsdelivr.net/npm/vue">script>
    
head>
<body>
    <div id="app">
        <p>自从打开网页,已经过去{{ seconds }}秒。p>
        <button :disabled="buttonDisabled">测试按钮button>
    div>

    <script>
        var app = new Vue(
            {
                el: '#app',
                data: {
                    seconds: 0,
                    buttonDisabled: true
                },

                created() {
                    // 应用启动时执行
                    console.log("应用启动...")
                    setInterval(() => {
                        this.seconds++,
                        this.buttonDisabled = !this.buttonDisabled
                    }, 1000)
                }
            }
        )
    script>
body>
html>

效果如下:

Vue响应式编程_第1张图片

Vue响应式编程_第2张图片
按钮在可用和不可用之间一秒一次切换。

到这里为止,应该可以感受到响应式的能力。响应式的实现原理是怎样的呢?后续会发一篇深入理解响应式实现原理的文章,先留空。

响应式的限制

为对象添加新的属性,并不是响应式的

const vm = new Vue({
	data: {
		formData: {
			username: 'xxx'
		}
	}
})
vm.formData.name = 'new user'

原先定义的username是响应式的,即该属性的变化会触发模板更新。

新定义的不是响应式的。

有什么解决办法呢?主要有三种:

  • 第一种:预先为name留个位置,就像我上面为要写的文章留个空一样,设置为undefined,等到后面想用的时候,直接修改即可,反正它一直都是响应式的。

但往未来预先定义一步,并不是那么冗余的,这牵涉到预测未来了。

  • 第二种:用Object.assign()创建新的对象以覆盖原来的对象。
vm.formData = Object.assign({}, vm.formData, {name: 'new user'})
  • 第三种:Vue.set()方法,可以将属性值设置为响应式的
Vue.set(vm.formData, 'name', 'new user')

关于设置数组元素

直接按照下标索引修改是不可行的(??)。

const vm = new Vue({
	data: {
		dogs: ['Rex', 'Rover', 'Alan'
	}
})

vm.dogs[2] = 'Bob' // 错误

改进的方式有两种:

  • .splice()函数, vm.dogs.splice(2,1, 'Bob')
  • Vue.set()函数,Vue.set(vm.dogs, 2, 'Bob')

两种方法效果相同。

设置数组长度

也是用.splice()函数,不过这个方法只能用于缩短长度,不能扩展长度。

END.

你可能感兴趣的:(Vue.js)