关于vue.js的学习官方文档里有教程

https://cn.vuejs.org/v2/guide/

赞一下vue.js的维护人员,我会按照官方的API里整合的目录分模块进行学习

本章内容是有关vue的数据处理,主要介绍data,computed,method,watch,有关props值传递,会单独开一章玩一下。ok,进入正题。(如对数据操作感兴趣的请看 个人对computer和filter工具使用的一些见解,传送门另外关于本文,说实话,很多错误,是自己初学的时候瞎写的,如对data的数据双向绑定感兴趣,请看这个链接)

1.data

关于data,很多人的第一印象就是,这个东西很简单,不就是把数据写到data里,就可以用双括号绑定数据了吗?(那你跟我的想法相同,然后踩到坑里无法自拔了)先来看一下官方文档:

Vue 实例的数据对象。Vue 将会递归将 data 的属性转换为 getter/setter,从而让 data 的属性能够响应数据变化。对象必须是纯粹的对象 (含有零个或多个的 key/value 对):浏览器 API 创建的原生对象,原型上的属性会被忽略。大概来说,data 应该只能是数据 - 不推荐观察拥有状态行为的对象。

一旦观察过,不需要再次在数据对象上添加响应式属性。因此推荐在创建实例之前,就声明所有的根级响应式属性。

实例创建之后,可以通过 vm.$data 访问原始数据对象。Vue 实例也代理了 data 对象上所有的属性,因此访问 vm.a 等价于访问 vm.$data.a。

以 _ 或 $ 开头的属性 不会 被 Vue 实例代理,因为它们可能和 Vue 内置的属性、API 方法冲突。你可以使用例如 vm.$data._property 的方式访问这些属性。

当一个组件被定义,data 必须声明为返回一个初始数据对象的函数,因为组件可能被用来创建多个实例。如果 data 仍然是一个纯粹的对象,则所有的实例将共享引用同一个数据对象!通过提供 data 函数,每次创建一个新实例后,我们能够调用 data 函数,从而返回初始数据的一个全新副本数据对象。
 

如果需要,可以通过将 vm.$data 传入 JSON.parse(JSON.stringify(...)) 得到深拷贝的原始数据对象。

以上即为官网对于data的说明,并不是三言两语,反而比很多其他听起来更复杂的对象或方法描述更详细,对于红字部分来一一验证或说明。

首先创建实例后,按照官网提供的方法,输出vm.$data 访问一下data,下面是一个小demo。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>data处理</title>
    <link rel="stylesheet" type="text/css" href="/static/css/common.css" >
</head>
<body>
    <div id="demo">${name}</div>
</body>
<script src="/static/js/vue.js"></script>
<script src="/static/js/jquery-1.11.1.js"></script>
<script>
    var vm = new Vue({
        delimiters:['${','}'],
        el:"#demo",
        data:{
            "name":"dkr"
        }
    })
    console.log(vm.$data);
</script>
</html>

可以看到控制台打印:

Vue 将会递归将 data 的属性转换为 getter/setter,从而让 data 的属性能够响应数据变化,所以数据是通过get和set方法进行数据绑定的。

然后来“作”一下,把name改成$name or _name,控制台可以输出值,但无法渲染到dom上,还会报错

当一个组件被定义,data 必须声明为返回一个初始数据对象的函数,因为组件可能被用来创建多个实例。这个特性跟组件有关,在后面讲组件的时候会讲到,大致了解一下,可以听不懂,就是组件的data如果用对象的方式声明,A组件和B组件会共用这个data对象里面的值,因此需要通过声明函数,通过函数返回值,使得A组件和B组件的内容不共用。(其实就是你所创建的某个东西,在计算机里是否存在同一区域的问题,如果存在同一区域,那肯定是共用该区域的内容,如果是不同区域,即使名字相同,也只是同名同姓的两个人,本质上不是一个人)

 

2.methods

method在官网里的描述不是很多就一句话:

methods 将被混入到 Vue 实例中。可以直接通过 VM 实例访问这些方法,或者在指令表达式中使用。方法中的 this 自动绑定为 Vue 实例。

只要注意一下method里的this指针指向的是创建的vue实例即可。

关于method的好处,个人觉得他可以统一管理某个组件里用到的方法,而不需要像平常做的项目一样,引入不知道多少个common文件,东拼西凑,代码维护起来很不方便。他的用法就是通过v-on监听事件是否触发,再绑定method里的函数。(关于v-on的用法上一章说的比较细,这里就不具体演示了)

写个小demo看一下this对象。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>data处理</title>
    <link rel="stylesheet" type="text/css" href="/static/css/common.css" >
</head>
<body>
    <div id="demo">
        <button @click="helloWorld"  v-text="name"></button>
    </div>
</body>
<script src="/static/js/vue.js"></script>
<script src="/static/js/jquery-1.11.1.js"></script>
<script>
    var vm = new Vue({
        delimiters:['${','}'],
        el:"#demo",
        data:{
            "name":"dkr"
        },
        methods:{
            helloWorld:function(){
                console.log("hello world");
                console.log(this);
            }
        }
    })

