概念:
1.script中声明的TodoItem是子组件
2.Vue实例化是父组件
3.div中的todo-item标签是父组件模板
子组件给父组件传值:
父组件给子组件传值:
通过todo-item中的v-bind指令,从父组件vue实例中接受参数。子组件中要有props进行接受数据。
子组件传值给父组件:
子组件中要有$emit 事件触发,向上一层触发事件,子组件触发的事件,父组件(模板)正好在监听,
监听过后,就能获得子组件带来的内容,实现子组件向父组件传值的功能。代码(实现父子组件交互):
<div id="root">
<input type="text" v-model="inputValue">
<!-- 如果设置v-model 则data对象里也要有个同样名字的键,即inputValue -->
<!-- v-model 双向绑定 表单或者data 任一个变化 另一个都会变化 -->
<button v-on:click="handleBtnClick">submit</button>
<!-- 这里函数后不用加() -->
<ul>
<!-- 这部分相当于父组件的模板 -->
<!-- <li v-for="item in list">{{item}}</li> -->
<!-- 使用了v-for 所以只写一个li就可以 自动遍历 -->
<todo-item v-bind:content="item" :index="index" v-for="(item,index) in list" @delete="handleItemDelete">
<!-- 创建item的同时 监听delete事件 -->
<!-- 通过for获得item 再通过v-bind 将item传给子组件todo-item -->
</todo-item>
<!-- 小横线要加上 -->
<!-- 这个标签名字todo-item对应的是component方法中的"TodoItem"名字,而不是todo item,即也可以to-item,则下面的名字改为"ToItem" -->
</ul>
</div>
<script>
// 《局部组件》
// 子组件
var TodoItem = {
props: ['content', 'index'],
template: "<li @click='handleItemClick'>{{content}}</li>",
methods: {
// 删除在父组件中操作
handleItemClick: function() {
// alert(11);
this.$emit("delete", this.index)
}
}
}
// 父组件 通过父组件向子组件传值
var app = new Vue({
// vue实例化
el: '#root',
//把TodoItem注册到vue中
components: {
TodoItem: TodoItem
},
data: {
list: [], //键值对中的值可以是列表可以是对象
inputValue: ''
// 可以看出 以后项目的data 里 基本都设置为空
},
methods: {
handleBtnClick: function() {
this.list.push(this.inputValue);
this.inputValue = ''
// alert(this.inputValue) //this指向app
},
handleItemDelete: function(index) {
// alert(index);
this.list.splice(index, 1)
}
}
})
</script>
总结:
相当于三部分进行交互:script标签中的父组件、子组件、以及div中的父组件模板。
1、父组件可以使用 props 把数据传给子组件。
2、子组件可以使用 $emit 触发父组件的自定义事件。//本文中的delete就是自定义事件