<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          「快速學(xué)習(xí)系列」我熬夜整理了Vue3.x響應(yīng)性API

          共 11236字,需瀏覽 23分鐘

           ·

          2021-03-06 22:54

          前言

          Vue3.x正式版發(fā)布已經(jīng)快半年了,相信大家也多多少少也用Vue3.x開發(fā)過項目。那么,我們今天就整理下Vue3.x中的響應(yīng)性API。

          響應(yīng)性API

          reactive

          作用:創(chuàng)建一個響應(yīng)式數(shù)據(jù)。

          本質(zhì):傳入數(shù)據(jù)(復(fù)雜類型:數(shù)組和json對象)包裝成一個Proxy對象。如果傳入其他對象,默認(rèn)情況下修改對象,界面不會自動更新,如果想更新,可以通過重新賦值(創(chuàng)建一個新的對象)的方式。

          <template>
          <div class="reactive">
          <button @click="fn">點(diǎn)擊</button>
          <p>{{ state }}</p>
          <button @click="fn1">點(diǎn)擊1</button>
          <p>{{ timeState }}</p>
          </div>
          </template>

          <script>
          import { reactive } from "vue";
          export default {
          name: "Reactive",
          setup() {
          let state = reactive({
          name: "123",
          });
          function fn() {
          console.log(state);
          state.name = "456";
          }

          let timeState = reactive({
          time: new Date(),
          });

          function fn1() {
          const newTime = new Date(timeState.time.getTime());
          newTime.setDate(timeState.time.getDate() + 1);
          timeState.time = newTime;
          console.log(timeState.time);
          }

          return {
          state,
          fn,
          timeState,
          fn1,
          };
          },
          };
          </script>

          ref

          作用:創(chuàng)建一個響應(yīng)式數(shù)據(jù)。

          本質(zhì):(該本質(zhì)寫的不夠嚴(yán)謹(jǐn))針對復(fù)雜類型還是reactive。當(dāng)我們給ref函數(shù)傳遞一個值(一般是簡單類型)之后,ref函數(shù)底層會自動將ref轉(zhuǎn)換成reactive,即ref(123) => reactive({value:123}),所以修改對應(yīng)的值必須在后面加上.value

          注意點(diǎn):template標(biāo)簽內(nèi)不用加.value。

          <template>
          <div>
          <button @click="fn">點(diǎn)擊</button>
          <p>{{state}}</p>
          <button @click="fn1">點(diǎn)擊1</button>
          <p>{{arrState}}</p>
          </div>
          </template>

          <script>
          import {ref} from "vue";
          export default {
          name:"Ref",
          setup(){
          let state = ref(123);
          function fn () {
          state.value = 345;
          }
          let arrState = ref([]);
          function fn1 (){
          arrState.value.push("1");
          }
          return {
          state,
          fn,
          arrState,
          fn1
          }
          }
          }
          </script>

          shallowReactive

          作用:創(chuàng)建一個響應(yīng)式 proxy,跟蹤其自身 property 的響應(yīng)性,但不執(zhí)行嵌套對象的深度響應(yīng)式轉(zhuǎn)換 (暴露原始值)。

          本質(zhì):對于嵌套對象不做響應(yīng),值跟蹤自身的第一層property。

          <template>
          <div>
          <button @click="fn">點(diǎn)擊</button>
          <button @click="fn1">點(diǎn)擊1</button>
          <p>{{state}}</p>
          </div>
          </template>

          <script>
          import { shallowReactive } from "vue"
          export default {
          name:"ShallowReactive",
          setup(){
          let state = shallowReactive({
          name:"maomin",
          age:{
          number:20
          }
          })
          function fn(){
          state.name = "123"; // 響應(yīng)性
          }
          function fn1(){
          state.age.number = 23; // 無響應(yīng)性
          }
          return {
          state,
          fn,
          fn1
          }
          }
          }
          </script>

          shallowRef

          作用:創(chuàng)建一個 ref,它跟蹤自己的 .value 更改,但不會使其值成為響應(yīng)式的。不會將其值轉(zhuǎn)化為Proxy對象。

          <template>
          <div>
          <button @click="fn">點(diǎn)擊</button>
          <p>{{ state }}</p>
          <button @click="fn1">點(diǎn)擊1</button>
          <p>{{ state1 }}</p>
          </div>
          </template>

          <script>
          import {
          shallowRef,
          ref,
          // triggerRef
          } from "vue";
          export default {
          name: "ShallowRef",
          setup() {
          let state = shallowRef({
          name: "maomin",
          });
          let state1 = ref({});
          function fn() {
          state.value.name = "345";
          console.log(state.value); // {name: "345"}, 但是UI界面不會變。
          // triggerRef(state); // 如果想觸發(fā)UI界面,可以使用它。
          }
          function fn1() {
          state1.value = {
          name: "123",
          };
          // eslint-disable-next-line no-irregular-whitespace
          console.log(state1.value); // Proxy {name: "123"}
          }
          return {
          state,
          fn,
          state1,
          fn1,
          };
          },
          };
          </script>

          readonly

          作用:獲取一個對象 (響應(yīng)式或純對象) 或 ref 并返回原始 proxy 的只讀 proxy。只讀 proxy 是深層的:訪問的任何嵌套 property 也是只讀的。

          <template>
          <div>
          <button @click="fn">點(diǎn)擊</button>
          <p>{{os}}</p>
          <p>{{state}}</p>
          </div>
          </template>

          <script>
          import {reactive, readonly} from "vue";
          export default {
          name:"Readonly",
          setup(){
          let state = reactive({
          name:"maomin",
          age:{
          number:18
          }
          })
          let os = readonly(state);
          function fn(){
          os.name = "123";
          }
          return{
          os,
          state,
          fn
          }
          }
          }
          </script>

          shallowReadonly

          作用:創(chuàng)建一個 proxy,使其自身的 property 為只讀,但不執(zhí)行嵌套對象的深度只讀轉(zhuǎn)換 (暴露原始值)。

          <template>
          <div>
          <button @click="fn">點(diǎn)擊</button>
          <p>{{os}}</p>
          <p>{{state}}</p>
          </div>
          </template>

          <script>
          import {
          reactive,
          shallowReadonly,
          isReadonly
          } from "vue";
          export default {
          name:"ShallowReadonly",
          setup(){
          let state = reactive({
          name:"maomin",
          age:{
          number:18
          }
          })

          let os = shallowReadonly(state);

          function fn(){
          console.log(isReadonly(os.name)) //false
          os.age.number = 20;
          }
          return{
          state,
          os,
          fn,
          }
          }
          }
          </script>

          toRaw

          作用:響應(yīng)式對象轉(zhuǎn)普通對象。

          本質(zhì):返回由reactive或 readonly 方法轉(zhuǎn)換成響應(yīng)式代理的普通對象。這是一個還原方法,可用于臨時讀取,訪問不會被代理/跟蹤,寫入時也不會觸發(fā)更改。不建議一直持有原始對象的引用。

          <template>
          <div>
          <button @click="fn">點(diǎn)擊</button>
          <p>{{state}}</p>
          </div>
          </template>

          <script>
          import { reactive, toRaw } from "vue";
          export default {
          name:"ToRaw",
          setup(){
          const obj = {
          name:"maomin"
          };
          let state = reactive(obj);
          function fn(){
          console.log(toRaw(state) === obj); //true
          let obj1 = toRaw(state);
          obj1.name = "123";
          // eslint-disable-next-line no-irregular-whitespace
          console.log(state); // Proxy {name: "123"}. 值雖改變,但是頁面沒有變化。
          }

          return {
          state,
          fn
          }
          }
          }
          </script>

          markRaw

          作用:標(biāo)記一個對象,使其永遠(yuǎn)不會轉(zhuǎn)換為 proxy。返回對象本身。

          <template>
          <div>
          <button @click="fn">點(diǎn)擊</button>
          <p>{{state}}</p>
          </div>
          </template>

          <script>
          import {markRaw,reactive} from "vue"
          export default {
          name:"MarkRaw",
          setup(){
          let obj = {name:'maomin', age: 20};
          obj = markRaw(obj);
          let state = reactive(obj);
          function fn(){
          state.name = '123';
          console.log(state); //這里雖然打印出name:123,但是UI界面不會改變。
          }
          return{
          state,
          fn
          }
          }
          }
          </script>

          toRef

          如果使用ref,我們修改響應(yīng)式的數(shù)據(jù)是不會影響到原始數(shù)據(jù)的(復(fù)制)。如果使用toRef,我們修改響應(yīng)式的數(shù)據(jù)是會影響到原始數(shù)據(jù)的(引用)。

          作用:可以用來為源響應(yīng)式對象上的 property 新創(chuàng)建一個 ref。然后可以將 ref 傳遞出去,從而保持對其源 property 的響應(yīng)式連接。

          <template>
          <div>
          <button @click="fn">點(diǎn)擊</button>
          <p>{{state}}</p>
          <button @click="fn1">點(diǎn)擊1</button>
          <p>{{state1}}</p>
          </div>
          </template>

          <script>
          import {reactive, ref, toRef} from "vue"
          export default {
          name:"ToRef",
          setup(){
          let obj = {name:"maomin"};
          let os = reactive(obj);

          let state = ref(os.name);
          let state1 = toRef(os,'name');
          // ref
          function fn(){
          state.value = "123";
          console.log(os); // 原始數(shù)據(jù)不會發(fā)生改變
          console.log(state);
          }
          // toRef
          function fn1(){
          state1.value = "345";
          console.log(os); // 原始數(shù)據(jù)會發(fā)生改變
          console.log(state1);
          }
          return {
          state,
          fn,
          state1,
          fn1
          }
          }
          }
          </script>

          toRefs

          作用:將響應(yīng)式對象轉(zhuǎn)換為普通對象,其中結(jié)果對象的每個 property 都是指向原始對象相應(yīng) property 的ref。

          用途:當(dāng)從合成函數(shù)返回響應(yīng)式對象時,toRefs 非常有用,這樣消費(fèi)組件就可以在不丟失響應(yīng)性的情況下對返回的對象進(jìn)行分解/擴(kuò)散。

          <template>
          <div>
          <button @click="fn">點(diǎn)擊</button>
          <p>{{state}}</p>
          <button @click="fn1">點(diǎn)擊1</button>
          <p>{{foo}}</p>
          </div>
          </template>

          <script>
          import {reactive, toRefs} from "vue"
          export default {
          name:"ToRefs",
          setup(){
          let obj = {
          name:"maomin",
          age:20
          }
          let os = reactive(obj);
          let state = toRefs(os);

          function fn(){
          state.name.value = "123";
          os.name = "234";
          console.log(os);
          console.log(state);
          console.log(state.name.value === os.name); //true
          }

          const { foo, bar } = useFeatureX();

          function fn1(){
          foo.value = "2";
          }
          return {
          fn,
          state,
          foo,
          bar,
          fn1
          }
          }
          }


          function useFeatureX() {
          const state = reactive({
          foo: 1
          })
          // 返回時轉(zhuǎn)換為ref
          return toRefs(state)
          }
          </script>

          customRef

          作用:創(chuàng)建一個自定義的 ref,并對其依賴項跟蹤和更新觸發(fā)進(jìn)行顯式控制。它需要一個工廠函數(shù),該函數(shù)接收 track 和 trigger 函數(shù)作為參數(shù),并應(yīng)返回一個帶有 get 和 set 的對象。

          <template>
          <div>
          <button @click="fn">點(diǎn)擊</button>
          <p>{{state}}</p>
          </div>
          </template>

          <script>
          import {customRef} from "vue";

          function myRef(value){
          return customRef((track, trigger)=>{
          return {
          get(){
          track();
          console.log('get',value);
          return value;
          },
          set(newValue){
          console.log('set',newValue);
          value = newValue;
          trigger();
          }
          }
          })
          }
          export default {
          name:"CustomRef",
          setup(){
          let state = myRef(18);

          function fn(){
          state.value = 19;
          }
          return {
          state,
          fn
          }
          }
          }
          </script>

          computed

          作用:依賴項變化時,其賦予的值也就相應(yīng)改變。

          注意點(diǎn):直接修改computed是不可以的。

          <template>
          <div>
          <p>{{state}}</p>
          <p>{{os}}</p>
          <button @click="fn">點(diǎn)擊</button>
          </div>
          </template>

          <script>
          import {computed,ref} from "vue"
          export default {
          name: "Computed",
          setup(){
          let state = ref(12);
          let os = computed(() => state.value + 1);

          function fn(){
          state.value = 23; // os的值也會相應(yīng)改變
          // os.value = 26; // Write operation failed: computed value is readonly
          }
          return{
          state,
          os,
          fn
          }
          }
          }
          </script>

          watchEffect

          作用:在響應(yīng)式地跟蹤其依賴項時立即運(yùn)行一個函數(shù),并在更改依賴項時重新運(yùn)行它。

          <template>
          <div>
          <button @click="fn">點(diǎn)擊</button>
          <p>{{state}}</p>
          <p>{{state1}}</p>
          <p>{{num}}</p>
          </div>
          </template>

          <script>
          import { reactive, ref, watchEffect } from "vue"
          export default {
          name:"WatchEffect",
          setup(){
          let state = ref(0);
          let state1 = reactive({
          name:"maomin"
          })
          let num = 1;
          // 首次運(yùn)行時會執(zhí)行它,如果響應(yīng)依賴項改變時,會重新執(zhí)行它。
          watchEffect(()=>{
          // console.log(num);
          console.log(state.value);
          console.log(state1);
          })

          function fn() {
          state.value = 3;
          state1.name = "123";
          num = 2;
          }

          return{
          fn,
          state,
          state1,
          num
          }
          }
          }
          </script>

          watch

          作用:默認(rèn)情況下,它也是惰性的——即回調(diào)僅在偵聽源發(fā)生更改時調(diào)用。

          <template>
          <div>
          <button @click="fn">點(diǎn)擊</button>
          <p>{{state}}</p>
          <button @click="fn1">點(diǎn)擊1</button>
          <p>{{state1}}</p>
          </div>
          </template>

          <script>
          import {reactive, ref, watch} from "vue"
          export default {
          name:"Watch",
          setup(){

          // reactive
          let state = reactive({
          name:"maomin"
          })

          watch(
          () => state.name,
          (count) =>{
          console.log(count); //123
          }
          )

          function fn() {
          state.name = "123";
          }

          //ref
          let state1 = ref(1);
          watch(
          state1,
          (count) =>{
          console.log(count); //2
          }
          )

          function fn1() {
          state1.value = 2;
          }

          return {
          state,
          fn,
          fn1,
          state1
          }
          }
          }
          </script>

          結(jié)語

          謝謝閱讀,希望沒有浪費(fèi)您的時間。可以結(jié)合代碼例子自己敲敲代碼,響應(yīng)性API還有很多用處,這里只介紹了九牛一毛。2021年到來,趕快行動起來吧!


          小獅子有話說

          你好,我是 Chocolate,一個獅子座的前端攻城獅,希望成為優(yōu)秀的前端博主,每周都會更新文章,與你一起變優(yōu)秀~

          1. 關(guān)注小獅子前端,回復(fù)【小獅子】獲取為大家整理好的文章、資源合集
          2. 我的博客地址:yangchaoyi.vip 歡迎收藏,可在博客留言板留下你的足跡,一起交流~
          3. 覺得文章不錯,【點(diǎn)贊】【在看】支持一波 ??ヽ(°▽°)ノ?

          叮咚~ 可以給小獅子加星標(biāo),便于查找。感謝加入小獅子前端,最好的我們最美的遇見,我們下期再見~



          瀏覽 41
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  天天干夜夜爽 | 欧美不卡a| 日韩AV无码专区亚洲AV | 内操主播 | 尹人在线视频 |