父子组件互传

main
roger_home_pc 1 year ago
parent a96c6c2109
commit 9f3180cfe7
  1. 27
      demo/component-v-model/App.vue
  2. 24
      demo/component-v-model/components/ChildComponentA.vue
  3. 59
      src/App.vue
  4. 70
      src/components/ChildComponentA.vue

@ -0,0 +1,27 @@
<template>
<!-- 2. 通过v-model:参数名的方式传递数据 -->
<ChildComponentA v-model:name="p_name" v-model:title="p_title"></ChildComponentA>
<br>
<label>这是父组件内容</label>
<p>名称{{ p_name }}</p>
<p>标题{{ p_title }}</p>
</template>
<script>
import ChildComponentA from "@/components/ChildComponentA.vue";
export default {
components: {ChildComponentA},
// 1.
data() {
return {
p_name: '父组件name数据',
p_title: '父组件title数据',
}
}
}
</script>
<style scoped>
</style>

@ -0,0 +1,24 @@
<template>
<label>这是子组件内容</label>
<!-- 3. 使用$emit绑定事件并且回传参数 -->
名称<input type="text" :value="name" @input="$emit('update:name', $event.target.value)"/>
标题<input type="text" :value="title" @input="$emit('update:title', $event.target.value)"/>
<p>名称是{{name}}</p>
<p>标题是{{title}}</p>
</template>
<script>
export default {
// 1.
props: {
name: String,
title: String,
},
// 2.
emits: ['update:name', 'update:title'],
}
</script>
<style scoped>
</style>

@ -1,9 +1,15 @@
<template>
<!-- 3. 添加自定义事件selected -->
<ChildComponentA title="list—data" :list_data="todos" @selected="onSelected"></ChildComponentA>
<div>
<h3>您选中了{{ selected_status }}</h3>
</div>
<ChildComponentA>
<template v-slot:header>
<P>提示</P>
</template>
<template v-slot:default="slotProps">
<p>我的错误是<span>{{ slotProps.types['404'] }}</span></p>
</template>
<template v-slot:footer="{types, sources}">
<div>错误来自{{sources['page']}} - {{types['404']}}</div>
</template>
</ChildComponentA>
</template>
<script>
@ -11,28 +17,33 @@ import ChildComponentA from "@/components/ChildComponentA.vue";
export default {
components: {ChildComponentA},
data() {
return {
todos: [
'todo-1',
'todo-2',
'todo-3',
'todo-4',
'todo-5'
],
// 1.
selected_status: ''
}
},
methods: {
// 2. 使
onSelected(item) {
this.selected_status = item;
}
}
}
</script>
<style scoped>
.wrap {
border: 1px solid #f66;
color: #f66;
padding: 10px;
position: relative;
max-width: 300px;
}
.header {
font-size: 20px;
color: #333;
font-weight: bold;
}
.close {
position: absolute;
right: 10px;
top: 10px;
}
.footer {
color: #666;
font-size: 12px;
text-align: right;
}
</style>

@ -1,38 +1,60 @@
<template>
<h3>{{ title }}</h3>
<ul>
<!-- 触发事件 -->
<li v-for="(item, index) in list_data" :key="index" @click="handleClick(item)">{{ index }} - {{ item }}</li>
</ul>
<div class="wrap">
<div class="header">
<slot name="header">错误</slot>
<div class="close">关闭</div>
</div>
<div>
<slot :types="types"></slot>
</div>
<div class="footer">
<slot name="footer" :types="types" :sources="sources"></slot>
</div>
</div>
</template>
<script>
export default {
props: {
title: String,
list_data: {
type: Array,
default: () => [],
required: true,
validator: value => {
return value.length >= 0
data() {
return {
types: {
404: 'Page Not Found',
500: 'System Error',
},
sources: {
system: '系统',
page: '页面',
console: '控制台',
}
}
},
// 1.
emits: ['selected'],
methods: {
// 2. $emit, $emit()
handleClick(item) {
this.$emit("selected", item);
}
},
mounted() {
console.log(this.list_data)
}
}
</script>
<style scoped>
.wrap {
border: 1px solid #f66;
color: #f66;
padding: 10px;
position: relative;
max-width: 300px;
}
.header {
font-size: 20px;
color: #333;
font-weight: bold;
}
.close {
position: absolute;
right: 10px;
top: 10px;
}
.footer {
color: #666;
font-size: 12px;
text-align: right;
}
</style>

Loading…
Cancel
Save