前言
上次写了关于自己初次使用vue3的一些感受,同时也获取了一众大佬的教导,其中最重要的是方法的setup的语法糖,为了搞清楚这个语法糖,我自己有把之前的页面,又重新重构了一次。果然得到真香定律,使用以后发现原来vue3还可以像react那样简洁的处理方法和传值,话不多说上代码看下吧
内部变量
首先看下内部变量变化,这是单纯之前使用setup
<template>
<div>
<div>
子组件内String:{{infor}}
</div>
<div>
子组件内obj:{{obj.data}}
</div>
<div>
子组件内arry:{{arry[0]}}
</div>
<div @click="changeInfor">
改变obj
</div>
</div>
</template>
<script>
import { ref, onMounted, defineEmits, defineProps, defineExpose, reactive } from "vue";
export default {
setup(){
const infor = ref('infor')
const obj = reactive({
data:'obj'
})
const arry = reactive([111,222,333])
const changeInfor = () =>{
obj.data = 'changeObj'
}
return {
infor, obj, arry, changeInfor
}
}
}
</script>
<style>
div{
line-height: 40px;
}
</style>
这是改成语法糖之后的代码
<template>
<div>
<div>
子组件内String:{{infor}}
</div>
<div>
子组件内obj:{{obj.data}}
</div>
<div>
子组件内arry:{{arry[0]}}
</div>
<div @click="changeInfor">
改变obj
</div>
</div>
</template>
<script setup>
import { ref, onMounted, defineEmits, defineProps, defineExpose, reactive } from "vue";
const infor = ref('infor')
const obj = reactive({
data:'obj'
})
const arry = reactive([111,222,333])
const changeInfor = () =>{
infor.value = '32323'
obj.data = 'changeObj'
}
</script>
<style>
div{
line-height: 40px;
}
</style>
这里可以明显看出来,未使用setup-script的方式,跟传统的还是有很大区别的, 结构简单明了,不需要把大量的变量和方法都写在setup这个函数里面,自由度很高,有点像react的类里面的使用方法
子父级传值
这里面主要涉及到三个方法 defineEmits,defineProps,defineExpose
// 父组件
<template>
<div>
父组件
<children ref="child" @getData="sentData" :data="data"/>
<div>{{childData || '我还没收到值'}}</div>
<div @click="makeClid">点击调用子组件方法</div>
</div>
</template>
<script setup>
import { ref, onMounted, defineEmits, defineProps, defineExpose, reactive } from "vue";
import children from './components/children.vue'
const childData = ref('')
const data = ref('父组件给的值prop传值')
const sentData = (data) =>{
childData.value = data
}
const child = ref(null) // 获取子组件ref
const makeClid = () =>{
child.value.setData('子组件已调用')
}
</script>
// 子组件
<template>
<div>
{{fatherData || '父组件还未调用我'}}
<div @click="getData">触发父组件</div>
<div>fatherProps:{{fatherProps}}</div>
</div>
</template>
<script setup>
import { ref, onMounted, defineEmits, defineProps, defineExpose, reactive } from "vue";
const fatherData = ref('')
const fatherProps = ref('')
const props = defineProps({ // 父组件传值
data:String
})
fatherProps.value = props.data
const emit = defineEmits(['getData']) // 接受父组件数据
const getData = () =>{
emit('getData','给父组件的值') // 触发父组件的方法
}
const setData = (val) =>{ // 父组件调用
fatherData.value = val
}
defineExpose({ // 抛出方法
getData,
setData
})
</script>
- 子组件调用父组件:这点很好理解,跟vue2差不多的形式,父组件里面挂载@getData,子组件里面通过defineEmits这个方法获取,最后调用方式跟之前也是一样的
- 父组件调用子组件:这点区别还是很大的,需要子组件先定义好方法,然后通过defineExpose暴露出去,父组件创建ref,这里需要创建的变量名字和子组件的ref名字一直,否者获取不到,最后通过获取抛出的value找到对应的方法。