vue3.0實戰從0到1實戰電商管理系統(次日)

alt vue3.0

章節文章課程簡介:

任何事情都須要時間的沉澱,技術也不例外,今天編寫Vue3.0系列的章節文章,只是但願可以比別人更早的去嚐鮮一些新的技術,畢竟Vue3.0已經Beta版本了,因此里正式版本也不遠了,提早去學習和了解,咱們就會比別人有更多的時間去充分理解Vue3.0的特性,只有當你真正理解一門技術的時候,纔可以正確的斷定它是否合適、是否應該運用到你當前的實際項目當中去。javascript

  • 第一天:淺談vue3.0、初始化項目之:Hello World Vue3.0
  • 次日:Api實戰之:vue-composition 我是api調用工程師
  • 第三天:vue3如何實現邏輯複用
  • 第四天:實戰之:高解耦式mock api的設計與訂單列表查詢
  • 第五天:如何實現代碼優化

今天是次日:Api實戰之:vue-composition 我是api調用工程師

學習任何框架以前,首先確定要學習的是它的生命週期,Vue3.0的全部生命週期函數都是在setup函數中定義,具體包含生命週期機器定義以下:html

import {
  onBeforeMount,
  onMounted,
  onBeforeUpdate,
  onUpdated,
  onBeforeUnmount,
  onUnmounted,
  onErrorCaptured,
  onRenderTracked,
  onRenderTriggered,
} from "vue";
export default {
  setup() {
    console.log("setup");
    onRenderTracked(() => {
      console.log("onRenderTracked");
    });
    onRenderTriggered((event) => {
      console.log('onRenderTriggered')
    });
    onBeforeMount(() => {
      console.log("onBeforeMount");
    });
    onMounted(() => {
      console.log("onMounted");
    });
    onBeforeUpdate(() => {
      console.log("onBeforeUpdate");
    });
    onUpdated(() => {
      console.log("onUpdated");
    });
    onBeforeUnmount(() => {
      console.log("beforeDestroy");
    });
    onUnmounted(() => {
      console.log("onUnmounted");
    });
    onErrorCaptured(() => {
      console.log("onErrorCaptured");
    });
    return {
    };
  },
};

複製代碼

Vue3.0組件生命週期圖

alt vue3.0

Vue3.0 vue-composition Api的使用

  • (1) setup() setup() 函數是 vue3 中統一的入口函數,全部生命週期函數定義都是須要定義在次函數下才生效,setup 函數中沒法訪問到 this,全部的組件參數都是經過,setup函數中包含props和context參數,props參數默認是響應式的

首先咱們先建立一個組件以下:vue

export default {
  setup() {
      console.log("組件入口函數");
  }
}
複製代碼

components/user,vuejava

<template>
  <section>
    <h2>我是:{{ userName }}</h2>
  </section>
</template>
複製代碼
export default {
  props: {
  userName: String
 },
  setup(props,context) {
    // context.attrs
    // context.slots
    // context.parent
    // context.root
    // context.emit
    // context.refs
      console.log(`組件傳遞props${props.userName}`);
      console.log(`組件的上下文對象${context}`);
  },
};
複製代碼

而後在App.vue頁面中使用它react

src/App,vueapi

<template>
  <section>
    <h2>Hello World Vue3.0</h2>
    <com-user :userName="'虎克小哥哥'"/>
    <br/>
  </section>
</template>
複製代碼
import ComUser from "./components/user.vue"
export default {
  components:{
    ComUser
  },
  setup() {
    return {
    };
  },
};
複製代碼
  • (2) reactive() 函數接收一個普通對象,返回一個響應式的數據對象,支持Map、Set、WeakSet、WeakMap數據結構
<template>
  <section>
    <h2>Hello World Vue3.0</h2>
    <h3>我是:{{userInfo.userName}}</h3>
    <br/>
  </section>
</template>
複製代碼
import { reactive } from "vue";
export default {
  setup() {
    const userInfo=reactive({userName:"虎克小哥哥"});
    return {
      userInfo
    };
  },
};
複製代碼
  • (3) ref() 函數用來根據給定的值建立一個響應式的數據對象,ref() 函數調用的返回值是一個對象,這個對象上只包含一個 .value 屬性。數據結構

    <template>
      <section>
        <h2>Hello World Vue3.0</h2>
        <h3>我叫虎克小哥哥,來自:{{city}}</h3>
        <button @click="getUserCity">你來自哪裏?</button>
        <br/>
      </section>
    </template>
    複製代碼
    import { ref } from "vue";
    export default {
      setup() {
        const city=ref("");
        const getUserCity=()=>{
          city.value="上海";
        }
        return {
          city
        };
      },
    };
    
    
    
    
    複製代碼
  • (4) isRef() 用來判斷某個值是否爲 ref() 建立出來的對象。 isProxy、isReactive、isReadonly都大同小異框架

