最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

實現(xiàn)一個VUE響應式屬性裝飾器詳析

 更新時間:2022年09月22日 08:56:49   作者:JiangHong  
這篇文章主要介紹了實現(xiàn)一個VUE響應式屬性裝飾器詳析,文章通過圍繞主題展開詳細的內容介紹,具有一定的參考價值,需要的小伙伴可以參考一下

前言

使用面向對象的開發(fā)思想難免會用到,既然有了類,那就應該有實例,然而我們使用類的時候可能需要實例中的某個屬性是vue的響應屬性,也可能里面的某個方法也可以被vue的watch監(jiān)聽。我就開始琢磨如何通過 Composition API 來實現(xiàn)這個類屬性裝飾器

不使用任何的響應Api

 // TestReactive.ts
 export class TestReactive {
     count = 0;
     loopSetCount() {
       setInterval(() => {
         this.count++;
       }, 1000);
     }
}
// App.vue
<template>
   <div>{{data.count}} </div>
</template>
<script setup lang="ts">
import { TestReactive } from './TestReactive'

const data = new TestReactive()

data.loopSetCount()

</script>

</script>

通過以上代碼可以看到我調用 loopSetCount 這個方法的作用就是想讓data實例對象中的count每間隔1s就加1 同時也想讓template模板中的 {{data.count}} 響應,但這樣操作他是不會響應的因為我們的 count 并非是 Composition API 提供的響應式數(shù)據(jù)。

使用 reactive 實現(xiàn)

最初的做法很簡單把實例裹了一層 reactive ,果不其然view層動態(tài)渲染了,但是這樣就會導致我整個實例中所有的方法以及屬性都會是響應式數(shù)據(jù),最終不是想要的效果

const data = reactive(new TestReactive())

使用 ref 實現(xiàn)

后面我又想了一個好方法就是把想要響應式的屬性賦一個 ref 對象,這樣也能實現(xiàn)同樣的效果,但是在賦值的時候還得必須用到 .value ,感覺很不優(yōu)雅。

// 去除reactive的包裹
const data = new TestReactive()
 // TestReactive.ts
import { ref } from "vue";
export class TestReactive {

  count = ref<number>(0);

  loopSetCount() {
    setInterval(() => {
      this.count.value++;
    }, 1000);
  }
}

使用裝飾器實現(xiàn)

實現(xiàn)Reactive裝飾器

最終又想了一個方案就是我想要哪個類屬性實現(xiàn)vue的響應,那我只需要用裝飾器裝飾一下這個屬性,即可讓view層跟著數(shù)據(jù)變化。

我們裝飾的是類屬性首先你得要了解類型裝飾器的規(guī)則,具體請參考TypeScript手冊

屬性裝飾器聲明在一個屬性聲明之前(緊靠著屬性聲明)。 屬性裝飾器不能用在聲明文件中(.d.ts),或者任何外部上下文(比如 declare的類)里。

屬性裝飾器表達式會在運行時當作函數(shù)被調用,傳入下列2個參數(shù):

  • 對于靜態(tài)成員來說是類的構造函數(shù),對于實例成員是類的原型對象。
  • 成員的名字。

注意  屬性描述符不會做為參數(shù)傳入屬性裝飾器,這與TypeScript是如何初始化屬性裝飾器的有關。 因為目前沒有辦法在定義一個原型對象的成員時描述一個實例屬性,并且沒辦法監(jiān)視或修改一個屬性的初始化方法。返回值也會被忽略。因此,屬性描述符只能用來監(jiān)視類中是否聲明了某個名字的屬性。

 // TestReactive.ts
import { ref } from "vue";

function Reactive(target: any, key: string) {
  const value = ref();

  Reflect.defineProperty(target, key, {
    get() {
      return value.value;
    },
    set(v) {
      value.value = v;
    },
  });
}
export class TestReactive {
  @Reactive
  count = 0;
  
  loopSetCount() {
    setInterval(() => {
      this.count++;
    }, 1000);
  }
}

通過以上代碼使用Reactive裝飾一下這個屬性頁面就會跟著變化,而且在賦值的時候也不需要通過this.count.value 去賦值。這樣一來就解決了我們不優(yōu)雅的問題。

實現(xiàn)Watch裝飾器

緊接著我們可以再實現(xiàn)一個Watch的裝飾器專門用于裝飾方法,通過傳遞Reactive裝飾的屬性名稱來監(jiān)聽,一旦Reactive裝飾的屬性變動就會調用Watch裝飾的方法。

import { ref, watch, WatchOptions } from "vue";

function Reactive(target: any, key: string) {
  const value = ref();

  Reflect.defineProperty(target, key, {
    get() {
      return value.value;
    },
    set(v) {
      value.value = v;
    },
  });
}

