What are listeners for?

The theory is that when the information being listened for changes, the listener’s callback function is triggered to perform subsequent operations in the listener’s callback function.

Typical scenario:

When the routing parameters change, the interface is called again to get the component’s data

Does this operation compute the property? Obviously not, because computing properties can only handle synchronous operations, whereas calling the interface’s operations to fetch component data is asynchronous, and that’s where the listener comes in.

This shows that listeners will be used a lot, so be sure to master them!

<template>
  <div>Listener exercise</div>
  <hr>
<div>{{count}}</div>
<button @click="count++">Click on the</button>
</template>
Copy the code
import { ref, watch } from 'vue'
export default {
  name: 'App',
  setup () {
    const count = ref(0)
    // Listen for data changes based on listeners
    // There is a basic rule for watch: the data being listened on must be responsive
    watch(count, (newValue, oldValue) = > {
      // newValue indicates the newValue
      // oldValue indicates the value before modification
      console.log(newValue, oldValue)
    })
    return { count }
  }
}
Copy the code

This is just listening for basic data types

When listening for object type data

<template>
  <div>{{obj.msg}}</div>
   <button @click="handleClick">Listen to the object</button>
</template>
Copy the code
import { watch, reactive } from 'vue'
export default {
  name: 'App',
  setup () {
  // Create a responsive object obj
    const obj = reactive({
      msg: 'tom'
    })
    // Click to change MSG to 'jerry
    const handleClick = () = > {
      obj.msg = 'jerry'
    }
    // listen for obj changes
    watch(obj, (nVal, oVal) = > {
    // The new value is the same as the old value
      console.log(nVal, oVal)
    })
    return { count, obj, handleClick }
  }
}
Copy the code

Reason: If you are listening on an object, then the two arguments to the listener’s callback have the same result, representing the latest object data. In this case, you can also read the object being listened on directly, so that the value is also the latest value.

So there is no need to use parameters, just listen through the object point property method

 // listen for obj changes
    watch(obj, () = > {
    console.log(obj.msg)
    })
Copy the code

The third scenario for listeners, when listening for multiple values:

<template>
<div>{{n1}}</div>
<div>{{n2}}</div>
<button @click="handleClick">Listen to the object</button>
</template>
Copy the code
import { ref, watch} from 'vue'
export default {
  name: 'App',
  setup () {
    // Listen for multiple values
    const n1 = ref(1)
    const n2 = ref(2)
    const handleClick = () = > {
      n1.value = 3
      n2.value = 4
    }
    // Listen for multiple values wrapped in an array
    watch([n1, n2], (V1, v2) = > {
    // Listen and get the new array value
      consoleThe log (v1, v2)// the parameter v1 represents the latest value
      // Parameter v2 represents the original value
    })
    return { handleClick, n1, n2 }
  }
}
Copy the code

This is useful when you need to listen for multiple values, and the first argument to the listener can receive an array of results, in the same order.

Listen for a single property of an object

<template>
  <div>Listener exercise</div>
  <hr>
<div>{{stuInfo.uname + '===' + stuInfo.age}}</div>
<button @click="handleClick">Click on the</button>
</template>
Copy the code
import { reactive, watch } from 'vue'
export default {
  name: 'App',
  setup () {
    const stuInfo = reactive({
      uname: 'lisi'.age: 12
    })
    const handleClick = () = > {
      stuInfo.age = 13
    }
    // If you are listening for an expression, use a function
    // Listening for too much data can affect performance, so if you really need to listen for one of the objects, you can write it as follows
    watch(() = > stuInfo.age, (v1, v2) = > {
      // The new value and the old value can be obtained
      console.log(v1, v2)
    })
    return { stuInfo, handleClick }
  }
}
Copy the code

Summary: If you listen for a single property in an object and need to use a function approach, listening for less data improves performance.

watchMethod configuration options (second argument to Watch)

<template>
  <div>Listener exercise</div>
  <hr>
<div>{{stuInfo.uname + '===' + stuInfo.age}}</div>
<div>{{stuInfo.friend.uname}}</div>
<button @click="handleClick">Click on the</button>
</template>
Copy the code
import { reactive, watch } from 'vue'
export default {
  name: 'App',
  setup () {
    const stuInfo = reactive({
      uname: 'lisi'.age: 12.friend: {
        uname: 'zhangsan'}})const handleClick = () = > {
      stuInfo.age = 13
      stuInfo.friend.uname = 'wangwu'
    }
    // If you are listening for an expression, use a function
    // Listening for too much data can affect performance, so if you really need to listen for one of the objects, you can write it as follows
    watch(() = > stuInfo.age, (v1, v2) = > {
      // The new value and the old value can be obtained
      console.log(v1, v2)
    })

    watch(() = > stuInfo.friend, () = > {
      // The listener callback is not called as soon as it comes in, if it needs to be
      console.log('stuInfo')
      {immediate: true}}
      // Change the value in friend to see if the listener prints
      // Change the name, but do not listen
      // Add another option: deep:true for deep listening
    }, {
      // Call the listener callback immediately
      // Immediately after the component is rendered
      immediate: true.// The listener must be written as a function ()=> stuinfo.friend
      deep: true
    })
    return { stuInfo, handleClick }
  }
}
Copy the code

Here’s an important point: When using deep listening, make sure that what is being listened on is written as a function:

() => stuInfo.friend
Copy the code

Summary:

1. Immediate :true, which indicates that the component is called immediately upon rendering. 2. Deep :true, which indicates that the subproperties of the object are listened to in depth.