<template>
   <section>
     <h2>Hello World Vue3.0</h2>
     <h3>{{Msg}}</h3>
     <button @click="getUserInfo">你來自哪裏?</button>
     <br/>
   </section>
 </template>
複製代碼
import { isRef } from "vue";
export default {
  setup() {
    const userName=ref("虎克小哥哥");
    const city=ref("上海");
    const Msg=ref("");
    const getUserInfo=()=>{
      if(isRef(userName)){
        Msg.value=`我叫:${userName.value},來自${city.value}`
      }else{
        Msg.value=`我叫:${userName.value}`
      }
    }
    return {
      Msg,
      getUserInfo
    };
  },
};

複製代碼
  • (5) toRefs() 函數能夠將 reactive() 建立出來的響應式對象,轉換爲普通的對象,就是能夠將reactive多層對象類型的響應對象,轉化爲普通類型的響應數據
<template>
  <section>
    <h2>Hello World Vue3.0</h2>
    <h3>轉換reactive類型數據{{userInfo.userName}}</h3>
    <h3>轉換reactive類型數據{{code}}</h3>
    <br/>
  </section>
</template>
複製代碼
import { reactive,toRefs } from "vue";
export default {
  setup() {
    const data=reactive({
      userInfo:{
        userName:"虎克小哥哥"
      },
       code:200
    });
   }
    return {
       ...toRefs(data),
    };
  },
};
複製代碼
  • (6) computed() 計算屬性 傳入一個 function 函數,能夠獲得一個只讀的計算屬性 傳入一個對象能夠自定義get set函數 返回一個響的應式ref對象
<template>
  <section>
    <h2>Hello World Vue3.0</h2>
    請輸入年齡:<input type="text" v-model="age">
    <br/><br/>
    個人年齡是:{{userMsg}}
    <br/>
  </section>
</template>
複製代碼
import { ref,computed } from "vue";
export default {
  setup() {
    const age = ref("");
    //傳入函數的方式
    const userMsg = computed(() =>{
      return `個人年齡是:`+age.value
    })

    //傳入對象自定義get set的形式
    const userMsg = computed({
    get(){
      return `個人年齡是:`+age.value
    },
    set(val){
      age.value=val;
    }
   })
  // 返回的userMsg是一個響應式的ref對象
   userMsg.value="";
    return {
      age,
      userMsg
    };
  },
};
複製代碼
  • (7) watch() 監聽函數
<template>
  <section>
    <h2>Hello World Vue3.0</h2>
    請輸入地址:<input type="text" v-model="city">
    請輸入年齡:<input type="text" v-model="age">
     <button @click="stop">不想給你知道個人年齡</button>
    <br/>
  </section>
</template>
複製代碼
import { ref,watch } from "vue";
export default {
  setup() {
     const city=ref("上海");
        //定義方式1 內部的響應對象改變就觸發監聽,默認會觸發深度監聽,
        //初始化的時候會執行一次
        //返回一個監聽實例函數
       const stop = watch(() => {
          console.log("個人年齡在增加:",age.value)
        },{
            lazy: false // 是否觸發深度監聽
       })
       //調用監聽實例函數,能夠中止監聽
       //stop()

        //監聽某個響應對象 
       const stop =  watch(
          () => age.value,
          (age, prevAge) => {
             console.log("age:",age,"prevAge",prevAge)
          }
        )
        //監聽多個響應對象
        const stop = watch(
          [
          () => age.value, 
          () => city.value, 
          ],
          (
            [age, city], 
            [prevage, prevcity], 
          ) => {
            console.log("age:",age,"prevage",prevage)
            console.log("city:",city,"prevcity",prevcity)
          },
          {
            lazy: true // 是否觸發深度監聽
          }
      )
    return {
       stop
    };
  },
};
複製代碼
  • (8) provide & inject 共享普通數據,輕輕鬆鬆垮多級組件的數據傳遞(不限層級,能夠說是優勢也能夠說是缺點,由於命名規則稍有不規範就會顯得數據維護性下降bug滿天飛,層級過深的時候也不是很直觀) provide() 和 inject() 能夠實現嵌套組件之間的數據傳遞。父級組件中使用 provide() 函數向下傳遞數據;子級組件中使用 inject() 獲取上層傳遞過來的數據

