IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> vue3 + typescript 实现组件间通信 -> 正文阅读

[JavaScript知识库]vue3 + typescript 实现组件间通信

vue 组件间通信分为 :

父组件向子组件通信
子组件向父组件通信
兄弟间组件通信

父组件向子组件通信

父组件向子组件通信的关键是defineProps函数
父组件向子组件传递一个字符串,子组件接收这个字符串并展示出来
father.vue

<script setup lang="ts">
import Son from './Son.vue'
</script>

<template>
  <Son msg="这信息来自父组件" /></Son>
</template>

son.vue

<script setup lang="ts">
    defineProps<{msg:string}>()
</script>

<template>
    <div class="son">
        子组件内容:
        <p></p>
        <div>{{msg}}</div>
    </div>
</template>

这里要特别注意的是 defineProps 在 typescript 的专用写法:defineProps<>() ,而且 defineProps 是在 setup 语法糖才能使用, defineProps无须引入。

<template>
  <h1>{{ msg }}</h1>
  <div @click="clickThis">1111</div>
</template>

<script setup lang="ts">
  defineProps<{ // 采用ts专有声明,无默认值
    msg: string,
    num?: number
  }>()
     // 采用ts专有声明,有默认值
    interface Props {
        msg?: string
        labels?: string[]
    }
    const props = withDefaults(defineProps<Props>(), {
        msg: 'hello',
        labels: () => ['one', 'two']
    })
    
  defineProps({ // 非ts专有声明
    msg: String,
    num: {
      type:Number,
      default: ''
    }
  })
</script>

<style scoped lang="less">
</style>

defineEmits

子组件向父组件事件传递

<template>
  <div @click="clickThis">点我</div>
</template>

<script setup lang="ts">
    /*ts专有*/
  const emit= defineEmits<{
    (e: 'click', num: number): void
  }>()
    /*非ts专有*/
  const emit= defineEmits(['click'])
  
  const clickThis = () => {
    emit('click',2)
  }
</script>

<style scoped lang="less">
</style>


子组件向父组件通信

子组件向父组件通信的关键是defineEmits函数
Son.vue 通过 defineEmits 定义事件传递方法 toFather

<script setup lang="ts">
    const emit = defineEmits<{(e:'toFather',msg:string):void}>()
    const click = () =>{
        emit('toFather','来自子组件信息')
    }
</script>

<template>
    <div class="son">
        子组件内容:
        <p></p>
        <button @click="click">
        点击传信息给父组件
        </button>
    </div>
</template>

defineExpose的用法

在vue2.x中我们可以通过this. r e f s . x x x 或 者 t h i s . refs.xxx或者 this. refs.xxxthis.parent 链获取到的组件的公开实例,

但是使用

为了在

假如我们要在子组件里暴露一个handleClick2方法,我们要先定义这个方法

const handleClick2 = () => {
  a.value = 3
  obj.name = '我叫改变'
};

然后整个

// defineExpose 统一暴露
defineExpose({
    a,
    obj,
    handleClick2
})

因为如果defineExpose代码行在上,handleClick2申明在下,会报错

//定义对象属性
 interface defineObj {
      readonly name: string; //只读属性
      age: number; //必填
      sex?: string; //选填
      call(): string; //有返回值,类型为string
      action(): void; //必填、无返回值
      [propName: string]: any; //任意属性
      //需要注意的是,一旦定义了任意属性,那么确定属性和可选属性都必须是它的子属性
 }
 const obj = reactive<defineObj>({
      name: "abc", //只读,不可修改
      age: 18, //sex:'男',
      a: "a",
      b: 9,
      c: true,
      call: () => "call",
      action: function () {
        console.log("void接口");
      },
      o: { id: 1 },
 });

点击跳转

defineExpose

暴露自己的属性供父组件使用

const count = ref(0);
defineExpose({
  count,
});<HelloWorld  ref="child" />
const child = ref(null);
onMounted(() => {
  console.log("child", child.value.count);
});

组件实战

父组件

<template>
  <HelloWorld :msg="msg"  @change="change"/>
  <p v-if="state.msg1!==''">   {{state.msg1}}</p>
</template>

<script  lang="ts">
import { defineComponent,ref,reactive } from 'vue';
import HelloWorld from './components/HelloWorld.vue';

export default defineComponent({
  name: 'App',
  components: {
    HelloWorld
  },
  setup(){
     let msg=ref("天下无敌")
     let state=reactive({
       msg1:""
     });
     let change=(val:string)=>{
       console.log("子组件传参过来了",val)
       state.msg1=val
       console.log(state.msg1)
     }
    return{
       msg,
       change,
       state
    }
  }
});
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

子组件

<template>
  <div class="hello" @click="change">
    {{msg}}
  </div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';

export default defineComponent({
  name: 'HelloWorld',
  props: {
    msg: String,
  },
  setup(props,context){
     let change=()=>{
       console.log("数据正在改变")
       context.emit('change','hellowoolad')
     }
     return{
       change
     }
  }
});
</script>

<style scoped>
</style>

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-06-26 16:49:40  更:2022-06-26 16:50:56 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 17:07:16-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码