Vue 的API-选项/数据

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/devincob/article/details/85103702

在这里插入图片描述
------------------------------------------------------------------------------官网示例------------------------------------------------------------------------------

var vm = new Vue({
  data: {
    a: 1,
    b: 2,
    c: 3,
    d: 4,
    e: {
      f: {
        g: 5
      }
    }
  },
  watch: {
    a: function (val, oldVal) {
      console.log('new: %s, old: %s', val, oldVal)
    },
    // 方法名
    b: 'someMethod',
    // 深度 watcher
    c: {
      handler: function (val, oldVal) { /* ... */ },
      deep: true
    },
    // 该回调将会在侦听开始之后被立即调用
    d: {
      handler: function (val, oldVal) { /* ... */ },
      immediate: true
    },
    e: [
      function handle1 (val, oldVal) { /* ... */ },
      function handle2 (val, oldVal) { /* ... */ }
    ],
    // watch vm.e.f's value: {g: 5}
    'e.f': function (val, oldVal) { /* ... */ }
  }
})
vm.a = 2 // => new: 2, old: 1

注意,不应该使用箭头函数来定义 watcher 函数 (例如 searchQuery: newValue => this.updateAutocomplete(newValue))。理由是箭头函数绑定了父级作用域的上下文,所以 this 将不会按照期望指向 Vue 实例,this.updateAutocomplete 将是 undefined。

什么时候用深度监听
watch:{} 对象,可监听数据,数据发生变化, 处理函数
目的: watch虽可监听,但只是浅监听,只监听数据第一层或者第二层,
何为第二层?

 let obj = {name: 'xx', child: {age: 11}};

child之后的值就为第二层或者深层
如果要实现 监听一个对象中的属性,属性最高也是第二层了,watch可能监听不到,所以要使用深度监听。
实现代码:

