【前端VUE】VUE通信组件学习(附源代码)

admin 2023年12月21日07:49:50评论12 views字数 9345阅读31分9秒阅读模式

props

props可以实现父子组件通信,不管是在vue2或者vue3,props数据还是只读的!!!不能直接修改其值;在vue3中,我们可以通过defineProps获取父组件传递的数据,且在组建内部不需要引入defineProps方法可以直接使用,如下面例子
Parent.vue

//父组件
<template>
  <h3>
    props组件案例
  </h3>
  <div class="text_div">props可以实现父子组件通信,不管是在vue2或者vue3,props数据还是只读的!!!不能直接修改其值;在vue3中,我们可以通过defineProps获取父组件传递的数据,且在组建内部不需要引入defineProps方法可以直接使用,如下面例子</div>

<div class="box">
<h1>这是父组件</h1>
<Child1 info ="我是父组件传过来的值" :money="money"></Child1>
</div>
</template>
<script setup lang="js">
import Child1 from "@/views/props/Child1.vue";
import {ref} from "vue";
let money =ref(10000)

</script>
<style scoped>
.text_div{
width: 70%;
height: 50px;
background: #1db393;
}
.box{
width: 500px;
height: 300px;
background: hotpink;
}

</style>

Child1.vue

<template>
  <div class="son">
    <h3>这是子组件</h3>
    <p>{{ props.info }}</p>
    <p>{{ props.money }}</p>
    <button @click = "updateProps">修改props数据</button>
  </div>
</template>

<script setup lang="js">
let props = defineProps(['info','money']);

const updateProps =() =>{
console.log(props.info)
}
</script>
<style scoped>
.son {
width: 200px;
height: 200px;
background: yellow;
}

</style>

实现效果:【前端VUE】VUE通信组件学习(附源代码)

使用props,子组件获取父组件传递数据方式有两种:

方式一:
let props = defineProps({
  info:{
    type:String,//接受的数据类型
    default:'默认参数',//接受默认数据
  },
  money:{
    type:Number,
    default:0
  }})
方式二:
let props = defineProps(["info",'money']);

原生DOM事件

在vue框架中,事件可以分为两种:
一种是原生DOM事件(比如click、abclick、change、mouseenter、mouseleave.....),原生事件可以让用户与网页进行交互;
一种是自定义事件,自定义事件可以实现子组件给父组件传递数据
<!-- 原生DOM事件,默认会给事件回调注入event事件对象,无需写入 --><pre @click="handler"> 我是DOM原生事件</pre>
如果想给点击事件注入多个参数时,注入的事件对象必须叫做$event
<div @click="handler1(1,2,3,$event)">我要传递多个参数</div>
在vue3中click、dbclick、change(这类原生DOM事件),不管是在标签、自定义标签上(组件标签)都是原生DOM事件,而在vue2中组件、标签都需要通过.native修饰符才能变为原生DOM事件。

自定义事件

在vue3中,原生DOM事件不管是放在元素标签身上、组件标签上都是原生DOM事件,在vue2中,则需要通过.native修饰符变为原生DOM事件,如下:
父组件:

<template>
  <h1>自定义事件案例</h1>

<div class="fu">
<h2>这是父组件</h2>
<!-- 原生DOM事件-->
<pre @click = "handler">大江东去浪淘尽,千古分流人物</pre>
<hr>
<button @click="handler1(1,2,3,$event)">点击我传递多个参数</button>
<!--
vue2框架当中:这种写法自定义事件,可以通过.native修饰符变为原生DOM事件
vue3框架下面写法其实即为原生DOM事件
vue3:原生的DOM事件不管是放在标签身上、组件标签身上都是原生DOM事件
-->

<hr>
<zizujian1 @click="handler2"></zizujian1>
<hr>
<!-- 绑定自定义事件xxx:实现子组件给父组件传递数据 -->
<zizujian2 @xxx="handler3" @click="handler4"></zizujian2>
</div>
</template>
<script setup lang="js">
import zizujian1 from "@/views/zdy/zizujian1.vue";
import Zizujian2 from "@/views/zdy/zizujian2.vue";

// 回调事件-1
const handler = (event) =>{
console.log(event)
}
//事件回调--2
const handler1 = (a,b,c,$event)=>{
console.log(a,b,c,$event)
}
//事件回调--3
const handler2 = ()=>{
console.log("测试123")
}
//事件回调---4
const handler3 = (param1,param2)=>{
console.log(param1,param2);
}
//事件回调--5
const handler4 = (param1,param2)=>{
console.log(param1,param2);
}
</script>
<style scoped>
.fu {
width: 700px;
height: 700px;
background: #1db393;
}

