组件化编码的基本流程:
1.拆分组件
2.实现静态组件:显示的界面数据是固定的,也没有交互
3.动态组件:有两个方面是动态的,初始化显示和交互
组件间通信
1.通过标签传递
组件接收父组件传递过来的数据,首先要有声明,接收传递过来的属性;这个属性就会成为组件对象的属性
示例编码:
拆分为App、Add、List和Item组件
js的入口文件main.js
/*
入口JS
*/
import Vue from 'vue'
import App from './App.vue'
// 创建vm
/* eslint-disable no-new */
new Vue({
el: '#app',
components: {App}, // 映射组件标签
template: '<App/>' // 指定需要渲染到页面的模板
})
根组件:App.vue
数据放在哪个组件里面,看这数据是某个组件用到,还是某些组件用到;
如果是某个组件用到,那就放到这个组件里面;
如果是某些组件用到,那就放到他们的父组件里面;
由于Add组件需要进行添加数据,List组件需要显示,所以数据放在App组件中
<template>
<div class="container">
<Add :addComment="addComment"/> //将addComment方法传递给Add组件,在Add组件进行调用
//通过标签传递数据,如果不加冒号传递的将是文本,加了冒号传递是这个变量的值
//deleteComment是给Item组件调用的,由于在App组件看不到Item组件,所以逐层传递
<List :comments="comments" :deleteComment="deleteComment"/>
</div>
</template>
<script>
//引入Add和List子组件
import Search from './components/Add.vue'
import Main from './components/List.vue'
export default {
data(){
return{
comments: [{
name: 'BOB',
content: 'Vue还不错'
},
{
name: 'JACK',
content: 'Vue挺好'
}]
}
},
//往数组中添加元素,this.comments.unshift(comment)
//this.comments是数组,comment是添加的元素,添加在上方用unshift()方法
methods: {
//添加评论
addComment (comment){
this.comments.unshft(comment)
},
//删除指定下标的评论
deleteComment (index){
this.comments.splice(index,1)
}
}
components: { //映射组件标签
Add,
List
}
}
</script>
<style>
</style>
数据展示,需要由App交给它的子组件List,所以要将数据传递过去,组件间通信
1.最原始的方式:通过标签属性传递,最好是同名,如上
App将数据传递给List组件,在List组件里要进行接收;
声明接收属性
组件List.vue
<template>
<div class="col-md-8">
<h3 class="replay">评论回复: </h3>
<h2 style='...'>暂无评论,点击左侧添加评论!!!</h2>
<ul class="list-group>
//:comment="comment"将comment传递给Item组件
<Item v-for="(comment,index) in comments" :key="index" :comment="comment" :deleteComment="deleteComment" :index="index"/>
</ul>
</div>
</template>
<script>
//引入子组件Item
import Item from './Item.vue'
export default {
//声明接收属性:这个属性就会成为组件对象的属性,在模板里面就可以直接读取此属性
props: ['comments','deleteComment'],//deleteComment在List组件中并没有使用,是App组件传递过来,List将它传递给Item组件,供Item调用
//映射组件
components: {
Item
}
}
</script>
<style>
</style>
List组件将comment传递给Item组件,要在Item组件里进行接收
Item.vue
<template>
<li class="list-group-item">
<div class="handle">
<a href="javascript:;" @click="deleteItem">删除</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'],只指定属性名
props: { //指定属性名和属性的类型
comment: Object,
deleteComment: function,
index: Number
},
methods: {
deleteItem(){
//从this,即vm中取出数据
const {comment,index,deleteComment} = this
if(window.confirm(`确定删除${comment.name}的评论吗?`)){
deleteComment(index)
}
}
}
}
</script>
<style>
</style>
组件Add.vue
<template>
<div>
</div>
</template>
<script>
export default {
//声明接收属性:这个属性就会成为组件对象的属性,在模板里面就可以直接读取此属性
//props: ['comment'],只指定属性名
//指定属性名和属性的类型
//props: {
// comment: Object
//},
//指定属性名/属性值类型/必要性
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>
<style>
</style>