「每天都为最平凡的一天而奋斗,当这一天的结束,你就会比它开始的时候,变得有那么一点点不平凡。」
目录
数据定义
ref
<template>
<div>
<!-- 页面使用ref定义并抛出的数据 -->
{{num}}
<button @click="change">修改</button>
</div>
</template>
<script>
//vue3中所有实例属性,方法,配置等都需要按需引入
import {ref} from 'vue'
export default {
setup(props) {
const num=ref(1) //ref方法定义一个响应式属性
const change=()=>{ //方法在外面单独定义,key=箭头函数格式
num.value=2 //修改值需要修改key.value
}
//抛出,变量和方法必须抛出后才能在模板中使用
return {
num,change
}
}
}
</script>
reactive
<template>
<div>
<!-- 页面使用reactive定义并抛出的数据 -->
{{user}}
</div>
</template>
<script>
//vue3中所有实例属性,方法,配置等都需要按需引入
import {reactive,toRefs} from 'vue'
export default {
setup(props) {
const state=reactive({ //reactive定义一个响应式对象
user:'py是个小白菜',
age:20
})
let name='tom'
return {
...toRefs(state) //使用...toRefs()方法能将state对象中的属性解构出来在页面中使用
,name //普通变量,可在页面初次渲染使用,无法进行响应式
}
}
}
</script>
//提升了性能,影响我代码体验……
生命周期
import { onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted, onActivated, onDeactivated, onErrorCaptured } from 'vue'
export default {
setup() {
onBeforeMount(() => {
// ...
})
onMounted(() => {
// ...
})
onBeforeUpdate(() => {
// ...
})
onUpdated(() => {
// ...
})
onBeforeUnmount(() => {
// ...
})
onUnmounted(() => {
// ...
})
onActivated(() => {
// ...
})
onDeactivated(() => {
// ...
})
onErrorCaptured(() => {
// ...
})
}
}
路由与当前路由对象
引入useRouter
useRouter
方法,调用后获取路由对象
<template>
<div></div>
</template>
<script>
import {useRouter,useRoute} from 'vue-router' //从vue-router中引入
export default {
setup(props) {
const router=useRouter() //路由实例对象,上面集成了路由的跳转等方法
const route=useRoute() //当前路由信息对象,可查看route.path route.meta
console.log(router);
console.log(route);
//跳转路由
router.push('/')
}
}
</script>
父子组件通信
props
emit
//父组件
<template>
<div>
<!-- 子组件 绑定值传值,绑定方法传方法 -->
<ChildComponent :val="val" @changeVal_parent="changeVal"></ChildComponent>
</div>
</template>
<script>
import { ref } from 'vue'
//引入子组件
import ChildComponent from '../components/Child'
export default {
components:{ChildComponent}, //子组件注册
setup (props) {
const val=ref('我是父组件过来的哦')
const changeVal=()=>{
val.value='我被子组件修改了'
}
return {
val,changeVal //变量与方法抛出
}
}
}
</script>
//子组件
<template>
<div>
<!-- 在页面展示 -->
{{val}}
<button @click="changeVal">修改</button>
</div>
</template>
<script>
export default {
props:{val:String}, //外部使用props接收父组件数据
setup(props,{emit}) { //接收一个{emit} 作为调用父组件方法
console.log(props.val); //可以在此查看打印结果
const changeVal=()=>{ //子组件方法,只为调用父组件方法
emit('changeVal_parent') //调用父组件传入的方法
}
return {
changeVal
}
}
}
</script>
监听器和计算属性
watch
computed
<template>
<div>
{{num}}
<button @click="add">加加</button>
<h1>计算属性:{{res}}</h1>
</div>
</template>
<script>
import {computed,ref,watch} from 'vue' //引入计算属性,监听器
export default {
setup(props) {
const num=ref(0) //定义响应式属性
watch(num,(newVal,oldVal)=>{ //监听器语法
console.log(newVal,oldVal); //打印新值和旧值,如果监听的是引用类型,无法打印旧值
})
const res=computed(()=>{ //计算属性语法 根据依赖值的改变而改变
return num.value*10
})
const add=()=>{
num.value++
}
return{
num,add,res
}
}
}
</script>
关于深度侦听
<template>
<div>
{{obj1.age}}
<button @click="add">加加</button>
</div>
</template>
<script>
import { shallowReactive, shallowRef, reactive, ref, watch } from 'vue' //引入计算属性,监听器
export default {
setup (props) {
const obj = reactive({
age: 20,
phone: {
a: 123
}
})
const obj1 = shallowReactive({
age: 20,
phone: {
a: 123
}
})
watch(() => obj,
(newVal, oldVal) => {
console.log(newVal.age, oldVal.age); //21 21 引用数据类型只能获取到改变后的值
console.log(newVal.phone) //124,监听成功
},
{ deep: true }
)
watch(() => obj1,
(newVal, oldVal) => {
console.log(newVal.age, oldVal.age); //21 21
console.log(newVal.phone) //124 修改不会触发监听
},
{ deep: true }
)
const add = () => {
// obj.age++;
// obj.phone.a++
// obj1.age++; //可监听到
obj1.phone.a++; //监听不到,数据会发生改变
}
return {
add, obj,obj1
}
}
}
</script>
ref以及reactive是递归监听,可以监听到对象深层的改变;某些情况下(对象层级较深),性能消耗较大
vue3提供了
shallowReactive方法,只能数据第一层改变能触发监听
shallowRef监听,那么监听的是.value的变化,并不是第一层变化
一般情况下我们使用ref和reactive即可,只有在需要监听的数据量比较大的时候,才需要shallowReactive和shallowRef来降低性能消耗.