</style>

子组件1

<template>
  <div class="son1">
    <p>我是子组件1</p>
    <button>点击我也执行</button>
  </div>
</template>

<style>
.son1{
width: 200px;
height: 200px;
background: #1b6d85;
}

</style>

子组件2

<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="js">
let $emit = defineEmits(['xxx','click']);
//按钮点击回调
const handler = () => {
//第一个参数:事件类型 第二个|三个|N参数即为注入数据
$emit('xxx','东风导弹','航母');
};

</script>
<style scoped>
.child {
width: 400px;
height: 200px;
background: pink;
}

</style>

【前端VUE】VUE通信组件学习(附源代码)

正常情况下,组件标签@click应该为原生DOM事件,但是如果子组件内部通过defineEmits定义就变为自定义事件了。

mitt

mitt是一个方法,会返回一个对象,该对象上挂载了四个方法,分别为all、on、off、emit

官网:https://www.npmjs.com/package/mitt

在src文件下新建文件bus/index.ts

//引入mitt插件:mitt一个方法,方法执行会返回bus对象
import mitt from 'mitt';
const $bus = mitt();
export default $bus;

父组件:

<template>
<div class="container">
      <Child1></Child1>
      <Child2></Child2>
 </div>
</template>

<script setup lang="ts">
//引入子组件
import Child1 from "./Child1.vue";
import Child2 from "./Child2.vue";

</script>
<style scoped>
.box {
width: 100vw;
height: 400px;
background: yellowgreen;
}
.container{
display: flex;
justify-content: space-between;
}

</style>

Child1.vue
<template> <div class="child1"> <h3>我是子组件1:曹植</h3> </div></template><script setup lang="ts">import $bus from "../../bus";//组合式API函数import { onMounted } from "vue";//组件挂载完毕的时候,当前组件绑定一个事件,接受将来兄弟组件传递的数据onMounted(() => { //第一个参数:即为事件类型 第二个参数:即为事件回调 $bus.on("car", (car) => { console.log(car); });});</script><style scoped>.child1 { width: 300px; height: 300px; background: hotpink;}</style>
Child2.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

v-model有两个功能,
一个是收集表单数据(实现数据双向绑定);
一个是实现父子组建数据同步。
父组件

<template>
  <div><h1>v-model:钱数{{ money }} {{ pageNo }} {{ pageSize }}</h1>
    <input type="text" v-model="info"/>
    <h5>v-model数据同步输入框信息:{{info}}</h5>
    <hr/>
    <!-- props:父亲给儿子数据 -->
    <!-- <Child :modelValue="money" @update:modelValue="handler"></Child> -->
    <!--
    v-model组件身上使用
    第一:相当有给子组件传递props[modelValue] = 10000
    第二:相当于给子组件绑定自定义事件update:modelValue     -->
    <zizujian1 v-model="money"></zizujian1>
    <hr/>
    <zizujian2 v-model:pageNo="pageNo" v-model:pageSize="pageSize"></zizujian2>
  </div>
</template>
<script setup lang="js">
//父亲给子组件数据 props
// 子组件给父组件数据 自定义事件
// 引入子组件
import zizujian1 from "@/views/v-model/zizujian1.vue";
import zizujian2 from "@/views/v-model/zizujian2.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>

子组件1

<template>
  <div class="child">
    <h3>钱数:{{ modelValue }}</h3>
    <button @click="handler">父子组件数据同步</button>
  </div>
</template>

<script setup lang="js">
//子组件获取父组件的值接受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>

子组件2

<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="js">
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>

【前端VUE】VUE通信组件学习(附源代码)

useAttrs

在Vue3中可以利用useAttrs方法获取组件的属性与事件(包含:原生DOM事件或者自定义事件),此函数功能类似于Vue2框架中attrs属性与listeners方法
父组件

<template>
  <h1>useAttrs组件学习</h1>
  <div class="fu" title="这是编辑按钮">
    <h2>这是父组件</h2>
<!--    自定义组件-->
    <el-button type="primary" size="default" :icon="Edit" @click="handler" @xxx="handler">修改按钮</el-button>
<!--    给子组件1传入参数-->
    <zizujian1 type="primary" size="default" :icon="Edit" @click="handler" @xxx="handler"></zizujian1>
  </div>
</template>

<script setup lang="js">
import zizujian1 from "@/views/useAttrs/zizujian1.vue";
import {
Edit,
} from '@element-plus/icons-vue'
const handler = () =>{
alert("点击了编辑按钮")
}

