Vue2,组件,组件间的通讯,父子组件间的相互访问

组件以及组件间的通讯

组件

使用全局定义

Vue.component("mynav",{
    template:"<ul><li>首页</li><li>我的</li></ul>"
})

注意:在定义组件时里面的data属性必须是函数式编程,目的是每次调用组件返回一个独立的数。

局部组件的定义

//1.创建组件
let mynav={
    template:"<p>这是一个导航</p>",
    data(){
        return{
            
        }
    },
    methods:{},
    watch:{},
    computed:{},
    
}
//2.注册组件
const app=new Vue({
    el:'#app',
  components:{
      mynav
  }
})

*注意:驼峰命名组件时,使用组件写标签形式的时候该用-连接,例如定义了一个组件时myIpt,那么使用标签就应该这样写<my-ipt></my-ipt>

组件的嵌套

<body>
    <div id="app">
        <father></father>
    </div>
    <script src="../node_modules/vue/dist/vue.js"></script>
    <script>
     let son = {
            template: '<div>son</div>'
        }
        let father = {
            template: '<span>father<son></son></span>',
            components: {
                son
            }
        }
     
        const app = new Vue({
            el: '#app',
            components: {
                father
            }
        })

    </script>
</body>

注意:组件的嵌套子组件声明要放在父组件前面,父组件内必须声明子组件

组件间的通信

父向子通讯

props的使用,首先在父组件的子标签内写上要传递的元素,接着在子组件中通过props来接收,相当于一个data值,不过注意这里不能够改变该值,因为是父组件给的。

<body>
    <div id="app">
        <father></father>
    </div>
    <script src="../node_modules/vue/dist/vue.js"></script>
    <script>
     let son = {
            template: '<div>son {{m}}</div>',
            // props: ['m'],     //props:两种方法书写,对象和数组的方式
            props:{
                m:{
                    // type:Number,   //规定该值的类型必须是什么
                    // default:300,   //默认值
                    required:true      //父组件是否必须写这个m属性
                }
            }
        
        }
        let father = {
            template: '<span>father<son :m="money" ></son></span>',
            components: {
                son
            },
            data(){
                return{
                    money:100
                }
            }
        }
     
        const app = new Vue({
            el: '#app',
            components: {
                father
            }
        })

    </script>
</body>

子向父通讯

使用自定义事件

//子组件发布事件
this.$emit('more') 发布事件
//父组件注册事件
@more='handler()' //handler是一个函数体

我们来看详细代码:

<body>
    <div id="app">
        <father></father>
    </div>
    <script src="../node_modules/vue/dist/vue.js"></script>
    <script>
     let son = {
            template: '<div>son {{m}} <button @click="add">点击增加</button> </div>',
            // props: ['m'],
            props:{
                m:{
    
                    required:true
                }
            },
            methods: {
                add(){
                    this.$emit('add')  //发布一个add
                }
            },
        
        }
        let father = {
            template: '<span>father<son :m="money" @add="add"></son></span>',  //son标签内接收add并触发后面的函数。
            components: {
                son
            },
            data(){
                return{
                    money:100
                }
            },
            methods:{
                add(){
                    this.money+=100
                }
            }
           
        }
     
        const app = new Vue({
            el: '#app',
            components: {
                father
            }
        })

    </script>
</body>

兄弟组件之间的通信

创建一个事件车的Vue实例,通过它来发布和订阅。

<body>
    <div id="app">
        <brother1></brother1>
        <bro-ther2></bro-ther2>  //注意驼峰命名的组件标签的写法
    </div>
    <script src="../node_modules/vue/dist/vue.js"></script>
    <script>
        const eventBus = new Vue()
        let brother1 = {
            template: '<span @click="changecolor">111</span>',
            methods:{
                changecolor(){
                    eventBus.$emit('green')   //通过事件车去发布green
                }
            }

        }
        let broTher2 = {
            template: '<span :style={color:color}>222</span>',
            created(){
                eventBus.$on('green',()=>{  //通过事件车订阅了green事件,并执行回调函数赋值color
                this.color='green'
                })
            },
            data(){
                return{
                    color:''
                }
            }
        }
        const app = new Vue({
            el: '#app',
            components: {
                brother1,
                broTher2
            }
        })
    </script>
