父子之间组件传值
父组件向子组件传值
父组件向子组件传data中的值
首先,我们知道子组件默认是无法访问父组件中的data上的数据和methods中的方法,其次,如果我们想要子组件取到父组件中data中的msg值,该怎么办呢?
先区分父组件中的data和子组件中data
子组件中的data数据,并不是通过父组件传递过来的,而是子组件自身私有的,比如:子组件通过ajax请求回来的数据,都可以放在data身上,注意:子组件的data必须是个方法,有返回值
var vm = new Vue({
el:'#app',
data:{
msg: '123 啊-父组件中的数据'
},
methods:{},
components: {
com1: {
data(){
return {
title: '123',
content: 'qqq'
}
},
template: '<h1>这是子组件 --- {{ parentmsg }}</h1>',
}
}
});
父组件向子组件传值:
通过属性绑定(v-bind)的方式,把需要传递给子组件的数据,以属性绑定的形式,传递到子组件内部,供子组件使用;然后在子组件中的props数组中定义从父组件传递过来的属性。
注意:子组件中的data上的数据,是可读可写的,props中的数据都是只读的,是无法重新赋值的
<body>
<div id="app">
<com1 v-bind:parentmsg="msg"></com1>
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
msg: '123 啊-父组件中的数据'
},
methods:{},
components: {
com1: {
data(){
return {
title: '123',
content: 'qqq'
}
},
template: '<h1>这是子组件 --- {{ parentmsg }}</h1>',
props: ['parentmsg'],
}
}
});
</script>
</body>
父组件向子组件传递方法
父组件向子组件传递方法,使用的是事件绑定机制:v-on (<com2 v-on:func=“show”>)
当我们自定义了一个事件属性之后,子组件就能通过某些方式(this.$emit(‘func’,this.sonmsg),看父组件的方法是否有参数),来调用传递进去的这个方法
<body>
<div id="app">
<com2 v-on:func="show"></com2>
</div>
<template id="tmp1">
<div>
<h1>这是子组件</h1>
<input type="button" value="这是子组件中的按钮- 点击它,触发父组件传递过来的func方法" @click="myclick">
</div>
</template>
<script>
var com2 = {
template : '#tmp1',
data(){
return {
sonmsg: {name:'小头儿子', age:6}
}
},
methods: {
myclick(){
//当点击子组件按钮时,如何拿到父组件传递过来的func方法,并调用这个方法
// emit英文意思:触发,调用意思
this.$emit('func',this.sonmsg)
}
}
}
var vm = new Vue({
el:'#app',
data:{
datamsgFormSon: null
},
methods:{
show(data){
// console.log(data)
this.datamsgFormSon = data
}
},
components: {
com2
}
});
</script>
</body>
实例:评论列表
分析:发表评论的业务逻辑
1.评论数据存到哪里去? 存放到本地localStorage中localStorage.setItem(‘cmts’,’’)
2.先组织一个最新的评论数据对象
3.想办法,把第二步得到的评论对象,保存到localStorage中
3.1 localStorage只支持存放字符串数据,要先序列化成一个对象,调用JSON.stringify
3.2 在保存最新的评论数据之前,要先从localStorage获取到之前的评论数据(string),转换为一个数组对象, 然后把最新的评论push到这个数组
3.3 如果获取到的localStorage中的评论字符串,为空不存在,则可以返回一个‘[]’让JSON.parse去转换
3.4 把最新的评论列表数组,再次调用JSON.stringify转化为数组字符串,然后调用localStorage.setItem()
知识点:在点击发表评论时,希望能够自动刷新列表从localStorage中获得最新列表。而该方法为localComments(),是父组件的方法,子组件是如何调用父组件的方法的。
知识点:JSON.parse() 从一个字符串解析出JSON对象;JSON.stringify()从一个对象中解析出字符串。
知识点:localStorage为本地存储,只存储字符串类型的对象,如果想要转成JSON对象类型就需要用到上一个知识点。
<body>
<div id="app">
<cmt-box @func="localComments"></cmt-box>
<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="tmp1">
<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 = {
data(){
return {
user: '',
content: ''
}
},
template: '#tmp1',
methods: {
postComment(){
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.user = this.content = ''
this.$emit('func')
}
}
}
var vm = new Vue({
el:'#app',
data:{
list:[
{id: Date.now(), user:'李白', content:'天生我材必有用'},
{id: Date.now(), user:'江小白', content:'劝君更进一杯酒'},
{id: Date.now(), user:'小马', content:'我姓马,风吹草低见牛羊的马'}
]
},
created(){
this.localComments()
},
methods:{
localComments(){ // 从本地localStorage中加载评论列表
var list = JSON.parse(localStorage.getItem('cmts') || '[]')
this.list = list
}
},
components:{
'cmt-box': commentBox
}
});
</script>
</body>
子组件向父组件传值
使用this.$refs来获取元素和组件。
首先,了解ref的功能,通过ref就能不操作DOM元素获取到h3的值,可以从控制台看到有$refs对象,给h3加上ref=myh3,就能看到$refs中有对象,键为myh3,值为DOM元素,在方法中,通过this.$refs.myh3.innerText就可以获取到该元素
<body>
<div id="app">
<input type="button" value="获取元素" @click="getElement">
<h3 ref="myh3">哈哈哈,今天天气太好了!!!</h3>
</div>
<script>
var vm = new Vue({
el:'#app',
data:{},
methods:{
getElement(){
console.log(this.$refs.myh3.innerText)
}
},
});
</script>
</body>
在父组件中通过** this.$refs.mylogin.show()**就可调用子组件的show方法,此时控制台的$refs中的mylogin对应的值就是子组件
<body>
<div id="app">
<input type="button" value="获取元素" @click="getElement">
<h3 ref="myh3">哈哈哈,今天天气太好了!!!</h3>
<hr>
<login ref="mylogin"></login>
</div>
<script>
var login={
template: '<h1>登录组件</h1>',
data(){
return {
msg: 'son msg'
}
},
methods: {
show(){
console.log('调用了子组件的方法')
}
}
}
var vm = new Vue({
el:'#app',
data:{},
methods:{
getElement(){
this.$refs.mylogin.show()
}
},
components:{
login
}
});
</script>
</body>