<template>
<img alt="Vue logo" src="./assets/logo.png">
<h1>{{ count }}</h1>
<!-- vue內部對一個ref對象在模板中引入的時候 可以直接幫我們把里面的值展示出來 所以寫count 而不是count.value -->
<h1>{{ double }}</h1>
<ul>
<li v-for="number in numbers" :key="number">{{ number }}</li>
</ul>
<h1>{{ person.name }}</h1>
<button @click="increase">點擊 + 1</button>
</template>
<script lang="ts">
import { ref, computed, reactive, toRefs, onMounted, onUpdated, onRenderTriggered, watch } from 'vue' // vue3中的Api reactive與ref相似函數 參數是一個對象
interface DataProps {
count: number;
double: number;
increase: () => void;
numbers: number[];
person: { name?: string }
}
export default {
name: 'App',
setup() { // 准備
// const count = ref(0) // ref是一個函數 接受一個參數返回一個響應式對象 響應式就是監測到到改變 做出對應的響應
// const double = computed(() => {
// return count.value * 2
// })
// const increase = () => {
// count.value++
// }
// vue3生命周期
// beforeCreate created => setup()
// beforemMount => onBeforeMount
// mounted => onMounted
// beforeUpdate => onBeforeUpdate
// updated => onUpdated
// beforeDestory => onBeforeUnmount
// destoryed => onUnmounted
// activated => onActivated
// deactivated => onDeactivated
// errorCaptured => onErrorCaptured
// 新增
// onRenderTracked
// onRenderTriggered
onMounted(() => {
console.log('mounted')
})
onUpdated(() => {
console.log('onUpdated')
})
onRenderTriggered((event) => { // 觀察數據變化
console.log(event)
})
const data: DataProps = reactive({ // 這里data報一個類型錯誤 因為data.count * 2 造成類型推論的循環 因為TS的局限性vue3無法解決這個問題 會把data自動為any類型 所以要把data指定一個類型
count: 0, // reactive會有一個缺陷 取出值 值的類型會失去響應式功能 所以要引入toRefs Api
increase: () => { data.count++ },
double: computed(() => data.count * 2 ),
numbers: [0, 1, 2],
person: {}
})
// vue3響應式對象的高明之處 內部依賴Es6 Proxy對象 內部完美支持對象數組的修改操作 使this.$set操作成為過去時
data.numbers[0] = 5
data.person.name = 'hky'
const refData = toRefs(data) // 接受一個reactive對象 把里面的值變為Ref類型 因為只有Ref才是響應式的
return { // 更好的追蹤引用和更新的情況
...refData
}
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
/* -webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale; */
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>