Vue3
安装与新增扩展
安装
https://jspang.com/detailed?id=64#toc21
- npm install -g @vue/cli # OR yarn global add @vue/cli
- vue --version 低于V4.5.4 不能创建 vue3 ; npm install -g @vue/cli
- vue create vue3-1
setup 、ref使用
<div class='app'>
<h2>请选择一位佳丽:</h2>
<div>
<button
v-for="(item,key) in girls"
:key="key"
@click="selectGirlFun(key)"
>{{key+1 }} : {{item}}</button>
</div>
<p>您选择了【{{selectGirl}}】为你服务!</p>
</div>
setup() {
const girls = ref(['张三', 'lisi'])
const selectGirl = ref('')
const selectGirlFun = (index: number) => {
// 在使用和获取ref时都要加上.value属性,模板中直接使用是vue3做了处理
selectGirl.value = girls.value[index]
}
// 只有return之后,才能全局使用
return {
girls,
selectGirl,
selectGirlFun,
}
},
reactive函数 toRefs
还没有什么实质性的理论到底是用Ref()好,还是reactive()好,也就是两种方法都可以。他们的作用都是生成响应式对象,目前来看只是编写上有所不同。
<template>
<div class='app'>
<h2>请选择一位佳丽:</h2>
<div>
<button
v-for="(item,key) in girls"
:key="key"
@click="selectGirlFun(key)"
>{{key+1 }} : {{item}}</button>
</div>
<p>您选择了【{{selectGirl}}】为你服务!</p>
</div>
</template>
<script lang="ts">
import { reactive,toRefs } from 'vue'
// 给data加上类型注解
interface DataProps {
girls: string[];
selectGirl: string;
selectGirlFun: (idnex: number) => void;
}
export default {
name: 'App',
setup() {
const data: DataProps = reactive({
girls: ['张三', 'lisi'],
selectGirl: '',
selectGirlFun: (index: number) => {
data.selectGirl = data.girls[index]
},
})
// 通过toRefs方法,使用扩展运算符对外暴露一个对象
const refData = toRefs(data)
// refData.girls refData.selectGirl 变成可相应式数据 可以在模板中使用
return {
...refData
}
},
}
</script>
生命周期
Vue 是组件化编程,从一个组件诞生到消亡,会经历很多过程,这些过程就叫做生命周期。
setup() :开始创建组件之前,在beforeCreate和created之前执行。创建的是data和method
onBeforeMount() : 组件挂载到节点上之前执行的函数。
onMounted() : 组件挂载完成后执行的函数。
onBeforeUpdate(): 组件更新之前执行的函数。
onUpdated(): 组件更新完成之后执行的函数。
onBeforeUnmount(): 组件卸载之前执行的函数。
onUnmounted(): 组件卸载完成后执行的函数
onActivated(): 被包含在<keep-alive>中的组件,会多出两个生命周期钩子函数。被激活时执行。
onDeactivated(): 比如从 A 组件,切换到 B 组件,A 组件消失时执行。
onErrorCaptured(): 当捕获一个来自子孙组件的异常时激活钩子函数(以后用到再讲,不好展现)。
// 只要页面有update的情况,他就会跟踪,然后生成一个event对象,我们通过event对象来查找程序的问题所在。
onRenderTracked((Event)=>{
console.log(Event)
})
// 状态触发,它不会跟踪每一个值,而是给你变化值的信息,并且新值和旧值都会给你明确的展示出来。
// 如果把onRenderTracked比喻成散弹枪,每个值都进行跟踪,那onRenderTriggered就是狙击枪,只精确跟踪发生变化的值,进行针对性调试。
onRenderTriggered((Event)=>{
console.log(Event)
})
watch :所有的副作用写在watch中
setup() {
const data = reactive({
overText: '完成了吗?',
overHandle: () => {
data.overText = '完成了吗?' + '点餐完成!'
// 这种写法不好,响应式或者可以响应式变量,又改变界面又改变标题而且使用了原生方法:副作用
// 好的写法是 所有的副作用写在watch里面
// document.title = overText.value
},
})
const refData = toRefs(data)
// watch第一个参数可以是一个数组或者一个变量 要么是ref或者get/set方法返回reactive中的值的问题
// watch(overText, (newVal, oldVal) => {
watch([() => data.overText], (newVal) => {
document.title = newVal[0].toString()
})
return {
...refData,
}
},
模块化
import { reactive } from 'vue'
const getDate = reactive({
title: 'this is a test title',
nowTime: '00:00:00',
getNowTime: () => {
const now = new Date()
const hour = now.getHours() < 10 ? '0' + now.getHours() : now.getHours()
const miunis =
now.getMinutes() < 10 ? '0' + now.getMinutes() : now.getMinutes()
const second =
now.getSeconds() < 10 ? '0' + now.getSeconds() : now.getSeconds()
getDate.nowTime = hour + ':' + miunis + ':' + second
setInterval(() => {
getDate.getNowTime()
}, 1000)
},
})
export {
getDate
}
<template>
<div class='app'>
{{title}}
<p>当前时间是:{{nowTime}}</p>
<p @click="getNowTime">获取当前时间</p>
</div>
</template>
<script lang="ts">
import { toRefs } from 'vue'
import { getDate } from './hooks/useNowTime'
export default {
name: 'App',
setup() {
const refData = toRefs(getDate)
return {
...refData,
}
},
}
</script>