对比vue2中的data
- data需要return数据变量才能被template访问,存在this指针指向全局变量
- setup需要return数据才内让template访问其内部的数据(变量及函数),但是setup中没有引入this变量
setup接受参数
两个参数(props、context)
- props参数:绑定上一级组件传递过来的数据(需要声明数据类型才能传递)
- context:上下文对象
响应式props传递数据
例:father组件通过模板中的组件传递数据给childString
Father.vue
<template>
<div class='father'>
{{test}}
</div>
<Son :childString="test"></Son>
</template>
<script>
import {
provide,
reactive
} from 'vue'
import Son from './Son'
export default {
components: {
Son
},
props: {
FatherData: String
},
setup(props) {
console.log('Father的props', props)
const leyoData = reactive({
name: 'leyo',
age: 18
})
console.log('father的leyData',leyoData)
let test = "father的数据"
provide('leyoData', leyoData)
return {
test
}
}
}
</script>
<style>
.father {
position: relative;
background: burlywood;
}
</style>
Son.vue
/* eslint-disable vue/no-setup-props-destructure */
<template>
<div class='son'>
childString:{{childString? childString:'未传入数据'}}<br>
childData:{{childData}}
</div>
</template>
<script>
import { inject } from 'vue'
export default {
props:{
childArray:Array,
childString:String,
childNumber:Number,
childObject:Object
},
setup(props) {
const leyoData = inject('leyoData')
console.log('上一级组件的leyData',leyoData)
leyoData.name='yma16'
let childData ='我是child定义的childData数据'
console.log('child的props',props)
return{
childData
}
}
}
</script>
<style>
.son{
position: relative;
background: rgb(177, 125, 226);
}
</style>
father的数据
child的接受的数据
不能使用 ES6 解构,它会消除 prop 的响应性
解构(非响应式)
props中toRefs和toRef区别
toRefs :若传入的 props 中可能没有定义的数据,将不会 创建一个 ref
toRef:若传入的 props 中可能没有定义的数据,会创建一个ref
共同点:都是object,得通过.value访问
非响应式context(可解构)
使用渲染函数h
理解:类似document.write(html),或者网div后加入dom节点
例:渲染一个div显示文本
<template>
<div></div>
</template>
<script>
import { h, ref, reactive } from 'vue'
export default {
setup() {
const readersNumber = ref(0)
const book = reactive({ title: 'Vue 3 的渲染函数' })
// 请注意这里我们需要显式使用 ref 的 value
return () => h('div', [readersNumber.value, book.title])
}
}
</script>
缺陷:返回一个渲染函数将阻止我们返回任何其它的东西。从内部来说这不应该成为一个问题,但当我们想要将这个组件的方法通过模板 ref 暴露给父组件时就不一样了。
如何让父组件访问渲染函数组件的内部
通过调用 expose 来解决这个问题,给它传递一个对象,其中定义的 property 将可以被外部组件实例
父组件:helloworld调用渲染组件
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<Father></Father>
<Other></Other>
<Learn ref="RefChilde"></Learn>
<button @click="clickFun">调用子组件的按钮</button>
</div>
</template>
<script>
import { ref } from 'vue'
import Father from './Father'
import Other from './Other'
import Learn from './Learn'
export default {
components:{
Father,
Other,
Learn
},
name: 'HelloWorld',
props: {
msg: String
},
setup(){
const RefChilde = ref(); //RefChilde 要和Son组件上的class名相同
console.log('ref',RefChilde)
console.log('ref.value',RefChilde.value)
let clickFun=()=>{RefChilde.value.increment()}
return {
RefChilde,
clickFun
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
渲染组件:
<template>
<div></div>
</template>
<script>
import { h, ref } from 'vue'
export default {
setup(props, { expose }) {
const count = ref(0)
const increment = () => ++count.value
expose({
increment
})
return () => h('div', count.value)
}
}
</script>