1.父组件向子组件传值
子组件要拿到父组件的 msg 数据,
-
通过下述语句把父组件的数据绑定到子组件上
<com1 v-bind:parentmsg="msg"></com1>
-
把父组件传递过来的parentmsg属性,在子组件的props数据中,定义一下,才能使用这个数据
props: ['parentmsg'],
-
即可在子组件中用插值表达式调用
例:
<div id="body">
<!-- 父组件,可以在引用子组件的时候,通过属性绑定(v-bind)的形式,
把需要传递给子组件的数据,以属性绑定的形式,传递到子组件内部,供子组件使用 -->
<com1 v-bind:parentmsg="msg"></com1>
</div>
<script>
var vm = new Vue({
el:"#body",
data:{
msg:'父组件中的数据'
},
methods:{
},
components: {
// 结论:经过演示发现,子组件中,默认无法访问到负组件中的 data 上的数据和 methods 中的方法
com1:{
data () { // 注意:子组件中的 data 数据,并不是通过父组件传递过来的,二十子组件自身私有的,
// 比如:子组件通过 Ajax ,请求回来的数据,都可以放到 data 身上
// data 上的数据,都是可读可写的
return {
title:'zizujianData',
content:'zizujianContent'
}
},
template:'<h1>这是子组件---{{parentmsg}}</h1>',
// 注意:组件中的所有 props 中的数据,都是通过父组件传递给子组件的
// props 中的数据,都是只读的,无法重新赋值
props: ['parentmsg'], // 把父组件传递过来的parentmsg属性,现在props数据中,定义一下,才能使用这个数据
directives: {},
filters: {},
}
}
})
</script>
2.子组件向父组件传值
原理是:
- 父组件向子组件先传一个方法:使用事件绑定机制 v-on 或 @
- 子组件中使用 this.$emit(‘func123’,this.sonmsg) 来获取父组件传来的方法
// emit 英文原意:是触发、调用、发射的意思 - 子组件直接使用 func123 来调用父组件中的方法
- 如果需要给父组件传值,直接卸载 func123 的参数里
- 把参数传到父组件的 data 中(父组件的方法中填写赋值操作)
例:
<template id="tmpl">
<div>
<h1>这是子组件</h1>
<input type="button" @click="myclick" value="子组件中的按钮-点击触发父组件传递过来的func132方法">
</div>
</template>
<div id="body">
<!-- 父组件向子组件传递方法,使用的是事件绑定机制 v-on,当我们自定义了一个事件属性之后,
那么,子组件就能够通过某些方法,来调用传递进去的这儿方法了 -->
<!-- <com2 @func123="show"></com2> -->
<com2 v-on:func123="show"></com2>
</div>
<script>
// 定义了一个自变量类型的 组件模板对象
var com2 = {
template:'#tmpl', // 通过制定了一个 Id ,表示要去加载这个指定Id的 template元素中的内容,当作组件的 HTML结构
data () {
return {
sonmsg:{name:'大头儿子',age:6}
}
},
methods:{
myclick(){
// 当点击子组件的按钮的时候,如何拿到父组件传递过来的 func123 方法,并调用这个方法?
// emit 英文原意:是触发、调用、发射的意思
this.$emit('func123',this.sonmsg)
}
}
}
var vm = new Vue({
el:"#body",
data:{
datamsgFromSon:null
},
methods:{
show(data){
console.log('调用了父组件身上的 show 方法')
console.log(data)
this.datamsgFromSon = data
}
},
components: {
com2
}
})
</script>
3. 父子组件传值-发表评论功能的实现案例
<div id="body">
<cmtbox @func="loadComments"></cmtbox>
<ul class="list-group">
<li class="list-group-item" v-for="item in list" key="item.id">
<span class="badge">评论人: {{ item.user }}</span>
{{ item.content }}
</li>
</ul>
</div>
<template id="commentBox">
<div>
<div class="form-group">
<label>评论人:</label>
<input type="text" class="form-control" v-model="user">
</div>
<div class="form-group">
<label>评论内容:</label>
<textarea class="form-control" v-model="content"></textarea>
</div>
<div class="form-group">
<input type="button" value="发表评论" class="btn btn-primary" @click="postComment">
</div>
</div>
</template>
<script>
var commentBox = {
template: '#commentBox',
data() {
return {
user: '',
content: '',
}
},
methods: {
postComment() { //发表评论功能
// 分析:发表评论的业务逻辑
// 1.数据存放到了 localStorage
// 2.先组织出一个最新的评论数据对象
// 3.想办法,把第二步中 得到的评论对象,保存到 localStorage中
// 3.1 localStorage中只存放字符串数据,要先调用 JSON.stringift
// 3.2 在保存最新的评论数据之前,要先从 localStorage 获取到之前的评论数据(String),转换为一个数组对象,然后把最新的评论, push到这个数组
// 3.3 如果获取到的 localStorage中的评论字符串,为空不存在,则可以返回一个 '[]' ,让 JSPN.parse去转化
// 3.4 把最新的评论列表数组,再次调用 JSON.stringify 转为数组字符串,然后用localStorage.setItem()
var comment = { id: Date.now(), user: this.user, content: this.content }
// 从 localStorage 中获取所有的评论
var list = JSON.parse(localStorage.getItem('cmts') || '[]')
list.unshift(comment)
// 重新保存最新的评论数据
localStorage.setItem('cmts', JSON.stringify(list))
this.$emit('func')
this.user = this.content = ''
}
}
}
var vm = new Vue({
el: "#body",
data: {
list: [
{ id: Date.now(), user: '李白', content: '天生我材必有用' }
]
},
methods: {
loadComments() {
var list = JSON.parse(localStorage.getItem('cmts') || '[]')
this.list = list
}
},
components: {
'cmtbox': commentBox
},
created () {
this.loadComments()
},
})
</script>