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