vue 组件间多种传值方法(全)

父传子

props传值
 1 <body>
 2     <div id="app">
 3         <p>msg: {{msg}}</p>
 4         <father></father>
 5     </div>
 6    
 7     <template id="father">
 8         <div>
 9             <p>这是father组件!----> {{fMsg}}</p>
10             <son :s-msg="fMsg"/>
11         </div>
12     </template>
13 </body>
14 
15 
16 <script src="./base/vue.js"></script>
17 <script>
18     // 父组件给子组件传递数据的时候,
19     //子组件需要利用props的属性来确定自己的预期数据
20     //中间有-   需要写出驼峰的形式来接收
21     //如果儿子没有通过props属性接受传递过来的数据,则数据会以自定义属性的方式,放在儿子最外层的根元素上面
22     
23 
24     //为什么组件的data必须是一个函数内部返回对象的形式?
25     //目的就是让每个实例可以维护一份被返回对象独立的拷贝。
26     //内部必须返回一个新的对象,这样就可以保证每个组件里面用到的数据对象都是唯一的。
27     // let json = {
28     //     fMsg:"father"
29     // }
30     Vue.component("father",{
31         template:"#father",
32         data(){
33             return {
34                 fMsg:"father"
35             }
36         },
37         components:{ //定义father组件的子组件son
38             son:{
39                 template:"<div>我是son组件 {{sMsg}} </div>",
40                 props:["sMsg"] //接受父组件传递来的属性
41             }
42         }
43     })
44    
45 
46     let vm = new Vue({
47         el: '#app',
48         data:{
49             msg:"hello world"
50         }
51     })
52 
53 
54  
55 </script>

 

子传父
  1、
父组件可以将自己方法传递给子组件来调用,实现子组件更改父组件的数据

<body>
    <div id="app">
        <father></father>
    </div>

    <template id="father">
        <div>            
          <p>这是父组件</p>
          <p>这是我儿子要和我说的话 ===> {{pMsg}}</p>
          <hr>
          <!--3.在调用子组件的时候,将这个更改自身数据的方法传递给子组件-->
          <son :change-a="changeMsg"></son>
        </div>
    </template>

    <template id="son">
        <div>  
           <p>这是子组件 {{msg}}</p>
           <!--5. 子组件调用此函数,相当于父组件的changeMsg就会被执行了,参数则是子组件传递过去的msg-->
           <p><button @click="changeA(msg)">我要对父亲说的话!</button></p>
        </div>
    </template>


</body>
<script src="./base/vue.js"></script>

<script>

    //父组件可以将自己方法传递给子组件来调用,
    //实现子组件更改父组件的数据
    Vue.component("father",{
        template:"#father",
        data(){
            return {
                pMsg:""   //1.定义一个父组件的数据
            }
        },
        methods:{
            changeMsg(msg){  //2.写一个更改自身数据的方法
                this.pMsg = msg
            }
        }
    })

    Vue.component("son",{
        template:"#son",
        props:["changeA"], //4.子组件需要通过props接收父组件传来的函数
        data(){
            return {
                msg:"今天很舒服"
            }
        }
    })

    new Vue({
        el:"#app"
    })
    
</script>
  


  2、还可以用this.$emit()方法调用父组件给子组件上绑定的方法

<body>
    <div id="app">
        <father></father>
    </div>

    <template id="father">
        <div>            
          <p>这是父组件</p>
          <p>这是我儿子要和我说的话 ===> {{pMsg}}</p>
          <hr>
          <!--1.父组件调用子组件的时候给其绑定一个自定义事件叫做change-->
          <son  @change="changeMsg"></son>
        </div>
    </template>

    <template id="son">
        <div>  
           <p>这是子组件 {{msg}}</p>
           <p><button @click="say">我要对父亲说的话!</button></p>
        </div>
    </template>
    

</body>
<script src="./base/vue.js"></script>

<script>

    
    //每一个组件或者实例都会有自定义事件,和触发事件的能力
    //父组件给子组件绑定一个自定义事件,这个事件的处理程序却是父组件的一个方法
    //当子组件触发这个事件的时候,相当于父组件的方法被执行

    Vue.component("father",{
        template:"#father",
        data(){
            return {
                pMsg:""   
            }
        },
        methods:{
            changeMsg(msg){  
                this.pMsg = msg
            }
        }
    })

    Vue.component("son",{
        template:"#son",
        data(){
            return {
                msg:"今天很舒服"
            }
        },
        methods:{
            say(){
                //2.子组件需要触发在自身上面绑定的事件   <son @change="changeMsg"/>
                this.$emit("change",this.msg)
            }
        }
    })

    new Vue({
        el:"#app"
    })

