1 组件是可复用的 Vue实例,所以他们是与new Vue接受相同的选项,例如data、computed、watch、methods以及生命周期钩子等。仅有的例外是el这样的实例特有的选项。
2 组件实例的作用域是孤立的。这意味着不能(也不应该)在子组件的模板内直接引用父组件的数据。父组件的数据需要通过prop才能下发到子组件中。
3 也就是说prop是子组件访问父组件数据的唯一接口。
一个组件可以直接在模板里面渲染data里面的数据(双大括号)
子组件不能直接在模板里面渲染父组件的数据
如果子组件想要引用父组件的数据,那么就在prop里面声明一个变量,这个变量就可以引用父元素的数据,然后再模板里渲染这个变量,这时候渲染出来的就是父元素里面的数据。
最终效果图
大概的使用方法为:
父组件 App.vue
<template>
<div>
<header class="site-header jumbotron">
<div class="container">
<div class="row">
<div class="col-xs-12">
<h1>请发表对Vue的评论</h1>
</div>
</div>
</div>
</header>
<div class="container">
<!-- :addComment="addComment"作用 : 将addComment()这个方法传递给子组件,并在子组件中使用prop接受该属性 -->
<Add :addComment="addComment"/>
<List :comments="comments"/>
</div>
</div>
</template>
<script>
import Add from './components/Add.vue'
import List from './components/List.vue'
export default {
data () {
return {
comments: [// 数据在哪个组件,更新数据的行为(方法)就应该定义在哪个组件
{
name: 'Tom',
content: 'Vue 还不错'
},
{
name: 'Bob',
content: 'Vue so easy'
},
{
name: 'Jerry',
content: 'Vue so difficult'
}
]
}
},
methods: {
// 添加评论
addComment (comment) {
// 往data里面的comments数组首部添加一条评论的信息
this.comments.unshift(comment)// 把页面收集到的comment数据添加到commens这个数组里面
}
},
components: {
Add,
List
}
}
</script>
子组件 List.vue
<template>
<div class="col-md-8">
<h3 class="reply">评论回复:</h3>
<h2 style='display: none'>暂无评论,点击左侧添加评论!!!</h2>
<ul class="list-group">
<Item v-for="(comment, index) in comments" :key="index" :comment="comment"/>
</ul>
</div>
</template>
<script>
import Item from './Item.vue'
export default {
// 声明接受属性:这个属性就会成为组建对象的属性
props: ['comments'],// 即告诉要引用父组件comments里面的数据
// 映射
components: {
Item
}
}
</script>
子组件 Item.vue
<template>
<li class="list-group-item">
<div class="handle">
<a href="javascript:;">删除</a>
</div>
<p class="user"><span >{{comment.name}}</span><span>说:</span></p>
<p class="centence">{{comment.content}}</p>
</li>
</template>
<script>
export default {
props: {// 指定属性名和属性值的类型
comment: Object
}
}
</script>
子组件 Add.vue
<template>
<div class="col-md-4">
<form class="form-horizontal">
<div class="form-group">
<label>用户名</label>
<input type="text" class="form-control" placeholder="用户名" v-model="name">
</div>
<div class="form-group">
<label>评论内容</label>
<textarea class="form-control" rows="6" placeholder="评论内容" v-model="content"></textarea>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="button" class="btn btn-default pull-right" @click="add">提交</button>
</div>
</div>
</form>
</div>
</template>
<script>
export default {
props: {
addComment: {// 指定属性名/属性值的类型/必要性
type: Function,
required: true
}
},
data () {
return {
name: '',
content: ''
}
},
methods: {
add () {
// 1. 检查输入的合法性
const name = this.name.trim()
const content = this.content.trim()
if (!name || !content) {
alert('姓名或者内容不能为空')
return
}
// 2. 根据输入的数据,封装成一个comment对象
const comment = {
name,
content
}
// 3. 添加到comments中
this.addComment(comment)
// 4.清除输入
this.name = ''
this.content = ''
}
}
}
</script>