Vue学习笔记

本次Vue学习基于尚硅谷天禹老师的视频课程。

官方文档:https://cn.vuejs.org/v2/guide/

1、初识Vue

Vue是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。

Vue的特点:

1、采用组件化模式,提高代码的复用率,让代码更好维护;

2、声明式编码,让编码人员无需直接操作DOM,提高开发效率;

3、使用虚拟DOM和优秀的Diff算法,尽量复用DOM节点;

 

 

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="UTF-8" />
 5         <title>初识Vue</title>
 6         <!-- 引入Vue -->
 7         <script type="text/javascript" src="js/vue.js"></script>
 8         <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"/>
 9     </head>
10     <body>
11         <!-- 
12             前置:
13                 1、强制刷新shift+F5
14                 2、解决网页标签favicon.ico缺失的问题,内部服务器
15                 3、new Vue({这里是配置对象,要用专有名词,如el,methods})
16             初识Vue:
17                 1.想让Vue工作,就必须创建一个Vue实例,且要传入一个配置对象;
18                 2.app容器里的代码依然符合html规范,只不过混入了一些特殊的Vue语法;
19                 3.app容器里的代码被称为【Vue模板】,模板会被vue实例解析成正常的html然后挂载到容器里;
20                 4.Vue实例和容器是一一对应的,一对一的关系;
21                 5.真实开发中只有一个Vue实例,并且会配合着组件一起使用;
22                 6.{{xxx}}中的xxx要写js表达式,且xxx可以自动读取到data中的所有属性;
23                 7.一旦data中的数据发生改变,那么页面中用到该数据的地方也会自动更新;
24 
25                 注意区分:js表达式 和 js代码(语句)
26                         1.表达式:一个表达式会产生一个值,可以放在任何一个需要值的地方:
27                                     (1). a
28                                     (2). a+b
29                                     (3). demo(1)
30                                     (4). x === y ? 'a' : 'b'
31                         2.js代码(语句)
32                                     (1). if(){}
33                                     (2). for(){}
34         -->
35 
36         <!-- 准备好一个容器 -->
37         <div id="app">
38             <h1>Hello,{{name.toUpperCase()}},{{address}}</h1>
39         </div>
40 
41         <script type="text/javascript" >
42             Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
43 
44             //创建Vue实例
45             //new不可少,Vue本身是个构造函数,不能直接调用,必须通过实例来调用 
46             new Vue({  //通过构造函数创建实例
47                 el:'#app', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。
48                 data:{ //data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。
49                     name:'waylon',
50                     address:'上海'
51                 }
52             })
53 
54         </script>
55     </body>
56 </html>

 

 

2、模板语法

 

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="UTF-8" />
 5         <title>模板语法</title>
 6         <!-- 引入Vue -->
 7         <script type="text/javascript" src="js/vue.js"></script>
 8     </head>
 9     <body>
10         <!-- 
11                 Vue模板语法有2大类:
12                     1.插值语法:
13                             功能:用于解析 标签体 内容。
14                             写法:{{xxx}},xxx是js表达式,且可以直接读取到data中的所有属性。
15                     2.指令语法:
16                             功能:用于解析标签(包括:标签属性、标签体内容、绑定事件.....)。
17                             举例:v-bind:href="xxx" 或  简写为 :href="xxx",xxx同样要写js表达式,
18                                      且可以直接读取到data中的所有属性。
19                             备注:Vue中有很多的指令,且形式都是:v-????,此处我们只是拿v-bind举个例子。
20 
21          -->
22         <!-- 准备好一个容器-->
23         <div id="root">
24             <h1>插值语法</h1>
25             <h3>你好,{{name}}</h3>
26             <hr/>
27             <h1>指令语法</h1>
28             <!-- 添加v-bind:之后就会把=右边的字符串当成js表达式去执行 -->
29             <a v-bind:href="school.url.toUpperCase()" x="hello">点我去{{school.name}}学习1</a>
30             <a :href="school.url" :x="hello">点我去{{school.name}}学习2</a>
31         </div>
32     </body>
33 
34     <script type="text/javascript">
35         Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
36 
37         new Vue({
38             el:'#root',
39             data:{
40                 hello:'嘻嘻',
41                 name:'jack',
42                 school:{
43                     name:'尚硅谷', //虽然同名,但不同级
44                     url:'http://www.atguigu.com',
45                 }
46             }
47         })
48     </script>
49 </html>

 

