亚洲视频二区_亚洲欧洲日本天天堂在线观看_日韩一区二区在线观看_中文字幕不卡一区

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.430618.com 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢(xún)客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

大家好,本篇文章我們繼續(xù)學(xué)習(xí)和 Vue 相關(guān)的內(nèi)容,今天我們歸納總結(jié)下如何使用 watch 監(jiān)聽(tīng)組件中的數(shù)據(jù)變化,以及 computed 和 watch 的區(qū)別。

什么是 watch,以及如何使用?

watch 是 Vue.js 中用于監(jiān)聽(tīng)數(shù)據(jù)變化的一種機(jī)制。它允許我們?cè)跀?shù)據(jù)發(fā)生變化時(shí)執(zhí)行特定的操作。

在 Vue 中使用 watch 的方法如下:

1.在 Vue 組件中,定義一個(gè) watch 對(duì)象,其中包含要監(jiān)聽(tīng)的數(shù)據(jù)屬性以及對(duì)應(yīng)的回調(diào)函數(shù)。

watch: {
  dataName: function(newValue, oldValue) {
    // code
  }
}

其中,dataName 是要監(jiān)聽(tīng)的數(shù)據(jù)名稱(chēng),newValue 是新的值,oldValue 是舊的值。

2.在 Vue 實(shí)例中,使用 $watch() 方法進(jìn)行監(jiān)聽(tīng)

vm.$watch('someData', function(newVal, oldVal) {
  // do something with newVal
});

注意:watch 回調(diào)函數(shù)會(huì)在偵聽(tīng)的數(shù)據(jù)發(fā)生變化時(shí)立即執(zhí)行,而 computed 屬性只有在其依賴(lài)的數(shù)據(jù)發(fā)生變化時(shí)才會(huì)計(jì)算。

watch 通常用于監(jiān)聽(tīng)一個(gè)數(shù)據(jù)的變化并執(zhí)行復(fù)雜的業(yè)務(wù)邏輯,例如在某個(gè)數(shù)據(jù)變化后需要進(jìn)行 HTTP 請(qǐng)求或者調(diào)用其他函數(shù)。

下面是一個(gè)簡(jiǎn)單的 watch 的例子:

<template>
  <div>
    <input v-model="message" type="text" placeholder="請(qǐng)輸入內(nèi)容">
    <p>{{ message }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: '',
    }
  },
  watch: {
    message: function (newVal, oldVal) {
      console.log('message changed from ' + oldVal + ' to ' + newVal)
    }
  },
}
</script>

在這個(gè)例子中,我們使用了 watch 來(lái)監(jiān)聽(tīng) message 的變化,并在數(shù)據(jù)變化時(shí)打印出更改前后的值。

當(dāng)然,watch 還可以接收一個(gè)對(duì)象,其中可以定義多個(gè)監(jiān)聽(tīng)器。這里有一個(gè)例子,它監(jiān)聽(tīng)了多個(gè)數(shù)據(jù):

watch: {
  firstName: function (newVal, oldVal) {
    console.log('firstName changed from ' + oldVal + ' to ' + newVal)
  },
  lastName: function (newVal, oldVal) {
    console.log('lastName changed from ' + oldVal + ' to ' + newVal)
  }
}

一些高級(jí)用法介紹

1、深度觀察 (deep: true):如果你希望對(duì)對(duì)象內(nèi)部屬性的變化進(jìn)行監(jiān)聽(tīng),可以使用 deep: true 選項(xiàng)。

data() {
  user: {
    name: 'John',
    age: 25
  }
},
watch: {
  'user.name': function (val) {
    console.log('user name changed:', val)
  }
}

在這個(gè)例子中,我們監(jiān)聽(tīng)了 user 對(duì)象中的 name 屬性,當(dāng)該屬性變化時(shí),會(huì)執(zhí)行回調(diào)函數(shù)。

2、設(shè)置初始值 (immediate: true):如果你希望 watch 在組件創(chuàng)建時(shí)立即執(zhí)行一次,可以使用 immediate: true 選項(xiàng)。

data() {
    count: 0
},
watch: {
    count: {
        handler: function (val, oldVal) {
            console.log('count changed');
        },
        immediate: true
    }
}

3、異步處理 (handler):watch 的回調(diào)函數(shù)是異步執(zhí)行的,這意味著如果有多個(gè)值在短時(shí)間內(nèi)發(fā)生變化,回調(diào)函數(shù)只會(huì)在這些變化結(jié)束后執(zhí)行一次。

watch: {
  searchText: function (val) {
    this.searching = true
    setTimeout(() => {
      this.searchData(val)
      this.searching = false
    }, 500)
  }
}

在這個(gè)例子中,我們監(jiān)聽(tīng)了 searchText 屬性,并在數(shù)據(jù)變化后延遲 500 毫秒執(zhí)行搜索操作。

4、使用 watch 觀察器實(shí)現(xiàn)自動(dòng)保存

