• Vue2(二):计算属性、监视属性、二者的区别


    一、计算属性

    1. 使用插值语法和methods拼接姓名

    如果样式要求不多的话这样写没问题,如下代码是截取我输入的姓的前三个字母

    1. <div id="root">
    2. 姓:<input type="text" v-moudel="firstName">
    3. 名:<input type="text" v-moudel="lastName">
    4. 姓名:<span>{{firstName.slice(0,3)}}-{{lastName}}</span>
    5. </div>
    6. <script type="text/javascript">
    7. const vm=new Vue({
    8. el:'#root',
    9. data:{
    10. firstName:'hb',
    11. lastName:'bj'
    12. }
    13. })
    样式太多的话就都放进methods里面去

    注意:之前的showInfo是绑定事件,加不加()都行,现在是调用那个函数必须得加()

    每次改动firstName后者lastName就会重新解析模版,调用fullName

    1. <div id="root">
    2. 姓:<input type="text" v-model="firstName">
    3. 名:<input type="text" v-model="lastName">
    4. 姓名:<span>{{fullName()}}</span>
    5. </div>
    6. <script type="text/javascript">
    7. const vm=new Vue({
    8. el:'#root',
    9. data:{
    10. firstName:'hb',
    11. lastName:'bj'
    12. },
    13. methods:{
    14. fullName(){
    15. // this是vue实例,里面就有firstName啥的
    16. return this.firstName+'-'+this.lastName
    17. }
    18. }
    19. })

    2. 使用计算属性拼接姓名

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

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

    属性:vue认为data里面写的就是属性,属性:属性值,属性在vm._data里

    计算属性:就是拿着你已经写完的属性去加工计算,放在vm里,不在data里

    属性放在data里,计算属性放在computed

    1. <div id="root">
    2. 姓:<input type="text" v-model="firstName">
    3. 名:<input type="text" v-model="lastName">
    4. 姓名:<span>{{fullName}}</span>
    5. 姓名:<span>{{fullName}}</span>
    6. 姓名:<span>{{fullName}}</span>
    7. </div>
    8. <script type="text/javascript">
    9. const vm=new Vue({
    10. el:'#root',
    11. data:{
    12. firstName:'hb',
    13. lastName:'bj'
    14. },
    15. computed:{
    16. fullName: {
    17. get(){
    18. //读取fullName的时候自动调用get
    19. // 并且vue给你设置computed里的this是vm
    20. console.log('get被调用喽')
    21. return this.firstName+'-'+this.lastName
    22. }
    23. }
    24. }
    25. })

    如果这个时候我多次调用fullName的话,输出get被调用喽只显示一次,因为有缓存 

    get什么时候调用?(1)初次读取fullName 时,(2)所依赖的数据发生变化时,所以不用担心姓或者名变化fullName没变

    我用computed不是fullName对象.get函数!而是我用fullName的时候立马就调用get函数,返回一个值放在fullName(计算出来的新属性)身上,在vm中可以查看

    set什么时候调用?fullName被修改的时候,而且必须设置参数,你把fullName改成什么就返回什么

    1. set(value){
    2. const arr=value.split('-')
    3. this.firstName=arr[0]
    4. this.lastName=arr[1]
    5. //fullName依赖firstlast,想真正的改掉就得把谁算出来的改掉
    6. }

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

    备注:
    1.计算属性最终会出现在vm上,直接读取使用即可,不用加括号,和methods区别一下子。
    2.如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生改变,这很关键。

    3. 计算属性的简写

    计算属性一般不修改,确定只读不改就可以用简写

    姓名:<span>{{fullName}}span>
    1. computed:{
    2. fullName(){
    3. return this.firstName+'-'+this.lastName
    4. }
    5. }

    fullName是一个属性,不是一个方法,只不过是调用里面的getter,把返回值直接给了vm,所以直接{{fullName}}不可以加()!!

    data的数据,methods的方法,computed的计算属性

    二、监视属性

    1. 天气切换案例

    (1)利用插值语法和三元表达式

    1. <div id="root">
    2. <h2>今天天气很{{isHot?'炎热':'凉爽'}}</h2>
    3. <button>切换天气</button>
    4. </div>
    5. <script type="text/javascript">
    6. const vm=new Vue({
    7. el:'#root',
    8. data:{
    9. isHot:true
    10. }
    11. })

    (2)利用计算属性

    1. <div id="root">
    2. <h2>今天天气很{{info}}</h2>
    3. <button @click="change">切换天气</button>
    4. </div>
    5. <script type="text/javascript">
    6. const vm=new Vue({
    7. el:'#root',
    8. data:{
    9. isHot:true
    10. },
    11. computed:{
    12. info(){
    13. return this.isHot?'炎热':'凉爽'
    14. // isHot不是computed里的找不到,所以得this,就是vue的
    15. }
    16. },
    17. methods:{
    18. change(){
    19. this.isHot=!this.isHot;
    20. }
    21. }
    22. })

    不需要methods也可以这样写:

    <button @click="isHot=!isHot">切换天气</button>

    @xxx:yyy绑定事件的时候可以写一些简单的语句

    2. 监视属性

    (1)watch

    1. watch:{
    2. isHot:{
    3. immediate:true,
    4. //初始化时让handler调用
    5. //当isHot发生改变时它就调用
    6. handler(newValue,oldValue){
    7. console.log('isHot改了',newValue,oldValue)
    8. }
    9. }
    10. }

    用handler的时候同时返回两个参数newValue和oldValue

    (2)vm.$watch

    1. const vm=new Vue({
    2. el:'#root',
    3. data:{
    4. isHot:true
    5. },
    6. computed:{
    7. info(){
    8. return this.isHot?'炎热':'凉爽'
    9. // isHot不是computed里的找不到,所以得this,就是vue的
    10. }
    11. },
    12. })
    13. vm.$watch('isHot',{
    14. immediate:true,
    15. //初始化时让handler调用
    16. //当isHot发生改变时它就调用
    17. handler(newValue,oldValue){
    18. console.log('isHot改了',newValue,oldValue)
    19. }
    20. })

    第一个参数是对象名,第二个参数是配置对象

    区别:很明确坚实谁就写第一种,否则就写第二种

    3. 深度监视

    (1).Vue中的watch默认不监测对象内部值的改变(一层,如果监视那么对象地址不变就不变)。
    (2).配置deep:true可以监测对象内部值改变(多层)。
    (3).Vue自身可以监测对象内部值的改变,但Vue提供的watch默认不可以!想要可以就要手动开启deep:true
    (4).使用watch时根据数据的具体结构,决定是否采用深度监视。

    1. <div id="root">
    2. <h3>a的值是:{{numbers.a}}</h3>
    3. <button @click="numbers.a++">点我实现a+1</button>
    4. <h3>b的值是:{{numbers.b}}</h3>
    5. <button @click="numbers.b++">点我实现b+1</button>
    6. </div>
    7. <script type="text/javascript">
    8. new Vue({
    9. el:'#root',
    10. data:{
    11. isHot:true,
    12. numbers:{
    13. a:1,
    14. b:1
    15. }
    16. },
    17. watch:{
    18. //监视多级结构中某个属性的变化
    19. numbers:{
    20. //不加引号报错是因为本来就应该加引号写,有的中间不带.的简写了没加
    21. // 如果想要给b也加的话,一个一个写太麻烦了,但是发现直接给number
    22. // 改变a或者bnumber都不输出,因为它没有深入的去看a或b的变化
    23. deep:true,//监视多级结构中所有属性的变化
    24. handler(){
    25. console.log('number改了')
    26. }
    27. }
    28. }
    29. })
    30. </script>

    4.监视的简写形式

    用简写的前提是不需要immediate也不需要deep

    (1)watch写法

    1. watch:{
    2. isHot(newValue,oldValue){
    3. console.log('isHot被改了')
    4. }
    5. }

    (2)$watch写法

    1. vm.$watch('isHot',function(newValue,oldValue)
    2. {
    3. console.log('isHot被改了')
    4. })

    三、watch对比computed

    1.watch

    1. <div id="root">
    2. 姓:<input type="text" v-model="firstName">
    3. 名: <input type="text" v-model="lastName">
    4. 全名: <span>{{fullName}}</span>
    5. </div>
    6. <script type="text/javascript">
    7. new Vue({
    8. el:'#root',
    9. data:{
    10. firstName:'张',
    11. lastName:'三',
    12. fullName:'张-三'
    13. },
    14. watch:{
    15. firstName(newValue){
    16. this.fullName=newValue+'-'+this.lastName
    17. },
    18. lastName(newValue){
    19. this.fullName=this.firstName+'-'+newValue
    20. }
    21. }
    22. })

    监视姓的同时还是监视名

    2.computed 

    1. computed:{
    2. fullName: {
    3. get(){
    4. console.log('get被调用喽')
    5. return this.firstName+'-'+this.lastName
    6. }
    7. }
    8. }

    加一下就完事了,但是computed计算属性里面不能开启异步任务去维护数据的,靠的就是返回值,watch就可以开延迟什么的。

    1. firstName(newValue){
    2. setTimeout(()=>{
    3. this.fullName=newValue+'-'+this.lastName
    4. },1000)

    总结:

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

    两个重要的小原则!
    1、所被Vue管理的函数,最好写成普通函数,这样this的指向才是vm 或 组件实例对象。
    2、所有不被Vue所管理的函数(定时器的回调函数、ajax的回调函数等、Promise的回调函数),最好写成箭头函数,这样this的指向才是vm 或 组件实例对象

  • 相关阅读:
    在昇腾平台上对TensorFlow网络进行性能调优
    Ubuntu22.2下C语言编程实现,首次,最佳适应算法
    算法设计与分析 | 页码统计
    27、Block-NeRF: Scalable Large Scene Neural View Synthesis
    自学JavaScript第一天- JS 基础
    关于如何检查一个进程是否存活
    宏观经济和风电预测误差分析(Matlab代码实现)
    (学习日记)2022.8.11
    JUC下的常用类
    非零基础自学Java (老师:韩顺平) 第8章 面向对象编程(中级部分) 8.8 面向对象编程 - 继承
  • 原文地址:https://blog.csdn.net/Hdhhdhbsjxbdhvyg/article/details/136758675