VUE 3.0 初體驗之路


碼文不易啊,轉載請帶上本文鏈接呀,感謝感謝 https://www.cnblogs.com/echoyya/p/14394057.html


在2020年9月中旬,vue.js發布了3.0正式版,在不久的將來,VUE3.0 也終將成為大前端的必然趨勢,

環境搭建

  1. node 版本要求: Node.js8.9 或更高版本 ,輸入 node -v 查看node版本

  2. vue-cli 版本:達到 vue-cli4.5.0 以上,可創建vue3.0的項目,支持體驗vue3.0的新特性,(3.x Preview),vue -V 查看腳手架版本

  3. 終端輸入: vue create project_name

核心知識


一、組件的定義和使用

組件:是維護單一功能,可復用的單個個體,相同的樣式及邏輯即可抽離成組件,方便維護,復用性增強。也是vue3.0項目中,最核心的概念

defineComponent:vue3.0中提供了一個函數返回傳遞給它的對象,最重要的是:在TypeScript下,給予了組件 正確的參數類型推斷 。此處先不展開介紹,后續會總結 vue3.0 + ts。

setup:組件的啟動函數,兩個參數: props(父組件傳遞的數據)content ( 上下文對象),最后return 定義的數據,方法,鈎子函數等,且setup中 沒有this,不能訪問this

<script>

    import { defineComponent } from 'vue'
    
    export default defineComponent ({
      setup (props, content) {
        // TODO 數據,方法,鈎子函數等
        return { }
      }
    })

</script>

二、數據的定義和使用

  1. ref定義單個數據,接受一個參數值並返回一個響應式且可改變的 ref 對象。ref 對象擁有一個指向內部值的單一屬性 .value
import { ref } from 'vue'

export default {
  setup () {
    let num1 =  ref(10)  // Number
    let name1 =  ref('Echoyya')  // String
    let arr1 =  ref(['a','d','c','d'])  // Array 
    let obj1 =  ref({age:20})  // Object 

    // 獲取及改變 ref對象的值,獲取內部值的單一屬性 value
    console.log(num1.value) // 10

    num1.value++
    console.log(num1.value) // 11
    
    return {
      //使用 ref 定義的數據,需要直接 return
      num1,name1,arr1,obj1
    }
  }
}

  1. reactive: 用於創建響應式數據,接收一個普通對象然后返回該普通對象的響應式代理,即雙向數據綁定,
    • 使用 reactive 定義的數據,不需要逐一 return,可以使用 ES6 的擴展運算符。

    • 解構會破壞雙向數據綁定的特性, 變更為單向數據綁定

    • 解決:vue3.0中添加了新特性,可對當前的數據進行轉換。將其轉換為響應式數據,toRefs將數據包裹即可轉換為響應式數據

import { reactive, toRefs } from 'vue'

export default {
  setup () {
    let data = reactive ({
      num:33,
      arr:['a','d','c','d'],
      obj:{age:20},
    })
     // 獲取及改變:reactive 定義的數據,調用時直接 reactive變量名.數據名,
    console.log(data.num) // 33

    data.num++
    console.log(data.num) // 34
    
    return {
      ...toRefs(data) 
    }
  }
}

三、方法的定義和使用

創建的方法仍然需要 return

<template>
  <div>
    <p><button @click="clickNum">{{num}}</button></p>
    <p><button @click="clickNum1">{{num1}}</button></p>
    <p><button @click="singleMethod">{{name}}</button></p>
  </div>
</template>

<script>

import { reactive, ref, toRefs } from 'vue'
export default {
  setup () {
    let num1 =  ref(10)
    let name =  ref('Echoyya')
    let data = reactive({
      num:33,
    })

    // 定義多個方法,不需要逐一 return
    let methods  = {
      clickNum1: () => {
        num1.value++ 
        console.log(num1.value);
      },
      clickNum : () => {
        data.num ++ 
        console.log(data.num);
      }
    }
     // 定義單個方法,需要return
    let singleMethod = () => {
      console.log(name.value)
    }
    return {
      num1,
      name,
      singleMethod,
      ...toRefs(data)
      ...methods,
    }
  }
}