3、数据绑定

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="UTF-8" />
 5         <title>数据绑定</title>
 6         <!-- 引入Vue -->
 7         <script type="text/javascript" src="js/vue.js"></script>
 8     </head>
 9     <body>
10         <!-- 
11             Vue中有2种数据绑定的方式:
12                 1.单向绑定(v-bind):数据只能从data流向页面。
13                 2.双向绑定(v-model):数据不仅能从data流向页面,还可以从页面流向data。
14             备注:
15                 1.双向绑定一般都应用在表单类元素上(如:input、select等)
16                 2.v-model:value 可以简写为 v-model,因为v-model默认收集的就是value值。
17          -->
18         <!-- 准备好一个容器-->
19         <div id="root">
20             <!-- 普通写法: -->
21             <!-- 
22             单向数据绑定:<input type="text" v-bind:value="name"><br/>
23             双向数据绑定:<input type="text" v-model:value="name"><br/> 
24             -->
25 
26             <!-- 简写: -->
27             单向数据绑定:<input type="text" :value="name"><br/>
28             双向数据绑定:<input type="text" v-model="name"><br/>
29 
30             <!-- 如下代码是错误的,因为v-model只能应用在表单类元素(输入类元素)上 -->
31             <!-- <h2 v-model:x="name">你好啊</h2> -->
32         </div>
33     </body>
34 
35     <script type="text/javascript">
36         Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
37 
38         new Vue({
39             el:'#root',
40             data:{
41                 name:'尚硅谷'
42             }
43         })
44     </script>
45 </html>

 

 

4、el与data的两种写法

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="UTF-8" />
 5         <title>el与data的两种写法</title>
 6         <!-- 引入Vue -->
 7         <script type="text/javascript" src="js/vue.js"></script>
 8     </head>
 9     <body>
10         <!-- 
11             data与el的2种写法
12                 1.el有2种写法
13                     (1).new Vue时候配置el属性。
14                     (2).先创建Vue实例,随后再通过vm.$mount('#root')指定el的值。
15                     如果 Vue 实例在实例化时没有收到 el 选项,则它处于“未挂载”状态,没有关联的 DOM 元素。可
16                     以使用 vm.$mount() 手动地挂载一个未挂载的实例。
17                 2.data有2种写法
18                     (1).对象式
19                     (2).函数式
20                     如何选择:目前哪种写法都可以,以后学习到组件时,data必须使用函数式,否则会报错。
21                 3.一个重要的原则:
22                     由Vue管理的函数,如data(),一定不要写箭头函数,一旦写了箭头函数,this就不再是Vue实例了,而是Window
23         -->
24         <!-- 准备好一个容器-->
25         <div id="root">
26             <h1>你好,{{name}}</h1>
27         </div>
28     </body>
29 
30     <script type="text/javascript">
31         Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
32 
33         //el的两种写法
34         /*
35         const vm = new Vue({
36             // el:'#root', //第一种写法
37             data:{
38                 name:'尚硅谷'
39             }
40         })
41         console.log(vm)
42         vm.$mount('#root') //第二种写法,mount意为:挂载
43         */
44        
45         // data的两种写法
46         const vm = new Vue({
47             el:'#root',
48             //data的第一种写法:对象式
49             /* data:{
50                 name:'尚硅谷'
51             } */
52 
53             //data的第二种写法:函数式
54             data(){        //即data:function(){}的简写
55                 console.log('@@@',this) //此处的this是Vue实例对象
56                 return{
57                     name:'尚硅谷'
58                 }
59             }
60         })
61     </script>
62 </html>

 

