与vue2的方法一样
1 父给子传值 props
我们通过在父组件引用子组件的时候,可以通过自定义属性进行值的传递,在子组件通过 props 进行接收。
父传值给的是值
父
<template>
<div class="main">
<rcode :tovalue="test"></rcode>
</div>
</template>
<script lang='ts'>
import rcode from "../component/list.vue";//这是子的文件
import { ref, watch, reactive, toRefs } from "vue";
export default {
components: { rcode },
setup() {
const test = ref("yangyang");
const data = reactive({
list: "12121",
});
const refData = toRefs(data);
return {
...refData,
test,
};
},
};
</script>
<style scoped>
.main {
font-size: 16px;
}
</style>
子
components/login/QRcode.vue //子文件
<template>
<div class="qrCode">
我是子
{{ tovalue }}
</div>
</template>
<script lang='ts'>
import { reactive, toRefs } from "vue";
export default {
name: "",
props: ["tovalue"],
setup() {
const data = reactive({});
const refData = toRefs(data);
return {
...refData,
};
},
};
</script>
<style scoped></style>
2 子组件向父组件传递 emit
子传父是通过点击事件传递值
子
<template>
<div class="qrCode">
我是子
</div>
<br>
<button @click="send">点击你</button>
</template>
<script lang='ts'>
import { reactive, toRefs } from "vue";
export default {
name: "",
setup(props, context) {
const data = reactive({
send(){
//使用setup中第二个参数向父组件发出信息,调用父组件中子组件上定义的接收方法“receiveChild”
context.emit("receiveChild", "这是一条来自子组件的消息");
}
});
const refData = toRefs(data);
return {
...refData,
};
},
};
</script>
<style scoped></style>
父
<template>
<div class="main">
<rcode @receiveChild="btnFa"></rcode>
</div>
</template>
<script lang='ts'>
import rcode from "../component/list.vue";//这是子的文件
import { ref, watch, reactive, toRefs } from "vue";
export default {
components: { rcode },
setup() {
const data = reactive({
btnFa(e) {
//输出接收到子组件传来的值,输出:“这是一条来自子组件的消息”
alert(e)
}
});
const refData = toRefs(data);
return {
...refData,
};
},
};
</script>
<style scoped>
.main {
font-size: 16px;
}
</style>
3 v-model传值
父
<template>
<div class="main">
我是父
<rcode v-model:aaa="aaa"></rcode>
</div>
</template>
<script lang='ts'>
import rcode from "../component/list.vue";//这是子的文件
import { ref, watch, reactive, toRefs } from "vue";
export default {
components: { rcode },
setup() {
const data = reactive({
aaa:20,
});
const refData = toRefs(data);
return {
...refData,
};
},
};
</script>
<style scoped>
.main {
font-size: 16px;
}
</style>
子
<template>
<div class="qrCode">
我是子
</div>
<br>
<div >{{ aaa }}</div>
<button @click="send">点击你</button>
</template>
<script lang='ts'>
import { reactive, toRefs } from "vue";
export default {
name: "",
props: { aaa: Number },
setup(props, context) {
const data = reactive({
send() {
context.emit('update:aaa',200)//事件名 修改的数值
}
});
const refData = toRefs(data);
return {
...refData,
};
},
};
</script>
<style scoped></style>
4 兄弟组件之间通讯
安装:npm i mitt -s
点击按钮,改变兄弟组件的值
1.父组件
<template>
<div>
<brotherC></brotherC>
<brotherD></brotherD>
</div>
</template>
<script>
import brotherC from "@/components/brother/brotherC";
import brotherD from "@/components/brother/brotherD";
export default {
name: "brotherLink",
components: {
brotherC,
brotherD,
},
}
</script>
2.子组件1
<template>
<div>
<h2>brotherC</h2>
<a-button @click="changeMsg" type="primary">点击修改msg</a-button>
</div>
</template>
<script>
import { reactive, ref } from "vue";
import emitter from "@/common/js/utils/mitt.js";
export default {
name: "brotherC",
setup() {
let changeMsg = () => {
emitter.emit('change-msg')
};
return {
changeMsg,
};
},
};
</script>
<style lang='scss' scoped>
</style>
3.子组件2
<template>
<div>
<h2>brotherD</h2>
<p>{{ msg }}</p>
</div>
</template>
<script>
import { reactive, ref, onUnmounted } from "vue";
import emitter from "@/common/js/utils/mitt.js"
export default {
name: "brotherD",
setup() {
let msg = ref("hello");
let changeMsg = ()=>{
msg.value = '我被改变啦';
}
// 监听事件,更新数据
emitter.on('change-msg',changeMsg)
// 卸载
onUnmounted(()=>{
console.log('onUnmounted')
emitter.off('change-msg',changeMsg)
})
return {
msg,
changeMsg
};
},
};
</script>
<style lang='scss' scoped>
</style>
4.mitt.js
import mitt from 'mitt';
const emitter = mitt();
export default emitter;
5 自定义事件
父
<template>
<div>1111111111</div>
<!-- 自定义事件 -->
<aTwo @xxx="handle"></aTwo>
</template>
<script lang='ts'>
import a1 from '../components/a1.vue'
import aTwo from '../components/a2.vue'
import { reactive, toRefs, onBeforeMount, onMounted } from 'vue'
import { useRouter, useRoute } from 'vue-router'//引入路由
export default {
name: '',
components: {
aTwo
},
setup() {
let router = useRouter(), route = useRoute();
const data = reactive({
handle(par1, par2) {
console.log(par1, par2);
}
})
onBeforeMount(() => {
})
onMounted(() => {
})
const refData = toRefs(data);
return {
...refData,
}
}
};
</script>
<style scoped></style>
子
<template>
<div>a2</div>
<div @click="handle">点击我触发xxx数据</div>
</template>
<script lang='ts'>
import { defineProps, defineEmits, reactive, toRefs, onBeforeMount, onMounted } from 'vue'
import { useRouter, useRoute } from 'vue-router'//引入路由
export default {
name: '',
$emit: defineEmits(['xxx']),
setup() {
let router = useRouter(), route = useRoute();
const data = reactive({
// 使用defineEmits方法返回函数自定义事件
handle() {
this.$emit('xxx', '45454545')
}
})
onBeforeMount(() => {
})
onMounted(() => {
})
const refData = toRefs(data);
return {
...refData,
}
}
};
</script>
<style scoped></style>
6 useAttrs方法
vue3提供useAttrs方法 可以获取组件的属性与事件
父
<template>
<div>1111111111</div>
<aTwo type="primary" icon="Edit" title="编辑"> </aTwo>
<!-- <el-button type="primary" icon="Edit" circle /> -->
</template>
<script lang='ts'>
import a1 from '../components/a1.vue'
import aTwo from '../components/a2.vue'
import { Edit } from '@element-plus/icons-vue';
import { useAttrs, reactive, toRefs, onBeforeMount, onMounted } from 'vue'
import { useRouter, useRoute } from 'vue-router'//引入路由
export default {
name: '',
components: {
aTwo,
Edit
},
setup() {
let router = useRouter(), route = useRoute();
const data = reactive({
// vue3提供useAttrs方法 可以获取组件的属性与事件
})
onBeforeMount(() => {
})
onMounted(() => {
})
const refData = toRefs(data);
return {
...refData,
}
}
};
</script>
<style scoped></style>
子
<template>
<div :title="attr.title">
<el-button :="attr" />
</div>
<!-- v-bind="{a:1,b:2}" 相当于:="{a:1,b:2}" -->
</template>
<script lang='ts'>
import { useAttrs, reactive, toRefs, onBeforeMount, onMounted } from 'vue'
import { useRouter, useRoute } from 'vue-router'//引入路由
export default {
name: '',
setup() {
let router = useRouter(), route = useRoute();
const data = reactive({
attr: useAttrs(),
// props与useAttrs都可以获取父组件传递过来的属性与属性值
// 但是prps接收了 useAttrs就接收不到 优先级高
})
console.log(data.attr);
onBeforeMount(() => {
})
onMounted(() => {
})
const refData = toRefs(data);
return {
...refData,
}
}
};
</script>
<style scoped></style>
7 ref
ref 父直接拿到子组件数据
父
<template>
<div>曹操{{ money }}</div>
<button @click="btnclick">点击曹操+10 曹植-10</button>
<aTwo ref="son"></aTwo>
</template>
<script lang='ts'>
import a1 from '../components/a1.vue'
import aTwo from '../components/a2.vue'
import { ref, reactive, toRefs, onBeforeMount, onMounted } from 'vue'
import { useRouter, useRoute } from 'vue-router'//引入路由
export default {
name: '',
components: {
aTwo,
},
setup() {
let router = useRouter(), route = useRoute();
const data = reactive({
son: ref(),
money: 1000,
btnclick() {
data.money += 10;
data.son.money -= 10;
}
})
onBeforeMount(() => {
})
onMounted(() => {
})
const refData = toRefs(data);
return {
...refData,
}
}
};
</script>
<style scoped></style>
子
<template>
<div>曹植{{ money }}</div>
</template>
<script lang='ts'>
import { ref, defineExpose, reactive, toRefs, onBeforeMount, onMounted } from 'vue'
import { useRouter, useRoute } from 'vue-router'//引入路由
export default {
name: '',
setup() {
let router = useRouter(), route = useRoute();
// let money = ref(10)//定义子的值
const data = reactive({
money: ref(10)//定义子的值
})
// 组件内部数据对外关闭 通过defineExpose暴露出去
onBeforeMount(() => {
})
onMounted(() => {
})
defineExpose({
...toRefs(data)//暴露出去 这个是data里面所有的数据都暴露
})
const refData = toRefs(data);
return {
...refData,
}
}
};
</script>
<style scoped></style>
7.1 $parent
子拿到父的数据
父
<template>
<div>曹操{{ money }}</div>
<!-- <button @click="btnclick">点击曹操+10 曹植-10</button> -->
<aTwo ref="son"></aTwo>
</template>
<script lang='ts'>
import a1 from '../components/a1.vue'
import aTwo from '../components/a2.vue'
import { ref, defineExpose, reactive, toRefs, onBeforeMount, onMounted } from 'vue'
import { useRouter, useRoute } from 'vue-router'//引入路由
export default {
name: '',
components: {
aTwo,
},
setup() {
let router = useRouter(), route = useRoute();
const data = reactive({
son: ref(),
money: 1000,
})
onBeforeMount(() => {
})
onMounted(() => {
})
defineExpose({
...toRefs(data)//暴露出去 这个是data里面所有的数据都暴露
})
const refData = toRefs(data);
return {
...refData,
}
}
};
</script>
<style scoped></style>
子
<template>
<div>曹植{{ money }}</div>
<button @click="btnclick($parent)">点击父组件</button>
</template>
<script lang='ts'>
import { ref, defineExpose, reactive, toRefs, onBeforeMount, onMounted } from 'vue'
import { useRouter, useRoute } from 'vue-router'//引入路由
export default {
name: '',
setup() {
let router = useRouter(), route = useRoute();
// let money = ref(10)//定义子的值
const data = reactive({
money: ref(10),//定义子的值
btnclick($parent) {
data.money += 10
$parent.money-=1
}
})
// 组件内部数据对外关闭 通过defineExpose暴露出去
onBeforeMount(() => {
})
onMounted(() => {
})
// defineExpose({
// ...toRefs(data)//暴露出去 这个是data里面所有的数据都暴露
// })
const refData = toRefs(data);
return {
...refData,
}
}
};
</script>
<style scoped></style>
8 provide/inject
父
<template>
<div>123456</div>
<aTwo></aTwo>
</template>
<script lang='ts'>
import a1 from '../components/a1.vue'
import aTwo from '../components/a2.vue'
import { ref, provide, defineExpose, reactive, toRefs, onBeforeMount, onMounted } from 'vue'
import { useRouter, useRoute } from 'vue-router'//引入路由
export default {
name: '',
components: {
aTwo,
},
setup() {
let router = useRouter(), route = useRoute();
const data = reactive({
// provide提供与inject注入可以实现隔辈传值
car: '法拉利'
// provide 2个参数 第一个数据的key 第二个祖先组件提供的数据
})
onBeforeMount(() => {
provide("token", data.car)
})
onMounted(() => {
})
const refData = toRefs(data);
return {
...refData,
}
}
};
</script>
<style scoped></style>
子
a2.vue
<template>
<div>我是子组件</div>
<a1></a1>
</template>
<script lang='ts'>
import a1 from '../components/a1.vue'
import { reactive, toRefs, onBeforeMount, onMounted } from 'vue'
import { useRouter, useRoute } from 'vue-router'//引入路由
export default {
name: '',
components: {
a1,
},
setup() {
let router = useRouter(), route = useRoute();
const data = reactive({
})
onBeforeMount(() => {
})
onMounted(() => {
})
const refData = toRefs(data);
return {
...refData,
}
}
};
</script>
<style scoped></style>
祖孙
a1.vue
<template>
<div>我是孙子组件{{ car }}</div>
</template>
<script lang='ts'>
import { inject, provide, reactive, toRefs, onBeforeMount, onMounted } from 'vue'
import { useRouter, useRoute } from 'vue-router'//引入路由
export default {
name: '',
setup() {
let router = useRouter(), route = useRoute();
// 注入祖先组件提供的数据
const data = reactive({
car: inject("token")
})
onBeforeMount(() => {
console.log(inject("token"), '12');
})
onMounted(() => {
})
const refData = toRefs(data);
return {
...refData,
}
}
};
</script>
<style scoped></style>
9 slot(插槽)
在这里插入代码片