vue的组件传值

组件化思想是vue框架里面极具重要的一种思想,使用组件可以在我们的项目之中更好的搭建整体布局,从而轻松的使用少量的代码完成大量的工作。

父组件向子组件传值

父组件向子组件进行传值,使用的是绑定一个属性的方式。我们先看一个例子:

            <todo-item v-bind:content = '1'>
            </todo-item>

我们定义了一个模板如下:

var TodoItem = {
        props: ['content' ],       //子组件接收父组件的传值
        template: "<li>{{content}}</li>"
    }

这是最简单的父组件向子组件传值,父组件绑定了一个属性,其名为content(这里content是我们自己定义的,你也可以之间使用已经定义好的属性,比如title),而它所携带的参数为数字1,这个1是number类型

这里我们需要注意一个重点,就是我们在父组件里面绑定属性用的是v-bind,你也可以不使用v-bind,直接写content='1',他俩的区别在于,直接写属性名后跟属性值,这个属性值只能是字符串类型,而使用v-bind绑定参数,而后跟的可以不仅仅是字符串,可以是任意类型

到现在为止父组件只需要做这么一件事即可,接下来子组件需要去获取到父组件传出来的数据

我们在子组件里面获取数据需要用到props来接收,其后面可以接收多个数据,当我们接收到数据之后,就可以直接使用这个传出来的content了

  • 另外需要注意的地方在于,vue规定子组件对于数据只有使用权不可以修改数据,因为可能有多个子组件接收父组件传出来的数据,如果这个数据是引用数据,那么有一个子组件修改了数据,势必影响其他的子组件,如果非要修改,我们可以使用一个变量拷贝接收的数据

子组件向父组件传值

子组件向外传出数据需要用到$emit
这里我们直接先放上例子,我就直接附上了完整的html代码

<body>
    <div id="root">
        <ul>
            <!--v-bind是父组件向子组件传值,简写方法直接写冒号即可
                这里@click是父组件监听子组件传出来的click事件,如果发现了子组件抛出的click事件,就会触发后面的itemClick函数-->
            <todo-item :content = '1' @click="itemClick"></todo-item>
        </ul>
    </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    Vue.component('TodoItem' , {
        props: ['content'],       //子组件接收父组件的传值
        template: "<li @click='handleItemClick'>{{content}}</li>",
        methods: {
            handleItemClick: function(){
                //点击子组件的时候,会向外抛出一个click事件,$emit用于向外抛出事件,后面可以跟一个或多个参数,用于传值
                this.$emit("click" , this.content)  
            }
        }
    })
    var vm = new Vue({
        el: '#root',
        methods: {
            //形参value是用来接收事件触发的时候传过来的参数,就是$emit后面携带的参数
            itemClick: function(value){
                alert(value)
            }
        }
    })
</script>

这段代码的功能是点击元素的时候,会弹框显示里面的内容
大体思路就是,

  • 一开始定义模板的时候,就已经绑定了会触发handleItemClick函数的点击事件
  • 当我们点击li标签的时候,触发该函数,通过$emit方法向外抛出一个名为click的事件
  • 我们在父组件里面进行监听,如果发现了click事件,就会触发后面的itemClick事件,并执行里面的回调函数,打印里面的值

非父子组件传值

  • 这里建议父子组件已经掌握的同学,再对非父子组件进行学习
    我们先附上例子,这样比较方便上下文查看,所以我依然附上完整代码,建议大家比着思路一点一点敲出来,尽量不要复制粘贴
<body>
    <div id="root">
        <child content='Dell'></child>
        <child content='Leo'></child>
    </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    //在vue的原型上面定义一个bus并让其等于vue的实例,vue是一个函数,所以它有原型链,这样任意一个vue实例都可以使用bus属性
    Vue.prototype.bus = new Vue()

    Vue.component('child' , {
        props:['content'],
        //这里有一个重点,组件里面使用的data必须是一个函数,且必须返回一个对象,所用到的数据都在该对象里面
        //下面这句话的意思就是我们把接收到的数据进行了拷贝,让selfContent等于当前content的值
        data: function(){
            return {
                selfContent: this.content
            }
        },
        template: '<div @click="handleClick">{{selfContent}}</div>',
        methods: {
            handleClick: function(){
                //通过实例自身的bus方法向外触发change事件,并携带了selfContent参数
                this.bus.$emit('change' , this.selfContent)
            }
        },
        //生命周期钩子,页面挂载后立即触发
        mounted: function(){
            //绑定当前组件对象,回调函数执行的时候this指向会改变
            let that = this
            //对事件进行监听,$on可以对事件进行监听,监听bus的改变,$emit用于向外触发事件,$off用于取消自定义事件监听器
            //bus是组件定义的实例,所以每个组件都会有bus属性,而bus是实例,所以它也会有$on方法
            this.bus.$on('change' , function(msg){
                //让组件中的selfContent全部等于传进来的参数
                that.selfContent = msg
            })
        }
    })

    var vm = new Vue({
        el: '#root'
    })
</script>

这段代码的作用是,页面中的两个元素是兄弟元素,当我们点击其中一个元素的时候,其他标签里面的值会和当前点击的标签里面的值相等

我来讲一下实现原理:父组件两个child组件是属于兄弟元素,我们想要他们之间进行数值互传。

  • 所以我们先定义一个bus方法让其在vue原型上面,这样只要是vue实例都可以使用该方法。
  • 然后我们在模板绑定点击事件,当元素点击时触发handleClick函数,当handleClick点击事件触发的时候,执行回调函数,向外抛出change事件,并传出去从父组件接收到的参数,selfContent
  • 紧接着我们使用生命周期钩子,mounted,它会在页面挂载之后触发
  • 所有的组件都会调用$on监听bus的改变,如果发现change事件,立即调用回调函数,并对$emit传出来的参数进行接收
  • 最后执行函数即可

纯原创,如果有错误,欢迎指正,我一定及时修改 =^=

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容