天天看點

vue3.0學習文檔

删除的api

  • o n , on, on,off,$once

$on,$off,$once被删除執行個體方法。應用程式執行個體不再實作事件發射器接口

vue2.X版本

eventBus.js

const eventHub = new Vue()
export default eventHub
           

childComponent.vue

// ChildComponent.vue
import eventHub from './eventHub'
export default {
  mounted() {
    // adding eventHub listener
    eventHub.$on('custom-event', () => {
      console.log('Custom event triggered!')
    })
  },
  beforeDestroy() {
    // removing eventHub listener
    eventHub.$off('custom-event')
  }
}
           

parentComponent.vue

import eventHub from './eventHub'
export default {
  methods: {
    callGlobalCustomEvent() {
      eventHub.$emit('custom-event') // if ChildComponent is mounted, we will have a message in the console
    }
  }
}
           
vue3.0版本

我們删除$on,$off,$once從完全的執行個體方法。$emit仍然是現有API的一部分,因為它用于觸發由父元件聲明式附加的事件處理程式

  • 過濾器

    過濾器已從Vue 3.0中删除,不再受支援

vue2.X文法
<template>
  <h1>Bank Account Balance</h1>
  <p>{{ accountBalance | currencyUSD }}</p>
</template>
<script>
  export default {
    props: {
      accountBalance: {
        type: Number,
        required: true
      }
    },
    filters: {
      currencyUSD(value) {
        return '$' + value
      }
    }
  }
</script>
           
vue3.X文法

在3.x中,過濾器已删除,不再受支援。相反,我們建議将它們替換為方法調用或計算的屬性

<template>
  <h1>Bank Account Balance</h1>
  <p>{{ accountInUSD }}</p>
</template>

<script>
  export default {
    props: {
      accountBalance: {
        type: Number,
        required: true
      }
    },
    computed: {
      accountInUSD() {
        return '$' + this.accountBalance
      }
    }
  }
</script>
           
  • 多根節點
vue2.X文法

在2.x中,不支援多根元件,并且在使用者意外建立元件時會發出警告。結果,許多元件被包裝在一個

中,以解決此錯誤。

<template>
  <div>
    <header>...</header>
    <main>...</main>
    <footer>...</footer>
  </div>
</template>
           
vue3.X文法
<!-- Layout.vue -->
<template>
  <header>...</header>
  <main v-bind="$attrs">...</main>
  <footer>...</footer>
</template>
           
  • setup(vue3.X文法)
<template>
  <div>{{count}}: {{double}}</div>
  <button @click="increment">+1</button>
</template>

<script>
  import { ref, computed } from 'vue'
  export default {
    setup() {
      let count = ref('abc')
      let double = computed(() => count.value + 'de')
      function increment() {
        count.value = count.value + 'f';
      }
      return {
        count,
        double,
        increment
      }
    }
  }
</script>
           
vue3.0學習文檔
  • 代碼複用

    useCount.js

import { ref, computed } from 'vue'
function useCount() {
    let count = ref(0)
    let double = computed(() => count.value * 2)
    function increment() {
        count.value++
    }
    return {
        count,
        double,
        increment
    }
}
export default useCount
           

app.vue

import useCount from './useCount.js'
export default {
    setup() {
        let { count, double, increment } = useCount()
        return { 
            count,
            double,
            increment
        }
    }
}
           
  • 生命周期(vue3.0文法)

App.vue

<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <HelloWorld msg="Hello Vue 3.0 + Vite" @count="fnCount">
    <div>我是slots1</div>
    <div>我是slots2</div>
    <div>我是slots3</div>
    <div>我是slots4</div>
    <div>我是slots5</div>
  </HelloWorld>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'

export default {
  name: 'App',
  setup(props,context){
    function fnCount(count){
      console.log(count); // 1,2,3,4,5...
    }
    return {
      fnCount
    }
  },
  components: {
    HelloWorld
  }
}
</script>
           

HelloWorld.vue

<template>
  <div>props值:{{msgProps}}</div>
  <div>{{count}}: {{double}}</div>
  <button @click="increment">改變count</button>
  <slot></slot>
</template>

<script>
  import useCount from './useCount.js'
  import { ref, computed, onMounted  } from 'vue'
  export default {
    props: {
      msg: {
        type: String,
        defalut: ''
      }
    },
    setup(props,context) {
      let { count, double, increment, msgProps } = useCount(props, context)
      onMounted(() => {
        console.log(context.slots.default()); //擷取到父級slot插槽中内容
      })
      return {
        count,
        double,
        increment,
        msgProps
      }
    }
  }
</script>
           
vue3.0學習文檔
  • reactive(vue3.0文法)

    連結:https://v3.vuejs.org/api/basic-reactivity.html#reactive

    HelloWorld.vue

<template>
  <div>props值:{{msgProps}}</div>
  <div>{{count}}: {{double}}</div>
  <button @click="increment">改變count</button>
  <!-- 點選fnChange改變,我是改變後的title -->
  {{state.title}}
  <button @click="fnChange">改變title</button>
  <slot></slot>
</template>

