赞
踩
实现父子组件通信,过defineProps获取父组件传递的数据
- <template>
- <div class="box">
- <h1>props:我是父组件曹操</h1>
- <hr />
- <Child info="我是曹操" :money="money" :shy="shy"></Child>
- </div>
- </template>
-
- <script setup lang="ts">
- //props:可以实现父子组件通信,props数据还是只读的!!!
- import Child from './Child.vue'
- import { ref } from 'vue'
- let money = ref(10000)
- let shy = ref<string>('说话啊!')
- </script>
-
- <style scoped>
- .box {
- width: 100vw;
- height: 400px;
- background: yellowgreen;
- }
- </style>
- <template>
- <div class="son">
- <h1>我是子组件:曹植</h1>
- <p>{{props.info}}</p>
- <p>{{props.money}}</p>
- <!--props可以省略前面的名字--->
- <p>{{info}}</p>
- <p>{{money}} -- {{ shy}}</p>
- <button @click="updateProps">修改props数据</button>
- </div>
- </template>
-
- <script setup lang="ts">
- //需要使用到defineProps方法去接受父组件传递过来的数据
- //defineProps是Vue3提供方法,不需要引入直接使用
- // 第一种接受方式
- // let props = defineProps(['info','money']); 返回代理对象
- // 第二种接受方式
- let props = defineProps({
- shy: {
- type: Number,
- default: 0
- },
- info: {
- type: String,
- default: '我是曹植'
- },
- money: {
- type: Number,
- default: 1000
- }
- })
- //按钮点击的回调
- const updateProps = () => {
- // props.money+=10; props:只能读
- console.log(props.info)
- }
- </script>
-
- <style scoped>
- .son {
- width: 400px;
- height: 200px;
- background: hotpink;
- }
- </style>
实现子组件向父组件传递数据
Event1子组件
- <template>
- <div class="son">
- <p>我是子组件1</p>
- <!-- 父组件绑定事件@click作用在跟节点上的 -->
- <button>点击我也执行</button>
- </div>
- </template>
-
- <script setup lang="ts">
- </script>
-
- <style scoped>
- .son {
- width: 400px;
- height: 200px;
- background: skyblue;
- }
- </style>
Event2子组件
- <template>
- <div class="child">
- <p>我是子组件2</p>
- <button @click="handler">点击我触发自定义事件xxx</button>
- <button @click="$emit('click','AK47','J20')">点击我触发自定义事件click</button>
- </div>
- </template>
-
- <script setup lang="ts">
- //利用defineEmits方法返回函数触发自定义事件
- let $emit = defineEmits(['xxx', 'click']) 返回一个$emit方法
- //按钮点击回调
- const handler = () => {
- //第一个参数:事件类型 第二个|三个|N参数即为注入数据
- $emit('xxx', '东风导弹', '航母')
- }
- </script>
-
- <style scoped>
- .child {
- width: 400px;
- height: 200px;
- background: pink;
- }
- </style>
EventText父组件
正常说组件标签书写@click应该为原生DOM事件,但是如果子组件内部通过defineEmits定义就变为自定义事件了
- <template>
- <div>
- <h1>自定义事件</h1>
- <!--
- vue2框架当中:这种写法自定义事件,通过.native变为原生DOM事件
- vue3框架这种写法为原生DOM事件,是作用在子组件的根节点上
- -->
- <Event1 @click="handler1"></Event1>
- <hr>
- <!-- 绑定自定义事件xxx:实现子组件给父组件传递数据 -->
- <Event2 @xxx="handler2" @click="handler3"></Event2>
- </div>
- </template>
-
- <script setup lang="ts">
- //引入子组件
- import Event1 from './Event1.vue'
- //引入子组件
- import Event2 from './Event2.vue'
- //事件回调---1
- const handler1 = () => {
- console.log(123)
- }
- //事件回调---2
- const handler2 = (param1, param2) => {
- console.log(param1, param2)
- }
- //事件回调--3
- const handler3 = (param1, param2) => {
- console.log(param1, param2)
- }
- </script>
-
- <style scoped>
- </style>
全局事件总线可以实现任意组件通信,通过插件mitt实现。
src/bus/index.ts
- //引入mitt插件:mitt一个方法,方法执行会返回bus对象
- import mitt from 'mitt';
- const $bus = mitt();
- export default $bus;
child1.vue
- <template>
- <div class="child1">
- <h3>我是子组件1:曹植</h3>
- </div>
- </template>
-
- <script setup lang="ts">
- import $bus from "../../bus";
- import { onMounted } from "vue";
- //组件绑定一个事件,接受兄弟组件传递的数据
- onMounted(() => {
- //第一个参数:即为事件类型 第二个参数:即为事件回调
- $bus.on("car", (car) => {
- console.log(car);
- });
- });
- </script>
-
- <style scoped>
- .child1 {
- width: 300px;
- height: 300px;
- background: hotpink;
- }
- </style>
Childe2.vue
- <template>
- <div class="child2">
- <h2>我是子组件2:曹丕</h2>
- <button @click="handler">点击我给兄弟送一台法拉利</button>
- </div>
- </template>
-
- <script setup lang="ts">
- //引入$bus对象
- import $bus from '../../bus';
- //点击按钮回调
- const handler = ()=>{
- $bus.emit('car',{car:"法拉利"});
- }
- </script>
-
- <style scoped>
- .child2{
- width: 300px;
- height: 300px;
- background: skyblue;
- }
- </style>
v-model可以收集表单数据(数据双向绑定),还可以实现父子组件数据同步。
利用props[modelValue]与自定义事件[update:modelValue]实现的
child.vue
- <template>
- <div class="child">
- <h3>钱数:{{ modelValue }}</h3>
- <button @click="handler">父子组件数据同步</button>
- </div>
- </template>
-
- <script setup lang="ts">
- //接受props
- let props = defineProps(["modelValue"]);
- let $emit = defineEmits(['update:modelValue']);
- //子组件内部按钮的点击回调
- const handler = ()=>{
- //触发自定义事件
- $emit('update:modelValue',props.modelValue+1000);
- }
- </script>
-
- <style scoped>
- .child {
- width: 600px;
- height: 300px;
- background: skyblue;
- }
- </style>
child1.vue
- <template>
- <div class="child2">
- <h1>同时绑定多个v-model</h1>
- <button @click="handler">pageNo{{ pageNo }}</button>
- <button @click="$emit('update:pageSize', pageSize + 4)">
- pageSize{{ pageSize }}
- </button>
- </div>
- </template>
-
- <script setup lang="ts">
- let props = defineProps(["pageNo", "pageSize"]);
- let $emit = defineEmits(["update:pageNo", "update:pageSize"]);
- //第一个按钮的事件回调
- const handler = () => {
- $emit("update:pageNo", props.pageNo + 3);
- };
- </script>
-
- <style scoped>
- .child2 {
- width: 300px;
- height: 300px;
- background: hotpink;
- }
- </style>
ModelTest.vue
- <template>
- <div>
- <h1>v-model:钱数{{ money }}{{pageNo}}{{pageSize}}</h1>
- <input type="text" v-model="info" />
- <hr />
- <!-- props:父亲给儿子数据 -->
- <!-- <Child :modelValue="money" @update:modelValue="handler"></Child> -->
- <!--
- v-model组件身上使用
- 第一:相当给子组件传递props[modelValue] = 10000
- 第二:相当给子组件绑定自定义事件update:modelValue
- -->
- <Child v-model="money"></Child>
- <hr />
- <Child1 v-model:pageNo="pageNo" v-model:pageSize="pageSize"></Child1>
- </div>
- </template>
-
- <script setup lang="ts">
- //父亲给子组件数据 props
- //子组件给父组件数据 自定义事件
- import Child from './Child.vue'
- import Child1 from './Child1.vue'
- import { ref } from 'vue'
- let info = ref('')
- //父组件的数据钱数
- let money = ref(10000)
- //自定义事件的回调
- const handler = num => {
- //将来接受子组件传递过来的数据
- money.value = num
- }
-
- //父亲的数据
- let pageNo = ref(1)
- let pageSize = ref(3)
- </script>
-
- <style scoped>
- </style>
useAttrs方法获取组件的属性与事件(包含:原生DOM事件或者自定义事件)
父组件AttrsListentersText
- <template>
- <div>
- <h1>useAttrs</h1>
- <el-button type="primary" size="small" :icon="Edit"></el-button>
- <!-- 自定义组件 -->
- <HintButton type="primary" size="small" :icon="Edit" title="编辑按钮" @click="handler" @xxx="handler"></HintButton>
- </div>
- </template>
-
- <script setup lang="ts">
- //vue3框架提供一个方法useAttrs方法,它可以获取组件身上的属性与事件!!!
- //图标组件
- import {
- Check,
- Delete,
- Edit,
- Message,
- Search,
- Star,
- } from "@element-plus/icons-vue";
- import HintButton from "./HintButton.vue";
- //按钮点击的回调
- const handler = () => {
- alert(12306);
- }
- </script>
-
- <style scoped></style>
hintButton.vue
- <template>
- <div :title="title">
- <el-button :="$attrs"></el-button>
- </div>
- </template>
-
- <script setup lang="ts">
- //引入useAttrs方法:获取组件标签身上属性与事件
- import { useAttrs } from 'vue';
- //此方法执行会返回一个对象
- let $attrs = useAttrs();
-
- let props = defineProps(['title']);
- //props与useAttrs方法都可以获取父组件传递过来的属性与属性值
- //props接受了useAttrs方法就获取不到了
- console.log($attrs);
- </script>
-
- <style scoped></style>
ref可以获取元素的DOM或者获取子组件实例的VC
父组件内部代码: RefChildrenParentTest.vue
- <template>
- <div class="box">
- <h1>我是父亲曹操:{{ money }}</h1>
- <button @click="handler">找我的儿子曹植借10元</button>
- <hr>
- <Son ref="son"></Son>
- <hr>
- <Dau></Dau>
- </div>
- </template>
-
- <script setup lang="ts">
- //ref:可以获取真实的DOM节点,可以获取到子组件实例VC
- //$parent:可以在子组件内部获取到父组件的实例
- //引入子组件
- import Son from './Son.vue'
- import Dau from './Daughter.vue'
- import { ref } from 'vue';
- //父组件钱数
- let money = ref(100000000);
- //获取子组件的实例
- let son = ref();
- //父组件内部按钮点击回调
- const handler = () => {
- money.value += 10;
- //儿子钱数减去10
- son.value.money -= 10;
- son.value.fly();
- }
- //对外暴露
- defineExpose({
- money
- })
- </script>
-
- <style scoped>
- .box {
- width: 100vw;
- height: 500px;
- background: skyblue;
- }
- </style>
父组件获取子组件的数据或者方法需要通过defineExpose对外暴露,因为vue3中组件内部的数据对外“关闭的”,外部不能访问
son.vue
- <template>
- <div class="son">
- <h3>我是子组件:曹植{{money}}</h3>
- </div>
- </template>
-
- <script setup lang="ts">
- import {ref} from 'vue';
- //儿子钱数
- let money = ref(666);
- const fly = ()=>{
- console.log('我可以飞');
- }
- //组件内部数据对外关闭的,别人不能访问
- //如果想让外部访问需要通过defineExpose方法对外暴露
- defineExpose({
- money,
- fly
- })
- </script>
-
- <style scoped>
- .son {
- width: 300px;
- height: 200px;
- background: cyan;
- }
- </style>
获取父组件的数据Daughter.vue
$parent可以获取某一个组件的父组件实例VC,因此可以使用父组件内部的数据与方法。必须子组件内部拥有一个按钮点击时候获取父组件实例,当然父组件的数据与方法需要通过defineExpose方法对外暴露
<button @click="handler($parent)">点击我获取父组件实例</button>
- <template>
- <div class="dau">
- <h3>我是曹操的闺女曹杰:{{ money }}</h3>
- <button @click="handlerFath($parent)">跟我老爸拿1000元</button>
- </div>
- </template>
-
- <script setup lang="ts">
- import { ref } from 'vue';
- //闺女钱数
- let money = ref(999999);
- //闺女按钮点击回调
- const handlerFath = (parent) => {
- money.value += 1000,
- console.log(parent.money -= 1000);
-
- // $parent.money -= 1000
- }
- </script>
-
- <style scoped>
- .dau {
- width: 300px;
- height: 300px;
- background: hotpink;
- }
- </style>
vue3提供两个方法provide与inject,可以实现隔辈组件传递参数
provide方法用于提供数据,此方法执需要传递两个参数,分别提供数据的key与提供数据value
- <script setup lang="ts">
- import {provide} from 'vue'
- provide('token','admin_token');
- </script>
后代组件可以通过inject方法获取数据,通过key获取存储的数值
- <script setup lang="ts">
- import {inject} from 'vue'
- let token = inject('token');
- </script>
- // 可以进行修改
- const updateCar = ()=>{
- car.value = '自行车';
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。