5、Vue中的MVVM模型

Vue学习笔记

 

 

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="UTF-8" />
 5         <title>理解MVVM</title>
 6         <!-- 引入Vue -->
 7         <script type="text/javascript" src="js/vue.js"></script>
 8     </head>
 9     <body>
10         <!-- 
11             MVVM模型
12                 1. M:模型(Model) :data中的数据   ————>js对象
13                 2. V:视图(View) :模板代码  ————>DOM
14                 3. VM:视图模型(ViewModel):Vue实例
15             观察发现:
16                 1.data中所有的属性,最后都出现在了vm身上。
17                 2.vm身上所有的属性 及 Vue原型[Prototype]上所有属性,在Vue模板中都可以直接使用。
18         -->
19         <div id="root">
20             <h1>学校名称:{{name}}</h1>
21             <h1>学校地址:{{address}}</h1>
22             <!-- <h1>测试一下1:{{1+1}}</h1>
23             <h1>测试一下2:{{$options}}</h1>
24             <h1>测试一下3:{{$emit}}</h1>
25             <h1>测试一下4:{{_c}}</h1> -->
26         </div>
27     </body>
28 
29     <script type="text/javascript">
30 
31         const vm = new Vue({
32             el:'#root',
33             data:{
34                 name:'尚硅谷',
35                 address:'北京',
36             }
37         })
38         console.log(vm)
39     </script>
40 </html>

 

Vue的实例对象vm:

Vue学习笔记

 

MVVM在vue中的体现:

 Vue学习笔记

 

 

6、数据代理

1、关于Object.defineproperty方法

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5         <title>关于Object.defineproperty方法</title>
 6     </head>
 7     <body>
 8         <script type="text/javascript">
 9             let number = 18
10             let person = {
11                 name:'张三',
12                 sex:'男',
13             }
14             
15             Object.defineProperty(person,'age',{
16                 // value:18,
17                 // enumerable:true, //控制属性是否可以枚举,默认值是false
18                 // writable:true, //控制属性是否可以被修改,默认值是false
19                 // configurable:true //控制属性是否可以被删除,默认值是false
20             
21                 //当有人读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值
22                 get(){
23                     console.log('有人读取age属性了')
24                     return number
25                 },
26             
27                 //当有人修改person的age属性时,set函数(setter)就会被调用,且会收到修改的具体值
28                 set(value){
29                     console.log('有人修改了age属性,且值是',value)
30                     number = value
31                 }
32                 //getter和setter将person和number两者产生了关联
33             })
34             // console.log(Object.keys(person)) //将对象的属性名提取出来组成一个数组
35             
36             console.log(person)
37             52         </script>
53     </body>
54 </html>

2、何为数据代理?

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="UTF-8" />
 5         <title>何为数据代理</title>
 6     </head>
 7     <body>
 8         
 9         <!-- 数据代理:通过一个对象实现对另一个对象中属性的(读/写)操作 -->
10         <script type="text/javascript" >
11             let obj = {x:100}
12             let obj2 = {y:200}
13 
14             Object.defineProperty(obj2,'x',{
15                 get(){
16                     return obj.x
17                 },
18                 set(value){
19                     obj.x = value
20                 }
21             })
22         </script>
23     </body>
24 </html>

 

3、在Vue中的数据代理如何实现?

 

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5         <title>Vue中的数据代理</title>
 6         <script type="text/javascript" src="js/vue.js"></script>
 7     </head>
 8     <body>
 9         <div id="app">
