• Vue(一)——Vue核心


    目录

    1.初识Vue

    搭建Vue环境

    Hello小案例

    2.模板语法

    3.数据绑定

    4.el和data的两种写法

    5.MVVM模型

    6.数据代理

    回顾Object.defineproperty方法

    何为数据代理?

    Vue中的数据代理

    7.事件处理

    事件的基本使用

    事件修饰符

    键盘事件

    8.计算属性

    姓名案例

    插值语法实现

    methods实现

    计算属性实现

    计算属性简写

    9.监视属性

    天气案例

    监视属性

    深度监视

    监视属性简写

    姓名案例:watch实现


    1.初识Vue

    搭建Vue环境

    • 在vue官网下载vue.js并引入
    1. <script type="text/javascript" src="../js/vue.js">script>
    • 在浏览器安装Vue devtools扩展程序

    • 关闭提示语句

    1. <script type="text/javascript" >
    2. Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
    3. script>

            在点击这个选项的一瞬间,他就开了一个5500的端口号,并且进行了一个最重要的动作,把整个工程里面所有的和文件夹都作为这台服务器的根资源去使用。

    Hello小案例

    1. <div id="demo">
    2. <h1>Hello,{{name.toUpperCase()}},{{address}},{{Date.now()}}h1>
    3. div>
    • root容器里的代码依然符合html规范,只不过混入了一些特殊的Vue语法;
    • root容器里的代码被称为【Vue模板】;

    最好在Vue.config之后使用Vue,因为Vue.config是全局配置,最好是调整完了再去使用。

    • 想让Vue工作,就必须创建一个Vue实例,且要传入一个配置对象;
    1. //创建Vue实例
    2. new Vue({
    3. el:'#demo', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。
    4. data:{ //data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。
    5. name:'zqf',
    6. address:'北京'
    7. }
    8. })

            Vue实例开始工作的时候,写了el的配置,就得把el整个容器都拿过来,拿过来之后呢,他进行了一个特别重要的步骤叫做解析,那解析的是什么呢?他去扫描有没有自己设计的语法,比如说这扫了,然后干嘛呢?他说那你要用谁呀?我要用name,那我的data里面有没有name呀?有,什么值?zqf,于是他拿着zqf,就把整个双括号里的的东西全都替换掉了,然后就生成了一个全新的div。 

    •  Vue实例和容器是一一对应的;

            当有两个同名的容器的时候,Vue实例只和第一个容器相对应。

    •  真实开发中只有一个Vue实例,并且会配合着组件一起使用;

    一个容器只能被一个实例所接管,第二个Vue实例接管同一个容器没有任何用处。 

    • {{xxx}}中的xxx要写js表达式,且xxx可以自动读取到data中的所有属性;

    一旦data中的数据发生改变,那么页面中用到该数据的地方也会自动更新;

    注意区分:js表达式 和 js代码(语句)

            1.表达式:一个表达式会产生一个值,可以放在任何一个需要值的地方:

                    (1). a

                    (2). a+b

                    (3). demo(1)

                    (4). x === y ? 'a' : 'b'

            2.js代码(语句)

                    (1). if(){}

                    (2). for(){}

    2.模板语法

    Vue模板语法有2大类:

            1.插值语法:

                    功能:用于解析标签体内容

                    写法:{{xxx}},xxx是js表达式,且可以直接读取到data中的所有属性。

            2.指令语法:

                    功能:用于解析标签(包括:标签属性、标签体内容、绑定事件.....)。

                    举例:v-bind:href="xxx" 或  简写为 :href="xxx",xxx同样要写js表达式,且可以直接读取到data中的所有属性。

                    备注:Vue中有很多的指令,且形式都是:v-????,此处我们只是拿v-bind举个例子。

    1. <div id="root">
    2. <h1>插值语法h1>
    3. <h3>你好,{{name}}h3>
    4. <hr/>
    5. <h1>指令语法h1>
    6. <a v-bind:href="school.url.toUpperCase()" x="hello">点我去{{school.name}}学习1a>
    7. <a :href="school.url" x="hello">点我去{{school.name}}学习2a>
    8. div>
    1. <script type="text/javascript">
    2. Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
    3. new Vue({
    4. el:'#root',
    5. data:{
    6. name:'jack',
    7. school:{
    8. name:'zqf',
    9. url:'http://www.baidu.com',
    10. }
    11. }
    12. })
    13. script>

    3.数据绑定

    Vue中有2种数据绑定的方式:

            1.单向绑定(v-bind):数据只能从data流向页面。

            2.双向绑定(v-model):数据不仅能从data流向页面,还可以从页面流向data。

    1.双向绑定一般都应用在表单类元素上(如:input、select等有value值的元素)

       以下写法是错误的:

    <h2 v-model:x="name">你好啊h2>

    2.v-model:value 可以简写为 v-model,因为v-model默认收集的就是value值。

    原始写法:

    1. 单向数据绑定:<input type="text" v-bind:value="name"><br/>
    2. 双向数据绑定:<input type="text" v-model:value="name"><br/>

    简单写法:

    1. 单向数据绑定:<input type="text" :value="name"><br/>
    2. 双向数据绑定:<input type="text" v-model="name"><br/>

    4.el和data的两种写法

    1.el有2种写法

    • new Vue时候配置el属性。
    • 先创建Vue实例,随后再通过vm.$mount('#root')指定el的值。
    1. const v = new Vue({
    2. el:'#root', //第一种写法
    3. data:{
    4. name:'尚硅谷'
    5. }
    6. })
    7. console.log(v)
    8. v.$mount('#root') //第二种写法

    第一种在用的时候就得确定为哪个容器服务,第二种是回头再指定,更加灵活。 

    把容器里的模板交给vue实例进行解析,解析之后将内容重新挂载指定的页面上去。

    2.data有2种写法

    • 对象式
    1. data:{
    2. name:'尚硅谷'
    3. }
    • 函数式

            把data写成一个函数,且必须返回一个对象,对象里的数据就是自己所需要的。

    1. data(){
    2. console.log('@@@',this) //此处的this是Vue实例对象
    3. return{
    4. name:'尚硅谷'
    5. }
    6. }

    注意:此处的this是Vue实例对象 

    如何选择:目前哪种写法都可以,以后学习到组件时,data必须使用函数式,否则会报错。

    由Vue管理的函数,一定不要写箭头函数,一旦写了箭头函数,this就不再是Vue实例了。

    5.MVVM模型

    • M:模型(Model) :对应 data 中的数据
    • V:视图(View) :模板
    • VM:视图模型(ViewModel) : Vue 实例对象

            MVVM模型,直白一点就是,把一堆乱七八糟的数据(Model),和DOM结构(View),用Vue(VM)进行连接。

    1. <div id="root">
    2. <h1>学校名称:{{name}}h1>
    3. <h1>学校地址:{{address}}h1>
    4. <h1>测试一下1:{{1+1}}h1>
    5. <h1>测试一下2:{{$options}}h1>
    6. <h1>测试一下3:{{$emit}}h1>
    7. <h1>测试一下4:{{_c}}h1>
    8. div>

    1. <script type="text/javascript">
    2. Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
    3. const vm = new Vue({
    4. el:'#root',
    5. data:{
    6. name:'zzuli',
    7. address:'郑州',
    8. }
    9. })
    10. console.log(vm)
    11. script>

    所有vm中的属性或者Vue原型中的属性,都可以表现出来:

     测试结果:

    • data中所有的属性,最后都出现在了vm身上。
    • vm身上所有的属性 及 Vue原型上所有属性,在Vue模板中都可以直接使用。

    6.数据代理

    回顾Object.defineproperty方法

            这个方法就是给一个对象添加或定义属性用的,定义person对象,定义好name,sex属性,如果想要添加age属性怎么办?Object.defineProperty()有三个参数,第一个参数是给哪个对象添加属性,第二个参数是要添加的属性名,第三个参数为配置项。

    • enumerable:true, //控制属性是否可以枚举,默认值是false

    • writable:true, //控制属性是否可以被修改,默认值是false

    • configurable:true //控制属性是否可以被删除,默认值是false

    完整代码:

    1. <script type="text/javascript" >
    2. let number = 18
    3. let person = {
    4. name:'张三',
    5. sex:'男',
    6. }
    7. Object.defineProperty(person,'age',{
    8. // value:18,
    9. // enumerable:true, //控制属性是否可以枚举,默认值是false
    10. // writable:true, //控制属性是否可以被修改,默认值是false
    11. // configurable:true //控制属性是否可以被删除,默认值是false
    12. //当有人读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值
    13. get(){
    14. console.log('有人读取age属性了')
    15. return number
    16. },
    17. //当有人修改person的age属性时,set函数(setter)就会被调用,且会收到修改的具体值
    18. set(value){
    19. console.log('有人修改了age属性,且值是',value)
    20. number = value
    21. }
    22. })
    23. // console.log(Object.keys(person))
    24. console.log(person)
    25. script>

    1. //当有人读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值
    2. get(){
    3. console.log('有人读取age属性了')
    4. return number
    5. },
    6. //当有人修改person的age属性时,set函数(setter)就会被调用,且会收到修改的具体值
    7. set(value){
    8. console.log('有人修改了age属性,且值是',value)
    9. number = value
    10. }

    何为数据代理?

    通过obj2读取x并且能够修改x:

    通过调用get方法,以后有人通过obj2访问x的时候,其实给他的是obj的x。

    通过调用set方法,以后有人想更改obj2的x,实际上就是更改obj的x。

    1. <script type="text/javascript" >
    2. let obj = {x:100}
    3. let obj2 = {y:200}
    4. Object.defineProperty(obj2,'x',{
    5. get(){
    6. return obj.x
    7. },
    8. set(value){
    9. obj.x = value
    10. }
    11. })
    12. script>

    Vue中的数据代理

    vm身上,以及Vue原型对象上所有的属性和方法在模板里可以直接用

    参考博客:

    Vue中数据代理详解(从底层刨析)

    Vue数据代理

    Vue中的数据代理

    vue数据代理

                    1.Vue中的数据代理:

                                通过vm对象来代理data对象中属性的操作(读/写)

                    2.Vue中数据代理的好处:

                                更加方便的操作data中的数据

                    3.基本原理:

                                通过Object.defineProperty()把data对象中所有属性添加到vm上。

                                为每一个添加到vm上的属性,都指定一个getter/setter。

                                在getter/setter内部去操作(读/写)data中对应的属性。

    7.事件处理

    事件的基本使用

    1.使用v-on:xxx或@xxx绑定事件,其中xxx是事件名(意为当点击该组件时会调用名为xxx的函数)

    2.事件的回调需要配置在methods对象中,最终会在vm上;

    3.methods中配置的函数,不要用箭头函数!否则this就不是vm了;而是window

    4.methods中配置的函数,都是被Vue所管理的函数,this的指向是vm 或 组件实例对象;

    5.@click="demo" 和 @click="demo($event)" 效果一致,但后者可以传参;

    1. <div id="root">
    2. <h2>欢迎来到{{name}}学习h2>
    3. <button @click="showInfo1">点我提示信息1(不传参)button>
    4. <button @click="showInfo2($event,66)">点我提示信息2(传参)button>
    5. div>

    普通函数看调用,箭头函数看定义。所有被Vue管理的函数最好都写成普通函数而不是箭头函数。

    1. <script type="text/javascript">
    2. Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
    3. const vm = new Vue({
    4. el:'#root',
    5. data:{
    6. name:'尚硅谷',
    7. },
    8. methods:{
    9. showInfo1(event){
    10. // console.log(event.target.innerText)
    11. // console.log(this) //此处的this是vm
    12. alert('同学你好!')
    13. },
    14. showInfo2(event,number){
    15. console.log(event,number)
    16. // console.log(event.target.innerText)
    17. // console.log(this) //此处的this是vm
    18. alert('同学你好!!')
    19. }
    20. }
    21. })
    22. script>

    事件修饰符

    Vue实例:

    1. <script type="text/javascript">
    2. Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
    3. new Vue({
    4. el:'#root',
    5. data:{
    6. name:'尚硅谷'
    7. },
    8. methods:{
    9. showInfo(e){
    10. alert('同学你好!')
    11. // console.log(e.target)
    12. },
    13. showMsg(msg){
    14. console.log(msg)
    15. },
    16. demo(){
    17. for (let i = 0; i < 100000; i++) {
    18. console.log('#')
    19. }
    20. console.log('累坏了')
    21. }
    22. }
    23. })
    24. script>
    • 1.prevent:阻止默认事件(常用);
    1. <a href="http://www.atguigu.com" @click.prevent="showInfo">点我提示信息a>

    • 2.stop:阻止事件冒泡(常用);

    事件冒泡:即多个组件嵌套,触发内层组件时,会一一触发外层事件,这个冒泡只会出现现在你这个元素的父元素上。正常情况下阻止事件冒泡:e.stopPropagation()  阻止父组件事件发生。

    1. <div class="demo1" @click="showInfo">
    2. <button @click.stop="showInfo">点我提示信息button>
    3. div>

     参考博客:事件冒泡(快速理解)

    • 3.once:事件只触发一次(常用;

    页面上有一个按钮,点了一次弹窗,以后再点的时候就不用弹窗了。

    1. <button @click.once="showInfo">点我提示信息button>

    • 4.capture:使用事件的捕获模式;

    如果想在捕获阶段就触发事件该怎么办?

    从水面到水底是捕获,泡泡从下到上是冒泡。捕获是从外往内的,冒泡是从内往外。

    1. <div class="box1" @click.capture="showMsg(1)">
    2. div1
    3. <div class="box2" @click="showMsg(2)">
    4. div2
    5. div>
    6. div>

    • 5.self:只有event.target是当前操作的元素时才触发事件;

    如果有人触发了div的click事件,并且e.target还得是当前div才能触发该事件。

    1. <div class="demo1" @click.self="showInfo">
    2. <button @click="showInfo">点我提示信息button>
    3. div>

    • 6.passive:事件的默认行为立即执行,无需等待事件回调执行完毕;

    @scroll:滚动条滚动                                                                                      @wheel:滚动轮滚动

            当滚动鼠标的滚轮之后,他首先去触发滚动的事件,然后去执行这个回调函数,这个回调函数执行完之后,他再去执行默认行为,在将那个滚动条滚动一下,整个过程就是我滚动鼠标滚轮,随后发demo函数调用,Demo函数调用了那个滚动条,再往下走一丢丢,但是在这个环节就浪费时间了,就会导致整个页面有点卡顿。

    1. demo(){
    2. for (let i = 0; i < 100000; i++) {
    3. console.log('#')
    4. }
    5. console.log('累坏了')
    6. }
    1. <ul @wheel.passive="demo" class="list">
    2. <li>1li>
    3. <li>2li>
    4. <li>3li>
    5. <li>4li>
    6. ul>

    键盘事件

    Vue实例:

    1. <script type="text/javascript">
    2. Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
    3. Vue.config.keyCodes.huiche = 13 //定义了一个别名按键
    4. new Vue({
    5. el:'#root',
    6. data:{
    7. name:'尚硅谷'
    8. },
    9. methods: {
    10. showInfo(e){
    11. // console.log(e.key,e.keyCode)
    12. console.log(e.target.value)
    13. }
    14. },
    15. })
    16. script>

    1.Vue中常用的按键别名:

                                回车 => enter

                                删除 => delete (捕获“删除”和“退格”键)

                                退出 => esc

                                空格 => space

                                换行 => tab (特殊,必须配合keydown去使用)

                                上 => up

                                下 => down

                                左 => lefts

                                右 => right

    2.Vue未提供别名的按键,可以使用按键原始的key值去绑定,但注意要转为kebab-case(短横线命名)

    3.系统修饰键(用法特殊):ctrl、alt、shift、meta

    (1).配合keyup使用:按下修饰键的同时,再按下其他键,随后释放其他键,事件才被触发。

    (2).配合keydown使用:正常触发事件。

    4.也可以使用keyCode去指定具体的按键(不推荐)

    5.Vue.config.keyCodes.自定义键名 = 键码,可以去定制按键别名

    1. <div id="root">
    2. <h2>欢迎来到{{name}}学习h2>
    3. <input type="text" placeholder="按下回车提示输入" @keyup.enter="showInfo">
    4. <input type="text" placeholder="按下回车提示输入" @keydown.huiche="showInfo"> //自定义回车
    5. <input type="text" placeholder="按下回车提示输入" @keyup.ctrl.y="showInfo"> //ctrl+y
    6. div>

    8.计算属性

    姓名案例

    页面里的输入要影响数据里的变化

    插值语法实现

    v-model:双向绑定

    1. <div id="root">
    2. 姓:<input type="text" v-model="firstName"> <br/><br/>
    3. 名:<input type="text" v-model="lastName"> <br/><br/>
    4. 全名:<span>{{firstName}}-{{lastName}}span>
    5. div>
    1. <script type="text/javascript">
    2. Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
    3. new Vue({
    4. el:'#root',
    5. data:{
    6. firstName:'张',
    7. lastName:'三'
    8. }
    9. })
    10. script>

            现在提出一个需求,输入的时候输入了很长一段字符,然后再计算全名的时候不需要这么长,也就是说不管姓名输入多少,我只要三位。

    全名:<span>{{firstName.slice(0,3)}}-{{lastName}}span>  //只截取0,1,2位置

    methods实现

            在插值语法里放入函数名(必须加括号),意思是把函数的返回值放到里面,而不是绑定事件(绑定事件的函数名可加括号也可不加),一定要分清楚自己写的到底是指令还是插值

    1. <div id="root">
    2. 姓:<input type="text" v-model="firstName"> <br/><br/>
    3. 名:<input type="text" v-model="lastName"> <br/><br/>
    4. 全名:<span>{{fullName()}}span>
    5. div>

            this指的是当前vue实例对象,data当中任何一个数据发生变化的时候,vue的模板都会重新解析一遍,当解析到fullname时,方法会重新调用一遍。

    1. <script type="text/javascript">
    2. Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
    3. new Vue({
    4. el:'#root',
    5. data:{
    6. firstName:'张',
    7. lastName:'三'
    8. },
    9. methods: {
    10. fullName(){
    11. console.log('@---fullName')
    12. return this.firstName + '-' + this.lastName
    13. }
    14. },
    15. })
    16. script>

    计算属性实现

            对于vue来讲,data里的数据叫做属性,所谓的计算属性,就是拿着你已经写完的属性去加工去计算,然后生成一个全新的属性,这就是计算属性。
            在vue当中属性和计算属性分开放,需要一个全新的配置项computed,配置的方法和data类似,需要写成对象的形式,把计算的整个过程写成对象。

    1. <div id="root">
    2. 姓:<input type="text" v-model="firstName"> <br/><br/>
    3. 名:<input type="text" v-model="lastName"> <br/><br/>
    4. 测试:<input type="text" v-model="x"> <br/><br/>
    5. 全名:<span>{{fullName}}span> <br/><br/>
    6. div>

            当你在读取full name的时候,vue会帮你调用get方法,还把get当中的this指向调成了vm,也就是这个vue实例。

            get有什么作用?当有人读取fullName时,get就会被调用,且返回值就作为fullName的值。

    1. <script type="text/javascript">
    2. Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
    3. const vm = new Vue({
    4. el:'#root',
    5. data:{
    6. firstName:'张',
    7. lastName:'三',
    8. x:'你好'
    9. },
    10. methods: {
    11. demo(){
    12. }
    13. },
    14. computed:{
    15. fullName:{
    16. //get有什么作用?当有人读取fullName时,get就会被调用,且返回值就作为fullName的值
    17. //get什么时候调用?1.初次读取fullName时。2.所依赖的数据发生变化时。
    18. get(){
    19. console.log('get被调用了')
    20. // console.log(this) //此处的this是vm
    21. return this.firstName + '-' + this.lastName
    22. },
    23. //set什么时候调用? 当fullName被修改时。
    24. set(value){
    25. console.log('set',value)
    26. const arr = value.split('-')
    27. this.firstName = arr[0]
    28. this.lastName = arr[1]
    29. }
    30. }
    31. }
    32. })
    33. script>

            这种情况下,理论上get会被调用四次,但是实际上get只被调用了一次,他读取到这个模板的时候,于是乎去调用get拿到返回值,然后就作为fullname的值去使用,随后他就做了一个缓存,剩余的fullname再去读取的时候不去调用get而是去读取缓存

     get什么时候调用?

            1.初次读取fullName时。

            2.所依赖的数据发生变化时。

            (比如对于fullname来讲,姓或者名做出更改的时候,会重新调用get方法,但是对于不被依赖的数据,例如x,更改x的值不会被重新调用get方法。)

            注意:data里面写啥就是啥,methods里写的是函数则显示函数,但是对于computed来讲,他自动去找到get并调用,拿到get的返回值,然后放在vm身上了,然后放的时候名字叫做fullname,不需要.get()

            get和set函数都是被vue所管理的函数,不要写成箭头函数。

    总结:

    计算属性:

            1.定义:要用的属性不存在,要通过已有属性计算得来。

            2.原理:底层借助了Objcet.defineproperty方法提供的getter和setter。

            3.get函数什么时候执行?

                    (1).初次读取时会执行一次。

                    (2).当依赖的数据发生改变时会被再次调用。

            4.优势:与methods实现相比,内部有缓存机制(复用),效率更高,调试方便。

            5.备注:

                    1.计算属性最终会出现在vm上,直接读取使用即可({{fullname}})。

                    2.如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生改变。

    计算属性简写

    1. <div id="root">
    2. 姓:<input type="text" v-model="firstName"> <br/><br/>
    3. 名:<input type="text" v-model="lastName"> <br/><br/>
    4. 全名:<span>{{fullName}}span> <br/><br/>
    5. div>

            一般情况下,数据只读取展示,不用来修改,一旦确定了计算属性只用来展示不用来修改,才可以用简写形式。

            不需要再将fullname写成一个配置对象,直接将其写成一个函数,这个函数就当getter用。当你写任何东西的时候,就问自己句话,我读的这个东西是个什么?是data中配置的数据?还是methods中配置的方法?还是computed里面配置的计算属性?计算属性不能加小括号。

    1. <script type="text/javascript">
    2. Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
    3. const vm = new Vue({
    4. el:'#root',
    5. data:{
    6. firstName:'张',
    7. lastName:'三',
    8. },
    9. computed:{
    10. //完整写法
    11. /* fullName:{
    12. get(){
    13. console.log('get被调用了')
    14. return this.firstName + '-' + this.lastName
    15. },
    16. set(value){
    17. console.log('set',value)
    18. const arr = value.split('-')
    19. this.firstName = arr[0]
    20. this.lastName = arr[1]
    21. }
    22. } */
    23. //简写
    24. fullName(){
    25. console.log('get被调用了')
    26. return this.firstName + '-' + this.lastName
    27. }
    28. }
    29. })
    30. script>

    9.监视属性

    天气案例

    @click后面可以写一些简单的语句,此时不用调用methods的方法。

    1. <div id="root">
    2. <h2>今天天气很{{info}}h2>
    3. <button @click="changeWeather">切换天气button>
    4. div>
    1. <script type="text/javascript">
    2. Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
    3. const vm = new Vue({
    4. el:'#root',
    5. data:{
    6. isHot:true,
    7. },
    8. computed:{
    9. info(){
    10. return this.isHot ? '炎热' : '凉爽'
    11. }
    12. },
    13. methods: {
    14. changeWeather(){
    15. this.isHot = !this.isHot //妙啊
    16. }
    17. },
    18. })
    19. script>

    监视属性

    之所以能做到天气的切换是因为在改变ishot的值

    1. <div id="root">
    2. <h2>今天天气很{{info}}h2>
    3. <button @click="changeWeather">切换天气button>
    4. div>

    监视属性watch:

            1.当被监视的属性变化时, 回调函数自动调用, 进行相关操作

            2.监视的属性必须存在,才能进行监视!(不仅可以监测data里的属性还可以监测计算属性)

            3.监视的两种写法:

    •                 (1).new Vue时传入watch配置
    1. const vm = new Vue({
    2. el:'#root',
    3. data:{
    4. isHot:true,
    5. },
    6. computed:{
    7. info(){
    8. return this.isHot ? '炎热' : '凉爽'
    9. }
    10. },
    11. methods: {
    12. changeWeather(){
    13. this.isHot = !this.isHot
    14. }
    15. },
    16. watch:{
    17. isHot:{
    18. immediate:true, //初始化时让handler调用一下
    19. //handler什么时候调用?当isHot发生改变时。
    20. handler(newValue,oldValue){
    21. console.log('isHot被修改了',newValue,oldValue)
    22. }
    23. }
    24. }
    25. })
    •                 (2).通过vm.$watch监视

    传两个参数,第一个参数就是要监视的东西,第二个是配置对象

    1. vm.$watch('isHot',{
    2. immediate:true, //初始化时让handler调用一下
    3. //handler什么时候调用?当isHot发生改变时。
    4. handler(newValue,oldValue){
    5. console.log('isHot被修改了',newValue,oldValue)
    6. }
    7. })

    深度监视

    深度监视:

        (1).Vue中的watch默认不监测对象内部值的改变(一层)。

        (2).配置deep:true可以监测对象内部值改变(多层)。

    备注:

        (1).Vue自身可以监测对象内部值的改变,但Vue提供的watch默认不可以

        (2).使用watch时根据数据的具体结构,决定是否采用深度监视。(数据简单不用开启)

    1. <div id="root">
    2. <h2>今天天气很{{info}}h2>
    3. <button @click="changeWeather">切换天气button>
    4. <hr/>
    5. <h3>a的值是:{{numbers.a}}h3>
    6. <button @click="numbers.a++">点我让a+1button>
    7. <h3>b的值是:{{numbers.b}}h3>
    8. <button @click="numbers.b++">点我让b+1button>
    9. <button @click="numbers = {a:666,b:888}">彻底替换掉numbersbutton>
    10. {{numbers.c.d.e}}
    11. div>

    监视多级结构中某个属性的变化 

    1. //加引号使之变为一个合法的key
    2. 'numbers.a':{
    3. handler(){
    4. console.log('a被改变了')
    5. }
    6. } */

    监视多级结构中所有属性的变化 

    1. numbers:{
    2. deep:true,
    3. handler(){
    4. console.log('numbers改变了')
    5. }
    6. }

    完整代码: 

    1. <script type="text/javascript">
    2. Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
    3. const vm = new Vue({
    4. el:'#root',
    5. data:{
    6. isHot:true,
    7. numbers:{
    8. a:1,
    9. b:1,
    10. c:{
    11. d:{
    12. e:100
    13. }
    14. }
    15. }
    16. },
    17. computed:{
    18. info(){
    19. return this.isHot ? '炎热' : '凉爽'
    20. }
    21. },
    22. methods: {
    23. changeWeather(){
    24. this.isHot = !this.isHot
    25. }
    26. },
    27. watch:{
    28. isHot:{
    29. // immediate:true, //初始化时让handler调用一下
    30. //handler什么时候调用?当isHot发生改变时。
    31. handler(newValue,oldValue){
    32. console.log('isHot被修改了',newValue,oldValue)
    33. }
    34. },
    35. //监视多级结构中某个属性的变化
    36. /* 'numbers.a':{
    37. handler(){
    38. console.log('a被改变了')
    39. }
    40. } */
    41. //监视多级结构中所有属性的变化
    42. numbers:{
    43. deep:true,
    44. handler(){
    45. console.log('numbers改变了')
    46. }
    47. }
    48. }
    49. })
    50. script>

    监视属性简写

    1. <div id="root">
    2. <h2>今天天气很{{info}}h2>
    3. <button @click="changeWeather">切换天气button>
    4. div>

    new Vue时传入watch配置 

    1. watch:{
    2. //正常写法
    3. isHot:{
    4. // immediate:true, //初始化时让handler调用一下
    5. // deep:true,//深度监视
    6. handler(newValue,oldValue){
    7. console.log('isHot被修改了',newValue,oldValue)
    8. }
    9. },
    10. //简写
    11. isHot(newValue,oldValue){
    12. console.log('isHot被修改了',newValue,oldValue,this)
    13. }
    14. }

    通过vm.$watch监视

    1. //正常写法
    2. vm.$watch('isHot',{
    3. immediate:true, //初始化时让handler调用一下
    4. deep:true,//深度监视
    5. handler(newValue,oldValue){
    6. console.log('isHot被修改了',newValue,oldValue)
    7. }
    8. })
    9. //简写
    10. vm.$watch('isHot',function(newValue,oldValue){
    11. console.log('isHot被修改了',newValue,oldValue,this)
    12. })

    姓名案例:watch实现

    computed和watch之间的区别:

            1.computed能完成的功能,watch都可以完成。

            2.watch能完成的功能,computed不一定能完成,例如:watch可以进行异步操作。

    两个重要的小原则:

            1.所被Vue管理的函数,最好写成普通函数,这样this的指向才是vm 或 组件实例对象。

            2.所有不被Vue所管理的函数(定时器的回调函数、ajax的回调函数等、Promise的回调函数),最好写成箭头函数,这样this的指向才是vm 或 组件实例对象。

    1. <div id="root">
    2. 姓:<input type="text" v-model="firstName"> <br/><br/>
    3. 名:<input type="text" v-model="lastName"> <br/><br/>
    4. 全名:<span>{{fullName}}span> <br/><br/>
    5. div>

    当姓改变的时候,全名延迟1s发生改变 ,watch可以畅快的使用异步任务而计算属性不行

    在普通函数中,this总是指向调用它的对象,如果用作构造函数,this指向创建的对象实例。

    箭头函数本身没有this,但是它在声明时可以捕获其所在上下文的this供自己使用。

  • 相关阅读:
    java面试小经历
    开源新工具 Azure Developer CLI
    Python源码剖析1-整数对象PyIntObject
    数字化底层逻辑揭秘!探寻地产工程行业发展新范式
    1400*C. Given Length and Sum of Digits...(贪心)
    maven的settings.xml和pom.xml配置文件详解
    一款非常容易上手的报表工具,简单操作实现BI炫酷界面数据展示,驱动支持众多不同类型的数据库,可视化神器,免开源了
    我的期末网页设计HTML作品——咖啡文化网页制作
    Java发送http请求报错: SSLException: Received fatal alert: internal_error
    opencv基础-印度小哥
  • 原文地址:https://blog.csdn.net/m0_52601969/article/details/126199820