</script>
<style scoped>
.fu {
width: 100vw;
height: 600px;
background: #1db393;
}

</style>

子组件

<template>
  <div class="son">
    <h2>这是子组件1</h2>
    <el-button :="$attrs"></el-button>
  </div>

</template>
<script setup lang="js">
import {useAttrs} from "vue";

let $attrs = useAttrs();
console.log($attrs)
</script>
<style scoped>
.son {
width: 300px;
height: 200px;
background: #42b983;
}

</style>

【前端VUE】VUE通信组件学习(附源代码)

ref与$parent

父组件

<template>
  <h1>这是父组件</h1>
  <div class="fu">
    <h2>我是父亲刘备:{{ money }}</h2>
    <button @click="handler">
      点我向儿子刘封借100元
    </button>
    <zizujian2 ref="son1"></zizujian2>
    <zizujian1></zizujian1>
  </div>
</template>

<script setup lang="js">
import {ref} from "vue";
import zizujian1 from "@/views/ref_parent/zizujian1.vue";
import zizujian2 from "@/views/ref_parent/zizujian2.vue";
import Zizujian1 from "@/views/ref_parent/zizujian1.vue";

let money = ref(10000000);
let son1 =ref()
const handler = () => {
money.value += 100;
son1.value.money -=100;
son1.value.fly()
}
defineExpose(
{
money,
}
)
</script>
<style scoped>
.fu {
width: 100vw;
height: 600px;
background: #1db393;
}

</style>

子组件1

<template>
<div class="son">
     <h1>我是儿子刘婵{{money}}</h1>
     <button @click="handler($parent)">点击我爸爸给我10000元</button>
  </div>
</template>

<script setup lang="js">
import {ref} from 'vue';
let money = ref(999999);
const handler = ($parent)=>{
money.value+=10000;
$parent.money-=10000;
}

</script>
<style scoped>
.son{
width: 300px;
height: 300px;
background: hotpink;
}

</style>

子组件2

<template>
  <div class="son">
    <h3>我是子组件:刘封{{money}}</h3>
  </div>
</template>

<script setup lang="js">
import {ref} from "vue";
let money =ref(1000)
const fly =()=>{
alert("父亲刘备向我借了100")
}

defineExpose(
{
money,
fly
}
)
</script>
<style scoped>
.son {
width: 300px;
height: 200px;
background: cyan;
}

</style>

【前端VUE】VUE通信组件学习(附源代码)

provide(提供)与inject(注入)

vue3提供两个方法provide与inject,可以实现隔辈组件传递参数
provide方法用于提供数据,此方法执需要传递两个参数,分别提供数据的key与提供数据value
爷组件

<template>
  <div class="box">
    <h1>我是父组件</h1>

<h2>car:{{ car }}</h2>
<hr>
<zizujian></zizujian>
</div>
</template>
<script setup lang="js">
import zizujian from "@/views/provide_inject/zizujian.vue";
//vue3提供provde与inject可以实现隔辈传递数据
import {ref, provide} from 'vue';

let car = ref("法拉利")
//provide 需要传入两个参数 第一个参数提供数据的key 第二个 祖先组件提供的数据
provide("fucar", car)
</script>
<style scoped>
.box {
width: 100vw;
height: 500px;
background: skyblue;
}

</style>

子组件

<template>
  <div class="er">
  <h1>儿子组件</h1>
    <runzujian></runzujian>
</div>

</template>
<script setup lang="js">
import runzujian from "@/views/provide_inject/runzujian.vue";

</script>
<style scoped>
.er{
width: 400px;
height: 300px;
background: palevioletred;
}

</style>

孙组件

<template>
<div class="sun">
  <h1>孙子组件</h1>
  <h2>{{car}}</h2>
</div>
</template>

<script setup lang="js">
import {inject} from "vue";

let car =inject("fucar")
</script>
<style scoped>
.sun{
width: 200px;
height: 200px;
background: red;
}

</style>

【前端VUE】VUE通信组件学习(附源代码)

pipa

pinia也是集中式管理状态容器,类似于vuex,
但是核心概念没有mutation、modules

solt

插槽:分为默认插槽、具名插槽、作用域插槽

原文始发于微信公众号(小C学安全):【前端VUE】VUE通信组件学习(附源代码)

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年12月21日07:49:50
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   【前端VUE】VUE通信组件学习(附源代码)https://cn-sec.com/archives/2320011.html

发表评论

匿名网友 填写信息