10             <h1>个人姓名:{{name}}</h1>
11             <h1>个人年龄:{{age}}</h1>
12         </div>
13         <script type="text/javascript">
14             const vm = new Vue({
15                 el:"#app",
16                 data:{
17                     name:'天青色',
18                     age:18
19                 }
20             })
21         </script>
22     </body>
23 </html>

 

 

在上面这段代码中,data属性是个对象,可以通过实例对象vm去操作data中的键值对,如下:

 Vue学习笔记

 

 

 Vue学习笔记

 

 这不就是数据代理吗?通过一个对象实现对另一个对象中属性的(读/写)操作 。这点可以从vm实例对象下面的name属性看出来,将鼠标光标移到上面显示 Invoke property getter,表示读取属性值时要通过getter实现。

Vue学习笔记

 

name和age都是有自己的getter和setter:

 Vue学习笔记

 

其实在vm实例对象下面有个_data属性,里面保存了data里的键值对,可以通过vm._data来进行读写操作:

Vue学习笔记

 

 

 Vue学习笔记

 

 vm下面的name和age就是通过数据代理与_data中的name和age建立了联系,如果没有这层联系,那模板中{{name}}就不能直接拿到_data中的name了,而应该是{{ _data.name }}才可以。而_data数据又来自于data,所以vm就很方便的代理操作了data。

尚硅谷老师的图也讲得很清楚:

 Vue学习笔记

 

 补充一点,_data里还实现了数据劫持。当我们通过vm.name更改值时,页面上用到name的地方也会自动响应式更新了。这就是_data里数据劫持的作用。

 

总结:

1.Vue中的数据代理:
  通过vm对象来代理data对象中属性的操作(读/写)
2.Vue中数据代理的好处:
  更加方便的操作data中的数据
3.基本原理:
  通过Object.defineProperty()把data对象中所有属性添加到vm上。
  为每一个添加到vm上的属性,都指定一个getter/setter。
  在getter/setter内部去操作(读/写)data中对应的属性。

 

7、事件处理

 

 

8、计算属性

先实现一个小案例:

Vue学习笔记

 

 

 

 输入框默认有张和三,手动输入后全名也会跟着改变。

1、通过插值语法实现案例

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="UTF-8" />
 5         <title>姓名案例_插值语法实现</title>
 6         <!-- 引入Vue -->
 7         <script type="text/javascript" src="js/vue.js"></script>
 8     </head>
 9     <body>
10         <!-- 准备好一个容器-->
11         <div id="root">
12             姓:<input type="text" v-model="firstName"> <br/><br/>
13             名:<input type="text" v-model="lastName"> <br/><br/>
14             全名:<span>{{firstName}}-{{lastName}}</span>
15         </div>
16     </body>
17 
18     <script type="text/javascript">
19         Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
20 
21         new Vue({
22             el:'#root',
23             data:{
24                 firstName:'张',
25                 lastName:'三'
26             }
27         })
28     </script>
29 </html>

 

2、通过methods实现案例

 

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="UTF-8" />
 5         <title>姓名案例_methods实现</title>
 6         <!-- 引入Vue -->
 7         <script type="text/javascript" src="js/vue.js"></script>
 8     </head>
 9     <body>
10         <!-- 准备好一个容器-->
11         <div id="root">
12             姓:<input type="text" v-model="firstName"> <br/><br/>
13             名:<input type="text" v-model="lastName"> <br/><br/>
14             全名:<span>{{fullName()}}</span>
15         </div>
16     </body>
17 
18     <script type="text/javascript">
19         Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
20 
21         new Vue({
22             el:'#root',
23             data:{
24                 firstName:'张',
25                 lastName:'三'
26             },
27             methods: {
28                 fullName(){
29                     console.log('@---fullName')
30                     return this.firstName + '-' + this.lastName
31                 }
32             },
33         })
34     </script>
35 </html>

注意14行的{{fullName()}}是要加()的。

另外,由于是双向数据绑定,每次输入都会导致data对象里面的属性值发生改变,从而会使得模板代码被Vue重新渲染,fullName方法也会被重新调用。如下:

 Vue学习笔记

