组件
关于组件的理解,可以认为是可复用的功能块,一个功能或许需要不等的组件,因此组件的通信也是要熟悉的,这个是跟着教程做的一个小的实例,主要是了解组建的嵌套和传值。
页面
页面要实现能够增加或删除一个数据
页面很简单,主要就是添加用户名和评论,在点击提交之后把值渲染出来
分析
页面的布局是很简单的头部、内容格式,因此主要是关心数据存放在哪,要怎么显示。
可以将左侧添加数据和右侧的数据展示分为单独的组件,这样能够方便维护。其次就是右侧会有很多评论,而每一个评论的布局都相似,所以可以将每一个评论分为一个组件被右侧单独引用。
根节点
根文件主要是把主要的结构框架搭建好
- 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">
<Add :addComment="addComment" />
<List :comments="comments" :deleteComment= 'deleteComment'/>
</div>
</div>
</template>
<script>
import Add from './components/Add.vue'
import List from './components/List.vue'
export default {
data () {
return {
comments: [
{name: 'Bob', content: 'Vue还可以'},
{name: 'jerry', content: 'Vue太简单'},
{name: 'lily', content: 'Vue垃圾'}
]
}
},
components: {
Add,
List
},
methods: {
addComment (comment) {
this.comments.unshift(comment)
},
deleteComment (index) {
this.comments.splice(index, 1)
}
}
}
</script>
组件的引用是先在js中导入该文件,然后再vue实例中声明组件,就能够直接使用标签了。
- 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 () {
const name = this.name.trim()
const content = this.content.trim()
if (!name || !content) {
alert('姓名或者内容不可为空')
return
}
const comment = {
name,
content
}
this.addComment(comment)
this.name = ''
this.content = ''
}
}
}
</script>
左侧新增的组件主要是对输入框进行了绑定,对按钮添加了事件。提交的时候获取实例中的数据,根据实例中获取到父组件的函数参数来将此条数据添加到总数据中。然后清空输入框。
- List.vue
<template>
<div class="col-md-8">
<h3 class="reply">评论回复:</h3>
<h2 v-show="comments.length === 0" >暂无评论,点击左侧添加评论!!!</h2>
<ul class="list-group">
<Item v-for="(comment, index) in comments" :key="index" :comment="comment"
:deleteComment="deleteComment" :index="index"/>
</ul>
</div>
</template>
<script>
import Item from './Item.vue'
export default {
// 声明接收属性
props: ['comments', 'deleteComment'],
components: {Item}
}
</script>
<style >
.reply {margin-top: 0px}
</style>
list中仅是创建好右侧展示的框架,实际的数据展示仍然在子组件中。根据数据的数量便利子组件,绑定每条数据的下标。
- 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: Object,
deleteComment: Function,
index: Number
},
methods: {
deleteItem () {
const {comment, index, deleteComment} = this
if (window.confirm(`确定删除${comment}?`)) {
deleteComment(index)
}
}
}
}
</script>
<style >
li {
transition: .5s;
overflow: hidden;
}
.handle {
width: 40px;
border: 1px solid #ccc;
background: #fff;
position: absolute;
right: 10px;
top: 1px;
text-align: center;
}
.handle a {
display: block;
text-decoration: none;
}
.list-group-item .centence {
padding: 0px 50px;
}
.user {
font-size: 22px;
}
</style>
列表组件中获取list传来的数据,根据数据进行渲染,其中添加了删除的操作,但是操作是在根组件中,因此根组件将方法以 :functionName=“functionName” 的形式逐级传递。item在接受到触发事件的下标值后通过传来的方法直接删除。
总结
这个小实例只是简单的了解vue组件的代码格式化,并没有什么太大的价值。其中使用的eslint是真的逼疯我了,我天哪,这是什么鬼工具!