</script>

四、路由的定義、使用和傳參

  1. /src/router/index.js:在路由文件中使用了createRouter方法
import { createRouter } from 'vue-router'
const routes = [
  {
    path: '/',
    name: 'Home',
    component: () => import('../views/Home.vue')
  },
  {
    path: '/about',
    name: 'About',
    component: () => import('../views/About.vue')
  }
]
const router = createRouter({
  routes
})

export default router

  1. home組件中使用,路由跳轉及傳遞參數
<template>
  <div>
    <p><button @click="gotoQuery">query跳轉</button></p>
    <p><button @click="gotoParams">params跳轉</button></p>
  </div>
</template>

<script>

import { useRouter } from 'vue-router'
export default {
  setup (){
    // router對象是全局路由的實例。
    let router = useRouter()

    // 跳轉路由用push: 跳轉時可使用name 和 path,傳遞參數可使用query 和 params

    let gotoQuery = () => {
      // query: 可以使用name和path,參數顯示在地址欄中, 且頁面刷新參數仍在
      router.push({
        // name:'About',
        path:'/about',
        query:{
          name:'Echoyya',
          age: 25,
          obj:JSON.stringify({gender:"f"})
        },
      })
    }
    let gotoParams = () => {
       // params:只能使用name ,不顯示在地址欄中,且頁面刷新,參數清空 console.log(route.params); 打印空對象
       router.push({
        name:'Home',
        params:{
          name:'Echoyya',
          age: 25,
          obj:JSON.stringify({gender:"f"})
        }
      })
    }

    return {
      gotoQuery,
      gotoParams
    }
  }
}
  1. about組件中使用,接收路由參數
import { useRoute } from 'vue-router'
export default {
  setup (){
    // route對象表示當前的路由信息,包含了當前 URL 解析得到的信息。包含當前的路徑,參數,query對象等。
    let route = useRoute() 
    
    console.log(typeof route.query.age) //string, query傳遞的參數都是string類型
    console.log(route.query);    //獲取query傳參
    console.log(route.params);    //獲取params傳參
    return {}
  }
}

五、父子組件傳值

  1. 父 to 子:通過動態綁定屬性的方式,子組件在props 中去接收,

  2. 子 to 父:通過ctx.emit('事件名稱', 傳遞的參數)事件分發的方式, 父組件當中,調用子組件標簽上綁定自定義事件,其中包含一個參數,即子組件傳遞過來的數據

    • ctx.emit('事件名稱', 傳遞的參數)事件分發, ctx是 setup 函數的第二個參數,上下文對象

    • emit 只能接受兩個參數,其余不生效,第一個參數:事件名稱,第二個: 傳遞的數據

    • 事件分發,不一定要通過點擊事件,也可使用鈎子函數等

    • 需要傳遞多個參數時,emit第二個參數可選擇數組或是對象

father.vue

<template>
  <div class="wrapper">
    <p>this is father components</p>
    <p> 子組件傳遞的值:{{childMsg}}</p>
    <!-- msg 自定義屬性,send 自定義監聽事件-->
    <p><child :msg="msg" @send="getChildData"></child></p>
  </div>
</template>

<script>
import { ref } from 'vue'
import child from '../components/child'
export default {
  components:{
    child
  },
  setup() {
    let msg = ref('father組件數據')
    let childMsg = ref('')
    let getChildData = (data)=>{
      childMsg.value = data
    }
    return {
      msg,
      childMsg,
      getChildData
    }
  },
}
</script>

child.vue

<template>
  <div>
    this is child components
    <p>父組件傳遞過來的值:{{msg}}</p>
    <p><button @click="send">傳值給父組件</button></p>
  </div>
</template>

