目录
watch侦听器允许开发者监视数据的变化,从而针对数据的变化做特定的操作。
语法格式如下:
- const vm = new Vue({
- el:'#app',
- data:{
- username: ''
- },
- watch:{
- // 监听 username 值的变化
- //newVal 是变化后的新值, oldVal 是变化之前的旧值
- uesrname(newVal, oldVal) {
- console.log(newVal, oldVal);
-
- }
- }
- })
监听数据变化,一般只监听一个变量或数组
使用场景:watch(异步场景
),computed(数据联动
) watch可以在所监听的数据后面直接加字符串形式的方法名
- DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8" />
- <title>title>
- <script src="../vue.js" type="text/javascript" charset="utf-8">script>
- head>
- <body>
- <div id="app">
- <h3>{{firstName}}h3>
- div>
- <script>
- const vm = new Vue({
- el: '#app',
- data() {
- return {
- firstName: "zhang",
- lastName: "san",
- watchFullName: "zhangsan",
- age: 18,
- }
- },
- watch:{
- firstName(newVal, oldVal){
- console.log(newVal);
- console.log(oldVal);
- }
- },
- })
- script>
- body>
- html>
使用如下方法也可实现上图效果:
使用侦听器监听 firstName 数据里字符串形式的change 方法名
watch:{
firstName:'change'
},
methods:{
change(newVal, oldVal){
console.log(newVal);
console.log(oldVal);
}
}
handler方法就相当于普通侦听器触发的事件,从结果可以看到,组件初始化的时候,侦听器并没有handler方法 ,所以fullName是没有值的
当修改以上代码,加上immediate: true,immediate:true代表watch里面声明了之后会立马执行handler里面的函数。执行相应的逻辑。组件初始化的时候,侦听器会立马(immediate)触发handler方法
- DOCTYPE html>
-
-
-
-
-
-
Vue计算属性/侦听器/方法比较 -
-
-
-
-
-
FullName: {{person.fullname}}
-
FirstName:
-
-
-
- var other = 'This is other';
- var app = new Vue({
- el: '#app',
- data(){
- return {
- person: {
- firstname: 'Menghui',
- lastname: 'Jin',
- fullname: ''
- }
- }
- },
- watch: {
- person: {
- handler(n,o){
- this.person.fullname = n.firstname + '' + this.person.lastname;
- },
- immediate: true, //刷新加载 立马触发一次handler
- deep: true // 可以深度检测到 person 对象的属性值的变化
- }
- }
- })
-
-
-
immediate 的作用是:控制侦听器是否自动触发一次,默认值是 false
当在输入框中输入数据时, 可以发现fullName的值并没有随之改变 。这是因为vue无法检测到对象内部属性值的变化,比如person.firstname的变化;所以此时 需要用到vue的深度监听(deep)此时加上代码 deep: true可以发现 每次输入框数据变化 fullname随之改变,上面的可以发现handler监听的新值和老值是一样的 这是有vue2.0的坑 犹豫同源导致的 可以用computed来修改
- DOCTYPE html>
-
-
-
-
-
-
-
-
FullName: {{person.fullname}}
-
FirstName:
-
-
-
- const app = new Vue({
- el: "#app",
- data() {
- return {
- person: {
- firstname: 'Menghui',
- lastname: 'Jin',
- fullname: ''
- }
- }
- },
- methods: {
-
- },
- computed: {
- person2(){
- return JSON.parse(JSON.stringify(this.person));
- }//解决深度监听新老值同源问题
- },
- watch:{
- person2:{
- handler(n,o){
- console.log(this.person);
- console.log(n.firstname);
- console.log(o.firstname);
-
- /* this.person.fullname = this.person.firstname + this.person.lastname */
- },
- /* immediate: true, */
- deep: true // 可以深度检测到 person 对象的属性值的变化
- }
- }
- })
-
-
- DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8" />
- <title>title>
- <script src="js/vue.js" type="text/javascript" charset="utf-8">script>
- head>
- <body>
- <div id="app">
- <h1>计算属性:computedh1>
- {{fullName}}
- <h1>方法:methodsh1>
- {{fullName2()}}
- <h1>侦听器:watchh1>
- {{watchFullName}}
- <h1>年龄:ageh1>
- {{age}}
- div>
- <script>
- var other = 'This is other';
- const vm = new Vue({
- el: "#app",
- data() {
- return {
- firstName: "zhang",
- lastName: "san",
- watchFullName: "zhangsan",
- age: 18,
- }
- },
- methods: {
- fullName2() {
- console.log("调用了fullName2,使用了一次方法")
- return this.firstName + this.lastName + ','+other
- }
- },
- computed: {
- fullName() {
- console.log("调用了fullName,计算了一次属性")
- return this.firstName + this.lastName + ','+other
- }
- },
- watch: {
- firstName(newfirstname,oldfirstname){
- console.log('firstName触发了watch');
- this.watchFullName = this.firstName+this.lastName+ ','+other
- },
- lastName(newlastname,oldlastname){
- console.log('lastName触发了watch');
- this.watchFullName = this.firstName+this.lastName+ ','+other
- },
- }
-
- })
- script>
- body>
- html>
初始化:
修改firstName/lastName/两者都修改
修改computed中没计算的age
修改Vue实例外的对象
修改Vue实例外对象后在修改Vue实例内的对象
测试结论:
- 使用computed计算了fullName属性,值为firstName+lastName。计算属性具有
缓存功能
,当firstName和lastName都不改变的时候,fullName不会重新计算,比如我们改变age的值,fullName的值是不需要重新计算的。- methods并没有缓存特性,比如我们改变age的值,fullName2()方法会被执行一遍。
- 当一个功能可以用上面三个方法来实现的时候,明显使用computed更合适,代码简单也有缓存特性。
- 计算属性范围在vue实例内,修改vue实例外部对象,不会重新计算渲染,但是如果先修改了vue实例外对象,在修改vue计算属性的对象,那么外部对象的值也会重新渲染。