1 (父組件傳值子、孫子組件)dom

Achild.vue 孫子組件ide

<template>
  <section> <div>孫子組件</div> <img style="width:50px;height:50px" :src="pic"/> </section> </template>

<script>
import { inject } from 'vue'
export default {
  setup() {
    //A組件獲取父組件傳遞過來的帥氣頭像數據
    const pic = inject('pic')
    return {pic}
  },
};
</script>
複製代碼

A.vue 子組件

<template>
<section>
 <div>子組件</div>
 <com-achild/>
</section>
</template>

<script>
import ComAchild from "./components/Achild.vue";
export default {
 components:{
  ComAchild,
},
};
</script>
複製代碼

App.vue 根組件

<template>
  <section>
   <com-a/>
  </section>
</template>

import ComA from "./components/A.vue";
import {provide,ref} from "vue";
const pic='https://dss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=1461286262,427682797&fm=26&gp=0.jpg'
export default {
   components:{
    ComA,
  },
  setup() {
    //父組件冒泡共享數據pic
    provide('pic',pic )
    //也支持傳遞響應式數據
    const pic = ref('pic');
    provide('pic',pic)
  },
};

複製代碼
  • (9) ref 組件實例獲取

App.vue

<template>
  <section>
    <com-a ref="comRef"/>
  </section>
</template>
複製代碼
import { ref,onMounted } from "vue";
import ComA from "./components/A.vue";
export default {
 components:{
  ComA,
 },
  setup() {
     const comRef = ref(null);
    //須要在domx渲染類型的生命週期後使用
    onMounted(() => {
      //獲取子組件實例,調用其內部函數
      console.log(comRef.value.getName())
    })
    return {
      comRef
    };
   },
};
複製代碼

子組件A.vue

<template>
<section>
  我是子組件
</section>
</template>

export default {
    setup(){
        //子組件中的函數 
        const getName=()=>{
            return "我是測試數據"
        }
        return{
            getName
        }
    }
};
複製代碼
  • (10) 高級反應性API customRef: 這個是真的香,建立一個能夠控制其get set觸發更新的引用對象,返回一個響應式的ref對象 markRaw:標記一個對象,使其永遠不會轉換爲代理。返回對象自己

App.vue

<template>
  <section>
    輕輕鬆鬆實現防抖
    {{text}}
    <input v-model="text"/>
  </section>
</template>
複製代碼
import { customRef } from "vue";
//只須要返回一個響應Ref對象,可自定義其get set
const useDebounce=(value, delay = 10000)=>{//10000秒以後纔會更新text的值
  return customRef((track, trigger) => {
    let timeout
    return {
      get() {
        track()//必須調用次函數纔會觸發更新
        return value
      },
      set(newValue) {
        clearTimeout(timeout)
        timeout = setTimeout(() => {
          value = newValue
          trigger()//必須調用次函數纔會觸發更新
        }, delay)
      }
    }
 })
}
export default {
  setup() {
    return {
      text:useDebounce()
    };
   },
};
複製代碼
- (11) 高級反應性API 
複製代碼

markRaw:標記一個對象,使其永遠不會轉換爲代理。返回對象自己 shallowRef:建立一個引用來跟蹤其自身的.value突變,但不會使其值具備反應性(意思就是)

App.vue

<template>
  <section></section>
</template>
複製代碼
import { markRaw } from "vue";
export default {
  setup() {
    const foo = markRaw({
     nested:true
    })
    const bar = reactive({
      nested: foo.nested
    })
    console.log(bar)
    console.log(foo)
   },
};
複製代碼

foo對象未被代理,最多見的運用場景就是大數據的列表頁面,列表數據不會純展現性質的,不會涉及到修改,也就不必去深度代理了。其實和凍結對象差很少,明白其意思根據具體場景使用便可,跳過代理轉換能夠提升性能

alt vue3.0

🎨 原創不易,支持請點贊、轉發

相關文章
相關標籤/搜索