data() {
  content: ''
},
watch: {
  content: function (val) {
    localStorage.setItem('content', val)
  }
}

在這個(gè)例子中,我們監(jiān)聽(tīng)了 content 屬性,并在數(shù)據(jù)變化時(shí)自動(dòng)保存到本地存儲(chǔ)中。

應(yīng)用場(chǎng)景介紹

watch 監(jiān)聽(tīng)器還有許多其他的應(yīng)用場(chǎng)景,例如:

  • 在表單輸入時(shí)進(jìn)行驗(yàn)證,并顯示錯(cuò)誤消息
  • 在表格中進(jìn)行排序和過(guò)濾
  • 在地圖上實(shí)時(shí)顯示用戶(hù)位置
  • 監(jiān)聽(tīng)路由變化并執(zhí)行相應(yīng)操作
  • 監(jiān)聽(tīng)窗口大小變化并調(diào)整布局
  • 監(jiān)聽(tīng)滾動(dòng)事件并實(shí)現(xiàn)懶加載
  • ……

1.在表單輸入時(shí)進(jìn)行驗(yàn)證,并顯示錯(cuò)誤消息

<template>
  <form>
    <label>
      EmAIl:
      <input v-model="email" @keyup="validateEmail"/>
    </label>
    <p v-if="error">{{ error }}</p>
  </form>
</template>

<script>
export default {
  data() {
    return {
      email: '',
      error: ''
    }
  },
  watch: {
    email: {
      immediate: true,
      handler(val) {
        if (!val.includes('@')) {
          this.error = 'Invalid email address'
        } else {
          this.error = ''
        }
      }
    }
  }
}
</script>

2.在地圖上實(shí)時(shí)顯示用戶(hù)位置

<template>
  <div>
    <div id="map"></div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      userLocation: {
        lat: 0,
        lng: 0
      },
      map: null
    }
  },
  mounted() {
    this.map = new google.maps.Map(document.getElementById("map"), {
      center: { lat: 0, lng: 0 },
      zoom: 8
    });
    navigator.geolocation.getCurrentPosition(position => {
      this.userLocation = {
        lat: position.coords.latitude,
        lng: position.coords.longitude
      }
    });
  },
  watch: {
    userLocation: {
      deep: true,
      handler(val) {
        this.map.setCenter(val);
        new google.maps.Marker({
          position: val,
          map: this.map
        });
      }
    }
  }
}
</script>

在這個(gè)示例中,我們使用了 watch 來(lái)監(jiān)聽(tīng) userLocation 的變化,在用戶(hù)位置發(fā)生變化時(shí),使用 setCenter 方法將地圖中心設(shè)置為用戶(hù)當(dāng)前位置,并使用 google maps API 在地圖上添加一個(gè)標(biāo)記,顯示用戶(hù)當(dāng)前位置。

注意:這個(gè)例子需要引入 google maps 的 js 文件。

3、監(jiān)聽(tīng)路由變化并執(zhí)行相應(yīng)操作

<template>
  <!-- 省略 -->
</template>

<script>
export default {
  watch: {
    $route(to, from) {
      // 根據(jù)路由變化執(zhí)行相應(yīng)操作
      if (to.path === '/home') {
        this.getHomeData()
      } else if (to.path === '/about') {
        this.getAboutData()
      }
    }
  },
  methods: {
    getHomeData() {
      // 獲取首頁(yè)數(shù)據(jù)
    },
    getAboutData() {
      // 獲取關(guān)于頁(yè)數(shù)據(jù)
    }
  }
}
</script>

4、監(jiān)聽(tīng)窗口大小變化并調(diào)整布局

<template>
  <!-- 省略 -->
</template>

<script>
export default {
  data() {
    return {
      windowWidth: 0
    }
  },
  created() {
    this.windowWidth = window.innerWidth
  },
  watch: {
    windowWidth(newWidth, oldWidth) {
      // 監(jiān)聽(tīng)窗口大小變化并調(diào)整布局
      if (newWidth < 768) {
        // 小屏幕布局
      } else {
        // 大屏幕布局
      }
    }
  },
  mounted() {
    window.addEventListener('resize', () => {
      this.windowWidth = window.innerWidth
    })
  }
}
</script>

5、監(jiān)聽(tīng)滾動(dòng)事件并實(shí)現(xiàn)懶加載

<template>
  <div class="container" ref="container" @scroll="handleScroll">
    <img v-for="(item, index) in images" :key="index" :src="item.src" v-show="item.isLoaded" />
  </div>
</template>