</script>

 

通过关系链传值(兄弟组件传值)
  
1、ref链、$parent/$children链

实例1
<body>
    <div id="app">
       <aaa></aaa>
    </div>
    <template id="aaa">  
        <div>
            <button ref="btn" @click="get">get</button>
            <bbb ref="bbb"></bbb>  
        </div>
    </template>
    <template id="bbb">
        <div>
            <input type="text" v-model="msg">
        </div>
    </template>

</body>
<script src="./base/vue.js"></script>

<script>

    //组件间不仅可以用过$root/$parent/$children来获取对应关系的组件,
    //父组件还可以主动的通过ref为子组件做标记  也可以给dom做标记
    //也会形成ref链,也可以交互,
    //注意多个子组件标记的是同一个键名,获取到的应该是一个数组


    Vue.component("bbb",{
        template:"#bbb",
        data(){
            return {
                msg:"hello"
            }
        }
    })

    Vue.component("aaa",{
        template:"#aaa",
        methods:{
            get(){
                // this.$children[0].msg = "world"   //关系链===》viewmodel链
                // this.$refs.bbb.msg = "world"         //ref链给组件做标记
                // this.$refs.btn.style.background = "pink"   //ref链给dom做标记
            }
        }
    })

    new Vue({
        el:"#app"
    })



</script>

实例2

<body>
    <div id="app">
        <big-brother ></big-brother>   
        <hr>
        <littel-brother ref="littel"></littel-brother>
    </div>


    <template id="big-brother">
        <div>
            <p>我是哥哥</p>
            <button @click="hitLittel">打弟弟</button> 
        </div>
    </template>


    <template id="littel-brother">
        <div>
            <p>我是弟弟</p>
            <p v-if="crying">呜呜呜uwuwuwuw~</p>
        </div>
    </template>

</body>
<script src="./base/vue.js"></script>

<script>
    //在兄弟组件之间的通信,可以采用关系链和ref链去使用,解决兄弟之间通信问题。
    Vue.component('big-brother', {
        template:"#big-brother",
        methods:{
            hitLittel(){
                //让弟弟组件的crying=true
                // this.$parent.$children[1].crying = true    ===> 通过vm链
                this.$parent.$refs.littel.crying = true     //===> 通过vm链+ref链
            }
        }
    })
    Vue.component('littel-brother', {
        template: '#littel-brother',
        data(){
            return {
                crying:false
            }
        }
    })
    new Vue({
        el:"#app"
    })


</script>

 

关系远了的话,就用event bus事件总线
  
event-bus
<body>
    <div id="app">
        <big-brother></big-brother>
        <hr>
        <littel-brother></littel-brother>
    </div>


    <template id="big-brother">
        <div>
            <p>我是哥哥</p>
            <button @click="hitLittel">打弟弟</button>
        </div>
    </template>


    <template id="littel-brother">
        <div>
            <p>我是弟弟</p>
            <p v-if="crying">呜呜呜呜呜~</p>
        </div>
    </template>

</body>
<script src="./base/vue.js"></script>

<script>

    //实现兄弟组件之间的通信
    // 1.viewmodel+ref链可以实现此通信。 2.event bus事件总线
    //创建一个空的实例,  event-bus 事件总线  绑定事件与触发事件的过程
    //创建vue对象  var bus= new Vue()
    //B组件绑定一个自定义事件,第二个参数为需要处理的函数
    //bus.$on("自定义事件名",this.cry)
    //A组件要执行B组件的事件名,就可以让B组件自己去执行cry的方法  
    //bus.$emit("自定义事件名")

    var bus= new Vue()   //1.创建一个公共的vue实例
    
    Vue.component('big-brother', {
        template: '#big-brother',
        methods:{
            hitLittel(){
                //3.触发事件
                bus.$emit("hit")
            }
        }
    })
    Vue.component('littel-brother', {
        template: '#littel-brother',
        data(){
            return {
                crying:false
            }
        },
        methods:{
            changeCrying(){
                this.crying = true
            }
        },
        mounted(){
            //2. 绑定好事件
            bus.$on("hit",this.changeCrying)
        }
    })
    new Vue({
        el:"#app"
    })


</script>

 




 

 

posted @ 2021-04-01 10:34  卖糖纸的小糖果  阅读(362)  评论(0)    收藏  举报