function Watch(watchField: string | string[], watchConfig: WatchOptions = {}) {
  return function (target: any, key: string, descriptor: PropertyDescriptor) {
    let watchFn: Array<() => any> | (() => any) = [];

    if (typeof watchField === "string") {
      watchFn = () => target[watchField];
    } else if (Array.isArray(watchField)) {
      watchFn = watchField.map((field) => () => target[field]);
    }
    watch(watchFn, descriptor.value, watchConfig);
  };
}
export class TestReactive {
  @Reactive
  count = 0;

  @Watch("count")
  doFetch(newValue: number) {
    console.log(newValue, "最新的數(shù)據(jù)");
  }
  loopSetCount() {
    setInterval(() => {
      this.count++;
    }, 1000);
  }
}

以上是我實現(xiàn)的一個思路,當我實現(xiàn)完這個功能后,同事告訴我 有一個 mobx 的庫可以像我這樣來操作數(shù)據(jù)響應式,然后我查了一下 mobx for vue 還真找到了一個 mobx-vue 的庫,感覺可以深度的去學習一下。

總結

響應式屬性還是通過Composition API來實現(xiàn)的,使用裝飾器(Decorators)來進行屬性的操作,讓使用者無感知,只需要知道哪個屬性需要響應我就給誰裝飾。

到此這篇關于實現(xiàn)一個VUE響應式屬性裝飾器詳析的文章就介紹到這了,更多相關 VUE響應式屬性裝飾器內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • eslint常見的一些報錯及解決方法

    eslint常見的一些報錯及解決方法

    這篇文章主要給大家介紹了關于eslint常見的一些報錯及解決方法,解決eslint的報錯問題可以要根據(jù)報錯行數(shù)快速定位.文中通過圖文介紹的非常詳細,需要的朋友可以參考下
    2023-03-03
  • Element-ui設置el-table表頭全選框隱藏或禁用

    Element-ui設置el-table表頭全選框隱藏或禁用

    這篇文章主要給大家介紹了關于Element-ui設置el-table表頭全選框隱藏或禁用的相關資料,文中手把手教你實現(xiàn)el-table實現(xiàn)跨表格禁用選項,需要的朋友可以參考下
    2023-07-07
  • vue2封裝input組件方式(輸入的雙向綁定)

    vue2封裝input組件方式(輸入的雙向綁定)

    這篇文章主要介紹了vue2封裝input組件方式(輸入的雙向綁定),具有很好的參考價值,希望對大家有所幫助。
    2023-04-04
  • Vue3?如何通過虛擬DOM更新頁面詳解

    Vue3?如何通過虛擬DOM更新頁面詳解

    這篇文章主要為大家介紹了Vue3?如何通過虛擬DOM更新頁面詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-09-09
  • Nuxt使用Vuex的方法示例

    Nuxt使用Vuex的方法示例

    這篇文章主要介紹了Nuxt使用Vuex的方法示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-09-09
  • Vue3如何在setup中獲取元素引用(ref)

    Vue3如何在setup中獲取元素引用(ref)

    這篇文章主要介紹了Vue3如何在setup中獲取元素引用(ref)問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • Vue3+TypeScript實現(xiàn)Docx/Excel預覽組件

    Vue3+TypeScript實現(xiàn)Docx/Excel預覽組件

    這篇文章主要為大家詳細介紹了如何使用Vue3+TypeScript實現(xiàn)Docx/Excel預覽組件,文中的示例代碼講解詳細,有需要的小伙伴可以參考下
    2024-04-04
  • vue如何從后臺下載.zip壓縮包文件

    vue如何從后臺下載.zip壓縮包文件

    這篇文章主要介紹了vue如何從后臺下載.zip壓縮包文件,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • vue.js利用Object.defineProperty實現(xiàn)雙向綁定

    vue.js利用Object.defineProperty實現(xiàn)雙向綁定

    這篇文章主要為大家詳細介紹了vue.js利用Object.defineProperty實現(xiàn)雙向綁定,幫大家解析神秘的Object.defineProperty方法
    2017-03-03
  • ?面試問題Vue雙向數(shù)據(jù)綁定原理

    ?面試問題Vue雙向數(shù)據(jù)綁定原理

    這篇文章主要介紹了?面試問題Vue雙向數(shù)據(jù)綁定原理,文章圍繞主題展開詳細的內容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-09-09

最新評論

彰化县| 婺源县| 花莲县| 佛教| 乐平市| 茌平县| 勃利县| 宾阳县| 烟台市| 六盘水市| 都安| 大港区| 礼泉县| 东城区| 白沙| 北流市| 腾冲县| 遂平县| 浙江省| 湖北省| 平乡县| 浏阳市| 岗巴县| 乌拉特后旗| 古蔺县| 玛多县| 嫩江县| 东莞市| 桑日县| 衡阳县| 耒阳市| 庄浪县| 石台县| 新密市| 钟山县| 兴文县| 民乐县| 白城市| 阜新市| 饶河县| 交城县|