<script>
export default {
  data() {
    return {
      images: [
        { src: 'image1.jpg', isLoaded: false },
        { src: 'image2.jpg', isLoaded: false },
        { src: 'image3.jpg', isLoaded: false },
        // ...
      ]
    }
  },
  mounted() {
    // 初始化加載第一屏圖片
    this.lazyLoad();
  },
  methods: {
    handleScroll() {
      this.lazyLoad();
    },
    lazyLoad() {
      const container = this.$refs.container;
      const imageList = Array.from(container.querySelectorAll('img'));
      // 遍歷圖片列表,如果圖片進(jìn)入了可視區(qū)域,就加載
      imageList.forEach(img => {
        if (this.isInViewport(img)) {
          img.src = img.dataset.src;
          img.isLoaded = true;
        }
      });
    },
    isInViewport(img) {
      // 獲取圖片相對(duì)于視口的位置
      const rect = img.getBoundingClientRect();
      // 判斷圖片是否進(jìn)入了可視區(qū)域
      return rect.top < window.innerHeight && rect.bottom > 0;
    }
  },
  watch: {
    images: {
      handler: function(newVal, oldVal) {
        // 每當(dāng)圖片加載完成時(shí),就移除已加載圖片的 isLoaded 屬性
        newVal.forEach((item, index) => {
          if (item.isLoaded) {
            this.$set(this.images[index], 'isLoaded', false);
          }
        });
      },
      deep: true
    }
  }
}
</script>

注意:需要注意的是,在這個(gè)案例中,因?yàn)閕mages數(shù)組中的對(duì)象被改變了,所以需要設(shè)置deep: true來(lái)監(jiān)聽(tīng)對(duì)象

總之,watch 是一個(gè)非常強(qiáng)大和靈活的功能,它可以在數(shù)據(jù)變化時(shí)執(zhí)行任何操作,并且可以與 computed 計(jì)算屬性配合使用,來(lái)實(shí)現(xiàn)更復(fù)雜的邏輯。

computed 和 watch 的區(qū)別

watch和computed都可以監(jiān)聽(tīng)Vue實(shí)例中的數(shù)據(jù)變化,但是它們有著明顯的不同。

watch

computed

用于監(jiān)聽(tīng)某個(gè)特定的數(shù)據(jù)變化。

用于計(jì)算屬性,可以計(jì)算出一個(gè)新的值。

每次數(shù)據(jù)變化都會(huì)觸發(fā)回調(diào)函數(shù)。

僅在相關(guān)依賴(lài)發(fā)生改變時(shí)才會(huì)觸發(fā)重新計(jì)算。

適用于異步操作或復(fù)雜邏輯。

適用于簡(jiǎn)單計(jì)算。

不可以在html模板中使用

可以在HTML模板中使用

沒(méi)有返回值

有返回值/getter

可以修改data中的數(shù)據(jù)

也可以使用setters 修改 data 中的數(shù)據(jù)

總之,如果你需要在數(shù)據(jù)變化時(shí)執(zhí)行異步操作或復(fù)雜邏輯,使用watch是更好的選擇;如果你需要在數(shù)據(jù)變化時(shí)計(jì)算出一個(gè)新值,使用computed是更好的選擇。

關(guān)于watch的性能

watch的性能取決于你的代碼實(shí)現(xiàn)方式和監(jiān)聽(tīng)的數(shù)據(jù)量。

  • 監(jiān)聽(tīng)的數(shù)據(jù)量:如果你監(jiān)聽(tīng)了大量的數(shù)據(jù),那么 watch 的性能可能會(huì)受到影響。
  • 代碼實(shí)現(xiàn):如果你在 watch 回調(diào)函數(shù)中執(zhí)行了復(fù)雜的邏輯或異步操作,那么 watch 的性能可能會(huì)受到影響。
  • 如果你只是需要在數(shù)據(jù)變化時(shí)執(zhí)行一些簡(jiǎn)單的操作,那么 watch 的性能應(yīng)該是可以接受的。

所以,在使用watch時(shí),應(yīng)該注意監(jiān)聽(tīng)的數(shù)據(jù)量,并且在watch回調(diào)函數(shù)中盡量少執(zhí)行復(fù)雜的邏輯.總之,watch監(jiān)聽(tīng)數(shù)據(jù)更新并執(zhí)行回調(diào)函數(shù),性能會(huì)受到監(jiān)聽(tīng)數(shù)據(jù)量和回調(diào)函數(shù)實(shí)現(xiàn)方式的影響,如果有性能問(wèn)題,應(yīng)該優(yōu)化監(jiān)聽(tīng)的數(shù)據(jù)量和回調(diào)函數(shù)的實(shí)現(xiàn)方式.

結(jié)束

今天的文章就介紹到這里,關(guān)于 watch 的用法你學(xué)會(huì)了,希望今天的文章能幫助到你,感謝你的閱讀。如果你喜歡我的分享,別忘了點(diǎn)贊轉(zhuǎn)發(fā),讓更多的人看到,最后別忘記點(diǎn)個(gè)關(guān)注,你的支持將是我分享最大的動(dòng)力,后續(xù)我會(huì)持續(xù)輸出更多內(nèi)容,敬請(qǐng)期待。

分享到:
標(biāo)簽:Vue3
用戶(hù)無(wú)頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過(guò)答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫(kù),初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定