3、通过计算属性实现案例

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="UTF-8" />
 5         <title>姓名案例_计算属性实现</title>
 6         <!-- 引入Vue -->
 7         <script type="text/javascript" src="js/vue.js"></script>
 8     </head>
 9     <body>
21         <!-- 准备好一个容器-->
22         <div id="root">
23             姓:<input type="text" v-model="firstName"> <br/><br/>
24             名:<input type="text" v-model="lastName"> <br/><br/>
25             测试:<input type="text" v-model="x"> <br/><br/>
26             全名:<span>{{fullName}}</span> <br/><br/>
27             <!-- 全名:<span>{{fullName}}</span> <br/><br/>
28             全名:<span>{{fullName}}</span> <br/><br/>
29             全名:<span>{{fullName}}</span> -->
30         </div>
31     </body>
32 
33     <script type="text/javascript">
34         Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
35 
36         const vm = new Vue({
37             el:'#root',
38             data:{
39                 firstName:'张',
40                 lastName:'三',
41                 x:'你好'
42             },
43             methods: {
44                 demo(){
45                     
46                 }
47             },
48             computed:{
49                 fullName:{
50                     //get有什么作用?当有人读取fullName时,get就会被调用,且返回值就作为fullName的值
51                     //get什么时候调用?1.初次读取fullName时。2.所依赖的数据发生变化时。
52                     get(){
53                         console.log('get被调用了')
54                         // console.log(this) //经过Vue的处理后此处的this是vm
55                         return this.firstName + '-' + this.lastName
56                     },
57                     //set什么时候调用? 当fullName被修改时。
58                     set(value){
59                         console.log('set',value)
60                         const arr = value.split('-')
61                         this.firstName = arr[0]
62                         this.lastName = arr[1]
63                     }
64                 }
65             }
66         })
67     </script>
68 </html>

 

 

总结:

1.定义:要用的属性不存在,要通过已有属性(如data对象里的属性)计算得来。它也是vm下面的一个属性。
2.原理:底层借助了Objcet.defineproperty方法提供的getter和setter。
3.get函数什么时候执行?
  (1).初次读取时会执行一次。
  (2).当依赖的数据发生改变时会被再次调用。
4.优势:与methods实现相比,内部有缓存机制(复用),效率更高,调试方便。
5.计算属性最终会出现在vm上,直接插值法读取使用即可。
6.如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生改变。

 

4、计算属性的简写

当只考虑计算属性的读取不考虑修改的时候,就可以简写:

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="UTF-8" />
 5         <title>姓名案例_计算属性实现</title>
 6         <!-- 引入Vue -->
 7         <script type="text/javascript" src="js/vue.js"></script>
 8     </head>
 9     <body>
10         <!-- 准备好一个容器-->
11         <div id="root">
12             姓:<input type="text" v-model="firstName"> <br/><br/>
13             名:<input type="text" v-model="lastName"> <br/><br/>
14             全名:<span>{{fullName}}</span> <br/><br/>
15         </div>
16     </body>
17 
18     <script type="text/javascript">
19         Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
20 
21         const vm = new Vue({
22             el:'#root',
23             data:{
24                 firstName:'张',
25                 lastName:'三',
26             },
27             computed:{
28                 //完整写法
29                 /* fullName:{
30                     get(){
31                         console.log('get被调用了')
32                         return this.firstName + '-' + this.lastName
33                     },
34                     set(value){
35                         console.log('set',value)
36                         const arr = value.split('-')
37                         this.firstName = arr[0]
38                         this.lastName = arr[1]
39                     }
40                 } */
41                 //简写
42                 fullName(){
43                     console.log('get被调用了')
44                     return this.firstName + '-' + this.lastName
45                 }
46             }
47         })
48     </script>
49 </html>

 

 读取的时候依然是 {{计算属性}} ,不可加() 。

 