<script>
import {ref,onMounted, reactive} from  'vue'
export default {
  name:'child',
  // props 接收的數據,不能直接修改,如props.xxx = yy
  props:{
    msg:{
      type:String , // 數據類型校驗
      require:true ,  // 是否必傳 默認false
      default:'默認值' // require和default 有些沖突,即必填時,可不設置默認值
    }
  },
  setup(props,ctx){
    console.log(props.msg);   // 父組件傳遞的數據:father組件數據

    let childMsg = ref('child組件數據')
    let data = reactive({
      childNum:10
    })
    
    let send = ()=>{
       ctx.emit('send',childMsg.value)
       // ctx.emit('send',[childMsg.value,data.childNum])  // 數組
       // ctx.emit('send',{  // 對象
       //   msg:childMsg.value,
       //   num:data.childNum
      })  
    }
    return {
     childMsg,
     send,
     ...data
    }
  }
})
</script>

六、狀態管理的定義和使用

狀態管理即 VUEX,為達到數據共享的目的

  1. /src/store/index.js:在狀態管理文件中使用了createStore方法
import { createStore } from 'vuex'

export default createStore({
  // 定義所需要的狀態
  state: {
    name: 'Echoyya',
  },

  // 同步修改state ,是方法,不能操作異步操作(包括發送請求及定時器等)
  mutations: {
    // 可接收兩個參數:一:state,二:需修改的值,payload(可選)
    setName(state, payload) {
      state.name = payload
    },
  },
  // 提交 mutations
  actions: {
    // 可接收兩個參數 一:store, 二 要修改的值
    asyncSetName(store, params) {
      setTimeout(() => {
        // commit 是提交mutation, 提交異步的mutations方法
        store.commit('setName', params)
        console.log(store.state.name) 
      }, 2000)
    }
  },
  // 模塊化
  modules: {}
})

  1. 組件中調用,VUEX操作數據
<template>
  <div>
    {{name}}===={{name1}}===={{name2}}
    <p><button @click="setName">設置 name</button></p>
    <p><button @click="asyncSetName">異步設置 name</button></p>
  </div>
</template>

<script>
import { reactive, ref, toRefs, computed } from 'vue'
import { useStore } from 'vuex'

export default {
  setup (){
    //通過 ref 方式
    let name = ref(store.state.name)
   
    // 計算屬性 方式
    let name1 = computed(()=>{
      return store.state.name + 'computed'
    })
    
    //reactive 方式
    let data = reactive({
       name2:store.state.name + '_reactive'
    })
    
    // 觸發 mutations
    let setName = ()=>{
       console.log(store.state.name)  // Echoyya
       store.commit('setName','nhyya') 
       console.log(store.state.name)  // nhyya
    }
    // 觸發 action
    let asyncSetName = ()=>{
        store.dispatch('asyncSetName','nhyya1212') 
    }
    return {
      name,
      name1,
      ...toRefs(data),
      setName,
      asyncSetName
    }
  }
})
</script>

七、常用的生命周期

  1. setup:不需要引入的生命周期 ,表示組件創建的過程,且沒有this

  2. onMounted:比setup 稍微晚一些執行,表示組件掛載的過程,包括數據, dom元素等,是一個函數,需要傳入一個回調函數執行,無參數。

    • 常用於:發送請求、數據初始化的操作、接受路由傳遞的參數
  3. onUnmounted:與 onMounted 相對應,組件卸載或銷毀(路由跳轉),常用於清除定時器等操作

較 VUE2.0 另有哪些改變?

  • 3.0去掉了filter, 沒有beforeCreate created,用setup取代

  • setup里沒有this

  • 3.0兼容IE12以上

  • 可直接監聽數組類型的數據變化

  • 監聽的目標為對象本身,不需要像Object.defineProperty一樣遍歷每個屬性,有一定的性能提升

  • 直接實現對象屬性的新增/刪除

  • 重構 Virtual DOM:模板編譯時的優化,將一些靜態節點編譯成常量

  • 另附上vue3.0 文檔地址: https://v3.cn.vuejs.org/

上述內容並非全部 VUE3 內容,只是我通過一段時間的學習,做的自我總結,以便學習和復習,寫的不准確之處還望大神們能留言指正


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM