<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>