9、监视属性

实现天气小案例:

Vue学习笔记

 

 默认炎热,点击后切换为凉爽,再点击切换为炎热。

1、实现案例

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5         <title></title>
 6         <script type="text/javascript" src="js/vue.js"></script>
 7     </head>
 8     <body>
 9         <div id="app">
10             <h1>今天的天气很{{weather}}</h1>
11             <button type="button" @click="changeWeather">点我切换天气</button>
12             <!-- <button type="button" @click="ishot=!ishot;x其他代码x">点我切换天气</button> -->
13             <!-- <button type="button" @click="window.alert('点击成功')">点我切换天气</button> -->
14             <!-- 在绑定事件的时候,@xxx='yyy',这里的yyy可以写一些简单的语句,复杂的话就交给methods -->
15         </div>
16         <script type="text/javascript">
17             const vm = new Vue({
18                 el:'#app',
19                 data:{
20                     ishot:true,
21                     // window  点击事件里的window在vm里找不到,所以要在这添加window,不然会报错
22                 },
23                 methods:{
24                     changeWeather(){
25                         this.ishot = !this.ishot
26                     }
27                 },
28                 computed:{
29                     weather(){
30                         return this.ishot ? '炎热' : '凉爽'
31                     }
32                 }
33             })
34         </script>
35     </body>
36 </html>

 

 

 

2、监视属性watch

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="UTF-8" />
 5         <title>天气案例_监视属性</title>
 6         <!-- 引入Vue -->
 7         <script type="text/javascript" src="js/vue.js"></script>
 8     </head>
 9     <body>
10         <!-- 准备好一个容器-->
11         <div id="root">
12             <h2>今天天气很{{info}}</h2>
13             <button @click="changeWeather">切换天气</button>
14         </div>
15     </body>
16 
17     <script type="text/javascript">
18         Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
19         
20         const vm = new Vue({
21             el:'#root',
22             data:{
23                 isHot:true,
24             },
25             computed:{
26                 info(){
27                     return this.isHot ? '炎热' : '凉爽'
28                 }
29             },
30             methods: {
31                 changeWeather(){
32                     this.isHot = !this.isHot
33                 }
34             },
35             /* watch:{
36                 isHot:{
37                     immediate:true, //初始化时让handler调用一下
38                     //handler什么时候调用?当isHot发生改变时。
39                     handler(newValue,oldValue){
40                         console.log('isHot被修改了',newValue,oldValue)
41                     }
42                 }
43             } */
44         })
45 
46         vm.$watch('isHot',{
47             immediate:true, //初始化时让handler调用一下
48             //handler什么时候调用?当isHot发生改变时。
49             handler(newValue,oldValue){
50                 console.log('isHot被修改了',newValue,oldValue)
51             }
52         })
53     </script>
54 </html>

 

总结:

监视属性watch:
1.当被监视的属性变化时, 回调函数自动调用, 进行相关操作
2.监视的属性必须存在,才能进行监视!可以使data里的属性,也可以是计算属性
3.监视的两种写法:
  (1).new Vue时传入watch配置(初期明确知道需要监视)
  (2).通过vm.$watch监视(后期需求添加的监视)

 

3、深度监视deep

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="UTF-8" />
 5         <title>天气案例_深度监视</title>
 6         <!-- 引入Vue -->
 7         <script type="text/javascript" src="js/vue.js"></script>
 8     </head>
 9     <body>
