setup函数
1. 执行时间 创建实例之前执行
2. setup函数里面没有this this=undefined
3. 组件视图数据和方法来自setup函数 必须return数据提供使用
两种写法:
<script>
export default {
setup(){
定义数组的变量数据和方法
const str='hello'
function fun(params){log('测试')}
return {str,fun}
}}
</script>
// 第二种
<script setup>
{/* 默认私有的,子组件访问不了 */}
{/* 想访问的话 需要defineExpose 宏显式暴露 */}
import { ref } from 'vue'
const a = 1
const b = ref(2)
defineExpose({
a,
b
})
</script>
写法二 是私有的 想访问的话 需要defineExpose 宏显式暴露
生命周期
setup 创建实例前
onBeforeMount 挂载dom前
onMounted 挂载dom后
onBeforeUpdate 更新组件前
onUpdated 更新组件后
onBeforeUnmount 卸载销毁前
onUnmounted 卸载销毁后
注意:生命周期可以写多个
响应式数据
ref
响应式数据:简单数据类型
语法:修改值或者获取值 都需要.value
import {ref} from 'vue'
setup(){
// 1.定义简单数据类型
let count=ref(100)
// 修改值
count.value++;
// 2.定义复杂数据类型
let obj=ref({user:'admin',age:20})
// 修改值
obj.value.user='新值'
return {str}
}
未知数据类型变量 用ref定义
const data=ref(null)
复杂数据类型变量 建议reactive
const arr=reactive([10,20])
reactive
响应式数据:复杂数据类型
语法:
定义--let obj=reactive({user:'小小'})
导入--import {reactive} from 'vue'
import {reactive} from 'vue'
setup(){
// 默认数据视图不响应
let str='hello'
// 定义响应式数据--对象
let obj=reactive({user:'小胖'})
// 修改值
obj.user='新值'
return {str}
}
toRef
响应式数据:转换响应式对象中某个属性为单独响应式数据,并且值是关联的
注意:从响应式数据对象中解构赋值出的属性数据,不再是响应式数据,需要用toRef去转换
语法:toRef(object对象,key键名)
import {toRef} from 'vue'
let user=toRef(obj,'user')
// user提取后 修改值 user.value='xxx' 原数据obj里面属性user同步修改
user.value='新值'
toRefs
定义响应式数据:转换响应式对象中所有属性为单独响应式数据,对象为普通对象,并且值时关联的
import {toRefs} from 'vue'
let obj2=toRefs(obj)
// 修改值
obj2.user.value='新值'
计算属性computed
缓存内容--只要依赖的变量修改 重新执行
setup(){
// 定义数据
let age=ref(20)
// 修改年龄
const changeAge=()=>{
age.value++
}
// 计算属性--计算年龄并缓存
const newAge=computed(()=>{
return age.value+2
})
return {
age,changeAge
}
}
get和set 只读和写入
// 创建一个只读的计算属性 ref:
const count = ref(1)
const plusOne = computed(() => count.value + 1)
console.log(plusOne.value) // 2
plusOne.value++ // 错误
// 创建一个可写的计算属性 ref:
const count = ref(1)
const plusOne = computed({
get: () => count.value + 1,
set: (val) => {
count.value = val - 1
}
})
plusOne.value = 1
console.log(count.value) // 0
侦听器watch
监听数据变化
语法:watch(监听目标元素,回调函数,{配置信息})
// 1.简单数据类型
let count=ref(100);
watch(count,(n,o)={log(n,o,'数据修改了')})
// 修改数据
const changeCount=()=>{
count.value++;
}
// 2.复杂数据类型
let obj=reactive({user:'admin',love:{eat:'红烧鹅',food:'牛肉面'}})
watch(obj,(n,o)=>{log('修改了')})
watch(()=>obj.love,(n,o)=>{log('修改了')},{
deep:true,//深度监听
immediate:true,//默认触发 首次进来就触发
})
// 修改的方法
const changeObj=()=>{
obj.user='啦啦啦'
}
const changeLove=()=>{
obj.love.eat='芹菜炒肉'
}
return {count,changeCount,obj,changeObj,changeLove}
深度监听
deep:true,//深度监听
immediate:true,//默认触发 首次进来就触发
ref获取dom元素
1. 声明一个 ref 来存放该元素的引用
2. 必须和模板里的 ref 同名
3. 修改值 需要ref.value
//定义ref变量 目的:获取dom元素
<div ref='box'>请获取我</div>
<button @click='getRef'>点击获取ref</button>
// 获取dom元素
const box=ref(null)
function getRef(){
box.value.style.color='red'
}
props-emit
1. 父传子: <子组件 msg='数据'>
子组件接收props:['msg','num']
2. 子传父:
emits:['change'],//抛出事件
setup(props,context){
context
<!-- 通知父组件修改 -->
context.emit('change',100)
}
父组件:<子组件 @change='change'>
function change=(val)=>{log(val)}
provide-inject
pinia
获取this
vue3中使用this,vue为我们提供了getCurrentInstance方法,该方法返回了ctx和proxy。
import { getCurrentInstance } from 'vue'
const { ctx } = getCurrentInstance() as any;//开发环境下使用
const { proxy } = getCurrentInstance() as any;//开发和生产环境都可以使用(推荐)