父子之间组件传值及评论案例

父子之间组件传值

父组件向子组件传值

父组件向子组件传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>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值