watch: {
'user.phone ' : {
	handler:function() {   //特别注意,不能用箭头函数,箭头函数,this指向全局处理函数},
	deep: true    //深度监听
}
}

--------------------------------------------------------------示例:监听&深度监听----------------------------------------------------------------------------
在这里插入图片描述
在这里插入图片描述
handler方法
watch 的一个特点是,最初绑定的时候是不会执行的,要等到 被监听的值 改变时才执行监听计算。
那我们想要一开始就让他最初绑定的时候就执行改怎么办呢?
解决办法是:修改一下我们的 watch 写法,给被监听值绑定了一个handler方法。
之前我们写的 watch 方法其实默认写的就是这个handler,Vue.js会去处理这个逻辑,最终编译出来其实就是这个handler。
immediate属性
immediate:true代表如果在 wacth 里声明了 被监听值 之后,就会立即先去执行里面的handler方法,如果为 false就跟我们以前的效果一样,不会在绑定的时候就执行。
deep属性
watch 里面还有一个属性 deep,默认值是 false,代表是否深度监听。
deep的意思就是深入观察,监听器会一层层的往下遍历,给对象的所有属性都加上这个监听器,但是这样性能开销就会非常大,任何修改 被监听对象 里面任何一个属性 都会触发这个监听器里的 handler。

优化:,可以使用字符串形式监听。
这样Vue.js会一层一层解析下去,直到遇到 属性 x,然后才给 x 设置监听函数。
注销watch
为什么要注销 watch?
因为我们的组件是经常要被销毁的,比如我们跳一个路由,从一个页面跳到另外一个页面,那么原来的页面的 watch 其实就没用了,这时候我们应该注销掉原来页面的 watch 的,不然的话可能会导致内置溢出。
不过我们平时 watch 都是写在组件的选项中的,他会随着组件的销毁而销毁

但是,如果我们使用下面这样的方式写 watch,那么就要手动注销了,这种注销其实也很简单

const unWatch = app.$watch('text', (newVal, oldVal) => {
  console.log(`${newVal} : ${oldVal}`);
})
unWatch(); // 手动注销watch

app.$watch调用后会返回一个值,就是unWatch方法,你要注销 watch 只要调用unWatch方法就可以了。

------------------------------------------------------------------------------props---------------------------------------------------------------------------------
在这里插入图片描述
------------------------------------------------------------------------------props示例---------------------------------------------------------------------------------
在这里插入图片描述

在这里插入图片描述
--------------------------------------------------------------------------computed---------------------------------------------------------------------------------
在这里插入图片描述
--------------------------------------------------------------------------computed示例---------------------------------------------------------------------------------
在这里插入图片描述
在这里插入图片描述
-----------------------------------------------------------------------method--------------------------------------------------------------------------------------
在这里插入图片描述
---------------------------------------------------------------------------method示例----------------------------------------------------------------------------
在这里插入图片描述
在这里插入图片描述
-----------------------------------------------------------浅析Vue中computed与method的区别-----------------------------------------------------------
一、在官方文档中,强调了computed区别于method最重要的两点

  1. computed是属性调用,而methods是函数调用
  2. computed带有缓存功能,而methods不是
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="app">
   <h1>{{message}}</h1>
    <p class="test1">{{methodTest}}</p>
    <p class="test2-1">{{methodTest()}}</p>
    <p class="test2-2">{{methodTest()}}</p>
    <p class="test2-3">{{methodTest()}}</p>
    <p class="test3-1">{{computedTest}}</p>
    <p class="test3-2">{{computedTest}}</p>
</div>
<script>
  var vm2=new Vue({
    el:"#app",
    data:{message: '我是消息'},
    computed: {
      computedTest() {
        return this.message + '现在我用的是computed'
      }
    },
    methods:{
      methodTest() {
        return this.message + '现在我用的是methods'
      }
    }
  });
</script>
</body>
</html>

二、computed的属性调用
在HTML的插值里,computed定义的方法我们是以属性访问的形式调用的,{{computedTest}}
但是methods定义的方法,我们必须要加上()来调用,如{{methodTest()}},否则,视图会出现

function () { [native code] }

三、 computed的缓存功能
首先,我们要明白缓存究竟有什么用?
相比大家都知道HTTP缓存,其核心作用就是对一些服务端未更新的资源进行复用,避免一些无谓的请求,优化了用户的体验

对于computed也是一样的:
在上面的例子中, methods定义的方法是以函数调用的形式来访问的,那么test2-1,test2-2,test2-3是反复地将methodTest方法运行了三遍,如果我们碰到一个场景,需要1000个methodTest的返回值,那么毫无疑问,这势必造成大量的浪费
更恐怖的是,如果你更改了message的值,那么这1000个methodTest方法每一个又会重新计算。。。。

所以,官方文档反复强调对于任何复杂逻辑,你都应当使用计算属性

computed依赖于data中的数据,只有在它的相关依赖数据发生改变时才会重新求值

如上例,在Vue实例化的时候,computed定义computedTest方法会做一次计算,返回一个值,在随后的代码编写中,只要computedTest方法依赖的message数据不发生改变,computedTest方法是不会重新计算的,也就是说test3-1,test3-2是直接拿到了返回值,而非是computedTest方法重新计算的结果。

同样,如果我们碰到一个场景,需要1000个computedTest的返回值,那么毫无疑问,对于methods而言,将调用计算1000次,大大消耗内存,对于computed而言,哪怕你改变了message的值,computedTest也只会计算一次而已

四、. computed的其它说明

  1. computed其实是既可以当做属性访问也可以当做方法访问
  2. computed的由来有一个重要原因,就是防止文本插值中逻辑过重,导致不易维护
    ------------------------------------------------------------------------------data---------------------------------------------------------------------------------

在这里插入图片描述

------------------------------------------------------------------------------官网示例---------------------------------------------------------------------------------

var data = { a: 1 }

// 直接创建一个实例
var vm = new Vue({
  data: data
})
vm.a // => 1
vm.$data === data // => true

// Vue.extend() 中 data 必须是函数
var Component = Vue.extend({
  data: function () {
    return { a: 1 }
  }
})

注意,如果你为 data 属性使用了箭头函数,则 this 不会指向这个组件的实例,不过你仍然可以将其实例作为函数的第一个参数来访问。

data: vm => ({ a: vm.myProp })

猜你喜欢

转载自blog.csdn.net/devincob/article/details/85103702