10         <!-- 准备好一个容器-->
11         <div id="root">
12             <h2>今天天气很{{info}}</h2>
13             <button @click="changeWeather">切换天气</button>
14             <hr/>
15             <h3>a的值是:{{numbers.a}}</h3>
16             <button @click="numbers.a++">点我让a+1</button>
17             <h3>b的值是:{{numbers.b}}</h3>
18             <button @click="numbers.b++">点我让b+1</button>
19             <button @click="numbers = {a:666,b:888}">彻底替换掉numbers</button>
20             <!-- {{numbers.c.d.e}} -->
21         </div>
22     </body>
23 
24     <script type="text/javascript">
25         Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
26         
27         const vm = new Vue({
28             el:'#root',
29             data:{
30                 isHot:true,
31                 numbers:{
32                     a:1,
33                     b:1,
34                     c:{
35                         d:{
36                             e:100
37                         }
38                     }
39                 }
40             },
41             computed:{
42                 info(){
43                     return this.isHot ? '炎热' : '凉爽'
44                 }
45             },
46             methods: {
47                 changeWeather(){
48                     this.isHot = !this.isHot
49                 }
50             },
51             watch:{
52                 isHot:{
53                     // immediate:true, //初始化时让handler调用一下
54                     //handler什么时候调用?当isHot发生改变时。
55                     handler(newValue,oldValue){
56                         console.log('isHot被修改了',newValue,oldValue)
57                     }
58                 },
59                 //监视多级结构中某个属性的变化,注意要用引号,之前isHot是简写
60                 /* 'numbers.a':{
61                     handler(){
62                         console.log('a被改变了')
63                     }
64                 } */
65                 //监视多级结构中所有属性的变化
66                 numbers:{
67                     deep:true,  //默认为false,开启深度监视
68                     handler(){
69                         console.log('numbers改变了')
70                     }
71                 }
72             }
73         })
74 
75     </script>
76 </html>

 

 

总结:

深度监视:
(1).Vue中的watch默认不监测对象内部值的改变(一层)。
(2).配置deep:true可以监测对象内部值改变(多层)。
(3).Vue自身可以监测对象内部值的改变,无论有多少层,如numbers.c.d.e,但Vue提供的watch默认不可以!
(4).考虑到效率性,使用watch时根据数据的具体结构,决定是否采用深度监视。

 

4、监视属性简写

当监视某个属性而不需要配置immediate和deep时,可以使用简写形式,类似于计算属性的简写:

 

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="UTF-8" />
 5         <title>天气案例_监视属性_简写</title>
 6         <!-- 引入Vue -->
 7         <script type="text/javascript" src="js/vue.js"></script>
 8     </head>
 9     <body>
10         <!-- 准备好一个容器-->
11         <div id="root">
12             <h2>今天天气很{{info}}</h2>
13             <button @click="changeWeather">切换天气</button>
14         </div>
15     </body>
16 
17     <script type="text/javascript">
18         Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
19         
20         const vm = new Vue({
21             el:'#root',
22             data:{
23                 isHot:true,
24             },
25             computed:{
26                 info(){
27                     return this.isHot ? '炎热' : '凉爽'
28                 }
29             },
30             methods: {
31                 changeWeather(){
32                     this.isHot = !this.isHot
33                 }
34             },
35             watch:{
36                 //正常写法
37                 /* isHot:{
38                     // immediate:true, //初始化时让handler调用一下
39                     // deep:true,//深度监视
40                     handler(newValue,oldValue){
41                         console.log('isHot被修改了',newValue,oldValue)
42                     }
43                 }, */
44                 //简写
45                 /* isHot(newValue,oldValue){
46                     console.log('isHot被修改了',newValue,oldValue,this)
47                 } */
48             }
49         })
50 
51         //正常写法
52         /* vm.$watch('isHot',{
53             immediate:true, //初始化时让handler调用一下
54             deep:true,//深度监视
55             handler(newValue,oldValue){
56                 console.log('isHot被修改了',newValue,oldValue)
57             }
58         }) */
59 
60         //简写
61         /* vm.$watch('isHot',(newValue,oldValue)=>{
62             console.log('isHot被修改了',newValue,oldValue,this)
63         }) */
64 
65     </script>
66 </html>

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

11

 

上一篇:macbook 源码安装 ngxin


下一篇:WTM多租户改造