Vue2、Vue3组件通信

 Vue3

父子通信

defineProps(父传子)

如果子组件想修改父组件传来的数据,可以使用回调函数

//子组件
<template>
  <div>
    <h2>我是子组件</h2>
    <button @click="change">点击子组件</button>
    <p>子组件: {{ info }}</p>
  </div>
</template>
<script setup lang="ts">
defineProps(['change','info'])
</script>
//父组件
<script setup lang="ts">
import Child from './views/Child.vue';
import { ref } from 'vue';
let msg =ref(true)
const changeValue = ()=>{
     msg.value =! msg.value
     console.log('子组件点击了')
}
</script>

<template>
  <div>
    <h1>我是父组件</h1>
    <Child :info ='msg' :change='changeValue'></child>
    <p>父组件: {{ msg }}</p>
  </div>
</template>

 

//父组件
<script setup lang="ts">
import Child from './views/Child.vue';
import { ref } from 'vue';
let msg =ref('hello')
const changeValue = ()=>{
     msg.value +='Vue'
     console.log('子组件点击了')
}
</script>

<template>
  <div>
    <h1>我是父组件</h1>
    <Child :info ='msg' :change='changeValue'></child>
    <p>父组件: {{ msg }}</p>
  </div>
</template>

 defineEmits(子传父)

//父组件
<script setup lang="ts">
import Child from './views/Child.vue';
import { ref } from 'vue';
let msg =ref('hello')
const changeValue =function(message:any){
     msg.value += message
     console.log('子组件点击了')
}
</script>

<template>
  <div>
    <h1>我是父组件</h1>
    <Child @change="changeValue"></child>
    <p>父组件: {{ msg }}</p>
  </div>
</template>
//子组件
<template>
  <div>
    <h2>我是子组件</h2>
    <button @click="changeWord">点击子组件</button>
  </div>
</template>
<script setup lang="ts">
let emit = defineEmits(['change'])
const changeWord = function(){
    emit('change', 'Vue')
}
</script>

 Vue2

props

自定义事件 $emit

/* 搜索组件  */
<template>
  <div :class="'search-input '+prefixCls">
    <van-search v-model.trim="searchVal" :show-action="showAction" 
  :placeholder="plaseInput" @focus="showAction = true" @blur="handleBlur"
   @input="handleSearcInput" @search="handleSearch">
      <template #action>
        <div class="search-btn-text" @click.stop="handleSearch">搜索</div>
  //@click.stop="handleSearch"确保了点击搜索按钮时,不会冒泡到更外层的元素上
      </template>
    </van-search>
  </div>
</template>

<script>
  import { Search } from 'vant'
  export default {
    name:       'SearchInput',
    components: {
      [Search.name]: Search
    },
    props: {
      prefixCls: {
        type:    String,
        default: 'search-input'
      },
      placeholder: {
        type:    String,
        default: ''
      },
      // 初始值
      text: {
        type:    String,
        default: ''
      }
    },
    data() {
      return {
        showAction: false,
        searchVal:      '',
        timer:      null,
        timeout:      null,
        plaseInput: this.placeholder || '请输入'
      }
    },
    mounted() {
      this.searchVal = this.text
    },
    methods: {
      // 点击搜索
      handleSearch() {
        this.$emit('search', this.searchVal)
      },
      // 防抖
      handleSearcInput() {
        if (this.timeout !== null) {
          clearTimeout(this.timeout)
        }
        this.timeout = setTimeout(() => {
          this.$emit('input', this.searchVal)
        }, 500)
      },
      // 失去焦点一段时间后隐藏搜索按钮
      handleBlur() {
        if (this.timer !== null) {
          clearTimeout(this.timer)
        }
        this.timer = setTimeout(() => {
          // 失去焦点 为了执行回调函数handleSearch,所以延迟处理
          this.showAction = false
        }, 100)
      }
    }
  }
</script>

<style lang='less' scoped>
.search-btn-text {
  width: 68px;
  text-align: center;
  font-size: 14px;
  color: #2d3040;
  padding-right: 20px;
}
</style>

<template>
  <div class="home-search">
    <Search :text="params.text" :placeholder="$t('common.search')" @search="handleSearch" />  
  </div>
</template>
<script>
  import Search from '@components/search-input'
    components: {
      Search,
    },
    data() {
      return {
        params:   {
          text: '',
          page: 0,
          // 超过三个 显示更多 所以初始化3
          size: 3
        },
      }
    },

    created() {
      this.params.text = this.$route.query.val
    },
    mounted() {
      this.handleSearch(this.params.text)
    },
    methods: {
      // 搜索
      handleSearch(val) {
        this.params.page = 0
        this.params.size = 3
        this.params.text = val
        this.search('question')
        this.search('article')
      },
      async search(t) {
        const { data } = await community.searchGroups({ ...this.params, t })
      }
    }
</script>


ref   $refs

全局事件总线

 黑马:

 尚硅谷   

VueComponent.prototype.__proto__ === Vue.prototype

消息订阅与发布(引入第三方库,npm i pubsub-js)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值