-
本次博客介绍的是vue的组件化思想和父子组件通信,并且将沿用上次todolist例子进行阐述。
-
首先,引入一个全局组件,代替之前的li标签
- 效果
- 代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<html>
<head>
<script src="http://vuejs.org/js/vue.js"></script>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<div id="app">
<input type="text" v-model="inputValue">
<button v-on:click="handleBtnClick">submit</button>
<ul>
<!-- <li v-for="item in list">{{item}}</li> -->
<todo-item v-for="item in list"></todo-item>
</ul>
</div>
<script>
Vue.component("TodoItem", {
template: "<li>todo item</li>"
})
//创建一个Vue的全局组件,代替之前的<li>
var app = new Vue({
el: '#app',
data: {
list: [],
inputValue: ''
},
methods: {
handleBtnClick: function () {
this.list.push(this.inputValue)
this.inputValue = ''
}
}
})
</script>
</body>
</html>
-
接着我们通过父子组件通信,将输入的内容传入到子组件,然后通过子组件呈现到待办列表中。
-
代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<html>
<head>
<script src="http://vuejs.org/js/vue.js"></script>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<div id="app">
<input type="text" v-model="inputValue">
<button v-on:click="handleBtnClick">submit</button>
<ul>
<todo-item v-bind:content="item" v-for="item in list"></todo-item>
</ul>
</div>
<script>
Vue.component("TodoItem", {
props: ['content'],
})
var app = new Vue({
el: '#app',
data: {
list: [],
inputValue: ''
},
methods: {
handleBtnClick: function () {
this.list.push(this.inputValue)
this.inputValue = ''
}
}
})
</script>
</body>
</html> -
v-for="item in list"
是将用户输入的每一项内容都传入到item中,v-bind:content="item"
是将item
的值绑定到content
中,然后传入到todo-item
中,那么子组件就需要一个props
来接收传入的content
,最后通过template
插值表达式来显示内容。这就是父组件向子组件传值。
-
上面是全局组件,现在用局部组件实现
-
代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<html>
<head>
<script src="http://vuejs.org/js/vue.js"></script>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<div id="app">
<input type="text" v-model="inputValue">
<button v-on:click="handleBtnClick">submit</button>
<ul>
<todo-item v-bind:content="item" v-for="item in list"></todo-item>
</ul>
</div>
<script>
var TodoItem = {
props: ['content'],
}
//创建局部组件,并注册
var app = new Vue({
el: '#app',
components: {
TodoItem: TodoItem
},
data: {
list: [],
inputValue: ''
},
methods: {
handleBtnClick: function () {
this.list.push(this.inputValue)
this.inputValue = ''
}
}
})
</script>
</body>
</html> -
PS: 这里有个key值问题,之后的博客会提到这个。
-
现在实现点击列表内容,自动删除的功能。这里就要用到父组件向子组件传值的方法。
- 效果
- 代码:
<!DOCTYPE html> <html> <head> <script src="http://vuejs.org/js/vue.js"></script> <meta charset="utf-8"> <title>JS Bin</title> </head> <body> <div id="app"> <input type="text" v-model="inputValue"> <button v-on:click="handleBtnClick">submit</button> <ul> <todo-item :content="item" :index="index" v-for="(item, index) in list" @delete="handleItemDelete"> </todo-item> <!--父组件delete会监听handleItemDelete事件。父组件将删除的列表的index通过v-bind传入到子组件--> </ul> </div> <script> var TodoItem = { props: ['content', 'index'], //子组件接收父组件的index template: "<li @click='handleItemClick'>{{content}}</li>", methods: { handleItemClick: function () { this.$emit("delete", this.index) } // 当点击子组件时,向上一层触发事件delete去监听父组件事件,并且把参数一并传入到父组件 } } var app = new Vue({ el: '#app', components: { TodoItem: TodoItem }, data: { list: [], inputValue: '' }, methods: { handleBtnClick: function () { this.list.push(this.inputValue) this.inputValue = '' }, handleItemDelete: function (index) { this.list.splice(index, 1) } //父组件接收子组件传入的index } }) </script> </body> </html>
- 子组件向父组件通信时,使用$emit方法派发一个事件和参数,通过
delete
监听handleItemDelete
,然后父组件通过v-bind将数据传入到子组件中,子组件通过props
接收数据,最后渲染到页面上。