</script>
</html>

3.computed

官网描述:

计算属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算。注意,如果某个依赖 (比如非响应式属性) 在该实例范畴之外,则计算属性是不会被更新的。补充一条:this指针默认指向创建的vue实例。

关于computed,个人理解他是用于数据的计算,并可以直接返回结果值,由于返回的是值,因此可以直接使用该数据,而不是绑定函数,驱动computed执行的是数据是否变化这个条件,所以可以理解为,computed里面的函数监听了数据是否变化。(跟method里监听鼠标点击,巴拉巴拉的操作其实差不多,只是各司其职)

写个简单的demo了解一下,实际项目中涉及的复杂计算请多多了解一些常用的计算工具。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>data处理</title>
    <link rel="stylesheet" type="text/css" href="/static/css/common.css" >
</head>
<body>
    <div id="demo">
        <button @click="helloWorld"  v-text="name"></button>
        <input type="number" v-model="A">
        <input type="number" v-model="B">
        <div>${Add}</div>
    </div>
</body>
<script src="/static/js/vue.js"></script>
<script src="/static/js/jquery-1.11.1.js"></script>
<script>
    var vm = new Vue({
        delimiters:['${','}'],
        el:"#demo",
        data:{
            "name":"dkr",
            "A":0,
            "B":0,
        },
        methods:{
            helloWorld:function(){
                console.log("hello world");
                console.log(this);
            }
        },
        computed:{
            Add:function(){
                return this.A + this.B;
            }
        }
    })

</script>
</html>

可以看到我把Add函数的返回值直接用双括号绑定的方法渲染在模板里。

 

4.watch

官网的介绍感觉不是很详细:

一个对象,键是需要观察的表达式,值是对应回调函数。值也可以是方法名,或者包含选项的对象。Vue 实例将会在实例化时调用 $watch(),遍历 watch 对象的每一个属性。

关于watch的使用其实有很多坑,deep参数的使用,新值旧值的获取等。

为了说明deep参数,我将测试三种类型的数据,分别是

str :字符串

arr:数组

json:对象

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>data处理</title>
    <link rel="stylesheet" type="text/css" href="/static/css/common.css" >
</head>
<body>
    <div id="demo">
        <button @click="helloWorld"  v-text="name"></button>
        <input type="number" v-model="A">
        <input type="number" v-model="B">
        <div>${Add}</div>
        <button @click="changeArr">改变对象数组值</button>
        <button @click="changeStr">改变str值</button>
        <button @click="changeObj">改变obj值</button>
    </div>
</body>
<script src="/static/js/vue.js"></script>
<script src="/static/js/jquery-1.11.1.js"></script>
<script>
    var vm = new Vue({
        delimiters:['${','}'],
        el:"#demo",
        data:{
            "name":"dkr",
            "A":0,
            "B":0,
            "arr":[{
                "name":"lalala",
                "sex":"nan",
            },{
                "name":"hahaha",
                "sex":"nan",
            },{
                "name":"xixixi",
                "sex":"nv",
            },],
            "str":"hello world",
            "obj":{
                "name":"diudiudiu",
                "sex":"nv",
            }
        },
        methods:{
            helloWorld:function(){
                console.log("hello world");
                console.log(this);
            },
            changeArr:function(){
                this.arr.push("nihao");
            },
            changeStr:function(){
                this.str = "hello vue";
            },
            changeObj:function(){
                this.obj.name="dididi";
            }
        },
        computed:{
            Add:function(){
                return this.A + this.B;
            }
        },
        watch:{
            "arr":{
                handler:function(val,oldVal){
                    console.log("监听到了arr数据变化");
                    console.log(JSON.stringify(val)===JSON.stringify(oldVal)); //true
                },
                //deep:true,
            },
            "str":{
                handler:function(val,oldVal){
                    console.log("监听到了str数据变化");
                    console.log(val,oldVal); //hello vue , hello world
                },
                //deep:true,
            },
            "obj":{
                handler:function(val,oldVal){
                    console.log("监听到了obj数据变化");
                    console.log(val === oldVal); //true
                },
                deep:true,
            },
        }
    })

</script>
</html>

分别点击三个button触发事件,获得以下结果

arr和str不需要深度监控,就可以探测到数据的变化(如果你的数组是对象数组,改变了某个对象里的某个值,其实可以归为下面一类,也是需要深度监控才能监听到

json对象需要深度监控,才能检测到某个数据的变化,否则不会触发监听事件(当然,如果你新增一个键值对,那么,不需要深度监控也能监听到

arr和json对象,val === oldval,都是新的值,是因为数组和对象共用同一块空间。

str类型能够顺利输出新值和旧值。

 

关于数据的基本操作,到此为止。有什么看不懂或者写错的地方,欢迎联系我,我电话110

 

 

Logo

前往低代码交流专区

更多推荐