</body>

隔代通讯

使用的方法:provide inject

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

    </div>

    <!-- 各个模板的书写 -->
    <template id="son">
        <div>
            Son
            {{msg}}
        </div>
    </template>

    <template id="father">
        <div>
            Father
            <son></son>
        </div>
    </template>


    <template id="grandFather">
        <div>
            grandFather
            <father></father>
        </div>
    </template>

    <script src="../node_modules/vue/dist/vue.js"></script>
    <script>
        let son = {
            template: '#son',
            inject:['msg']   //inject接收

        }
        let father = {
            template: '#father',
            components: {
                son
            }
        }
        let grandFather = {
            template: '#grandFather',
            components: {
                father
            },
            provide:{
                msg:"隔代通讯"  //provide 提供 
            }

        }

        const app = new Vue({
            el: '#app',
            components: {
                grandFather
            }
        })
    </script>
</body>

PubSub插件实现 任意组件间的通讯

同样的可以用第三方插件:PubSub来实现同样的操作

  • pubsub.subscribe() 订阅
  • pubsub.publish() 发布
<body>
    <div id="app">
        <brother1></brother1>
        <brother2></brother2>
    </div>
    <script src="../node_modules/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/PubSub"></script>
    <script>
        const eventBus = new Vue();
        const pubsub = new PubSub();
        let brother1 = {
            template: '<span @click="changeGreen" :style={color:color}>brother1</span>',
            methods: {
                changeGreen() {
                    pubsub.publish('green')
                }
            },
            data() {
                return {
                    color: ''
                }
            },
            created() {
                pubsub.subscribe('red', () => {
                    this.color = 'red'
                })
            }
        }
        let brother2 = {
            template: '<span :style={color:color}  @click="changeRed">brother2</span>',
            created() {
                pubsub.subscribe('green', () => {
                    console.log(111);
                    this.color = 'green';
                })
            },
            data() {
                return {
                    color: ''
                }
            },
            methods: {
                changeRed() {
                    pubsub.publish('red')
                }
            }

        }
        const app = new Vue({
            el: '#app',
            components: {
                brother1,
                brother2
            }
        })
    </script>
</body>

父子组件的互相访问

父访问子

ref方法的使用,利用ref绑定组件,获得绑定的组件。

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

    </div>

    <!-- 各个模板的书写 -->
    <template id="son">
        <div v-show='isShow'>
            Son
        </div>
    </template>

    <template id="father">
        <div>
            Father
            <son ref="myson"></son>
            <button @click="change">显示或隐藏</button>
        </div>
    </template>
    <script src="../node_modules/vue/dist/vue.js"></script>
    <script>
        let son={
            template:'#son',
            methods: {
                changeColor(){
                   return this.isShow=!this.isShow
                }
            },
            data(){
                return{
                    isShow:false
                }
            }
        }
//ref 加到组件上的时候,获取到的是Vue实例

        let father={
        template:'#father',
        components:{
            son
        },
        methods:{
change(){
    console.log(this.$refs.myson)
    this.$refs.myson.changeColor()
}
        }
        }

    const app=new Vue({
            el:'#app',
            components:{
                father
            }
        })
    </script>
</body>

子访问父

$parent方法,访问到父组件。

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

    </div>

    <!-- 各个模板的书写 -->
    <template id="son">
        <div >
            Son
            <button @click="get">点击我得到父级元素的属性</button>
        </div>
        
    </template>

    <template id="father">
        <div>
            Father
            <son></son>
   
        </div>
    </template>
    <script src="../node_modules/vue/dist/vue.js"></script>
    <script>
        let son = {
            template: '#son',
            methods: {
                get(){
                    console.log(this.$parent.money)  //$parent 访问父组件
                }
            },
       
        }
  

        let father = {
            template: '#father',
            components: {
                son
            },
            data(){
                return{
                    money:111234
                }
            }
           
        }

        const app = new Vue({
            el: '#app',
            components: {
                father
            }
        })
    </script>
</body>

总结

无论是组件通讯还是组件间的访问目的都是为了组件间的传递数据,灵活的运用才是王道。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值