<script>
  import useCount from './useCount.js'
  import { ref, computed, onMounted, reactive  } from 'vue'
  export default {
    props: {
      msg: {
        type: String,
        defalut: ''
      }
    },
    setup(props,context) {
      let { count, double, increment, msgProps } = useCount(props, context)
      const state = reactive({ title: '原title' })
      function fnChange(){
        state.title = '我是改變後的title'
      }
      onMounted(() => {
        console.log(context.slots.default())
      })
      return {
        count,
        double,
        increment,
        msgProps,
        fnChange,
        state
      }
    }
  }
</script>
           
  • 渲染函數(vue3.0)
import { h, ref, reactive } from 'vue'
export default {
  setup() {
    const readersNumber = ref(0)
    const book = reactive({ title: 'Vue 3 Guide' })
    // Please note that we need to explicitly expose ref value here
    return () => h('div', [readersNumber.value, book.title])
  }
}
           
  • provide & inject(vue3.0)

    類似于vue2中provide與inject, vue3提供了對應的provide與inject API,實作元件傳參。

    provide 函數允許你通過兩個參數定義 property:

  1. property 的 name ( 類型)
  2. property 的 value

myMap.vue

<script>
    import {provide} from 'vue'
    import myMarker from './myMarker.vue'
    export default {
        name: "myMap",
        components:{
            myMarker
        },
        setup(){
            provide('location', 'North Pole')
            provide('geolocation', {
                longitude: 90,
                latitude: 135
            })
        }
    }
</script>
           

myMarker.vue

<template>
    {{userLocation}} {{userGeolocation.longitude}}
</template>

<script>
    import { inject } from 'vue'
    export default {
        setup() {
            const userLocation = inject('location', 'The Universe')
            const userGeolocation = inject('geolocation')
            return {
                userLocation,
                userGeolocation
            }
        }
    }
</script>
<style scoped>

</style>
           
  • watch & computed(vue3.0文法)

watch:偵聽器,接受三個參數

  1. 一個響應式引用或我們想要偵聽的 getter 函數
  2. 一個回調
  3. 可選的配置選項
import { ref, watch } from 'vue'
export default {
    setup() {
        const counter = ref(0)
        watch(counter, (newValue, oldValue) => {
            console.log('The new counter value is: ' + counter.value)
        })
    },
    // setup中的相當于以下
    data() {
        return {
            counter: 0
        }
    },
    watch: {
        counter(newValue, oldValue) {
            console.log('The new counter value is: ' + this.counter)
        }
    }
}
           

或者如下代碼:

<template>
    {{obj.a}}
    {{count}}
    <button @click="fnChangeCount">改變count</button>
<!--    <myMarker/>-->
</template>

<script>
    import {provide, watch, ref, reactive} from 'vue'
    // import myMarker from './myMarker.vue'
    export default {
        name: "myMap",
        // components:{
        //     myMarker
        // },
        setup(){
            let count = ref(0);
            let obj = ref({a: 1})
            function fnChangeCount(){
                count.value++;
                obj['value']['a'] = 2;
            }

            function getProxy(obj) {
                return new Proxy(obj, {
                    get: function(target, property) {
                        if (property in target) {
                            return target[property];
                        } else {
                            throw new ReferenceError("Property \"" + property + "\" does not exist.");
                        }
                    }
                });

            }

            watch(count, (newVal, oldVal) => {
                console.log(newVal,oldVal)
            })
            watch(obj, (newVal, oldVal) => {
                console.log(getProxy(newVal).a, getProxy(oldVal).a)
            },{
                deep: true,     // 深度監聽
                lazy: true,     // vue中的immediate,預設挂載後執行
                flush: '',      // 三個值:'post'(預設), 'pre', 'sync'
                                // 'pre': 表示在狀态更新時同步調用
                                // 'sync':表示在元件更新之前調用
                onTrack(){},    // 在reactive屬性或ref被追蹤為依賴時調用。
                onTrigger(){
                    
                }   // 在watcher的回調因依賴改變而觸發時調用。
            })
            return {
                obj,
                count,
                fnChangeCount
            }
            // provide('location', 'North Pole')
            // provide('geolocation', {
            //     longitude: 90,
            //     latitude: 135
            // })
        }
    }
</script>
<style scoped>

</style>
           

watch第三個參數:

{
    deep: true,     // 深度監聽
    lazy: true,     // vue中的immediate,預設挂載後執行
    flush: '',      // 三個值:'post'(預設), 'pre', 'sync'
                    // 'pre': 表示在狀态更新時同步調用
                    // 'sync':表示在元件更新之前調用
    onTrack(){},    // 在reactive屬性或ref被追蹤為依賴時調用。
    onTrigger(){}   // 在watcher的回調因依賴改變而觸發時調用。
}
           
  • computed

    與vue2中computed功能一緻,它接收一個函數并傳回一個value為getter傳回值的不可改變的響應式ref對象。

const count = ref(1)
const plusOne = computed(() => count.value + 1)
console.log(plusOne.value) // 2
plusOne.value++ // 錯誤,computed不可改變

// 同樣支援set和get屬性
onst count = ref(1)
const plusOne = computed({
    get: () => count.value + 1,
    set: val => { count.value = val - 1 }
})
plusOne.value = 1
console.log(count.value) // 0

           
vue