zoukankan      html  css  js  c++  java
  • vue组件通信

     一、vue组件通信

    1、props(父向子传递)

    • 父组件使用子组件时,自定义属性(属性名任意,属性值为要传递的数据)

    • 子组件通过props接收父组件数据,通过自定义属性的属性名

    示例:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <div id="app">
        <child_temp v-bind:child_msg="parent_msg" :chlid_movies="parent_movies"></child_temp>
    </div>
    
    <template id="child_temp">
        <div>
            <ul>
                <li v-for="item in chlid_movies">{{item}}</li>
            </ul>
            <p>{{child_msg}}</p>
            <p>{{chlid_movies}}</p>
            <p>{{myname}}</p>
            <!--<button @click="child_btn">子按钮</button>-->
        </div>
    </template>
    </body>
    <script src="../../js/vue.js"></script>
    <script>
    
        const child_temp = {
            template:'#child_temp',
            /*props:['chlid_movies','child_msg'],*/
            props:{
                //props的扩展,包括类型,默认值,是否必须等
                //1类型限制
                /*chlid_movies:Array,
                child_msg:String*/
                //2.提供默认值,扩展
                chlid_movies:{
                  type:Array,
                  default() {
                      return [];
                  }
                },
                child_msg: {
                    type: String,
                    required: true,
                    default() {
                        //如果把child_temp模板里的v-bind:child_msg="parent_msg"去掉,页面就会显示这里的值
                        return ["子_我是子组件默认值,当使用父组件data里的属性值得时候,如果没有用v-bind绑定,会取到我这一串值"];
                    }
                }/*,
                methods:{
                    child_btn(){
                        alert("我是子组件的方法")
                    }
                }*/
            },
            data(){
                return {
                    myname:"子_我是子属性自己的值,我使用的是自己组件里的data的属性值"
                }
            }
        }
        var vm = new Vue({
                el:"#app",
            data:{
                parent_msg:"父_我是父组件里的信息,传到了子组件",
                parent_movies:['父_火影','父_海贼王','父_柯南']
            },
            components:{
                child_temp
                }
            })
    </script>
    </html>

    效果:

    2、props验证(参照上边代码例子)

    props:定义需要从父组件中接收的属性

    • items:是要接收的属性名称

    • type:限定父组件传递来的必须是数组

    • default:默认值

    • required:是否必须

    验证支持的数据类型

    • String

    • Number

    • Boolean

    • Array

    • Object

    • Date

    • Function

    • Symbol

    动态静态传递

    给 prop 传入一个静态的值:

    <temp child_msg="大家好,我是组件"/>

    给 prop 传入一个动态的值: (通过v-bind从数据模型中,获取title的值)

    <temp :child_msg="parent_msg"/>

    3、子向父的通信:$emit

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <!--父组件模板-->
        <div id="app">
            <!--监听子组件发射出的btn_child_click事件,find_parent_click要在父组件里定义methods-->
            <chlid_temp v-on:btn_child_click="find_parent_click"></chlid_temp>
        </div>
        <!--子组件模板-->
        <template id="chlid_temp">
            <div>
                <button v-for="item in movies"
                        @click="btn_ckik(item)">
                        {{item.id}}-{{item.name}}
                </button>
            </div>
        </template>
    </body>
    <script src="../../js/vue.js"></script>
    <script>
        //子组件
        const chlid_temp = {
            template:"#chlid_temp",
            data(){
                return{
                    movies:[
                        {id:"1",name:"火影"},
                        {id:"2",name:"海贼"},
                        {id:"3",name:"七大罪"},
                        {id:"4",name:"菜鸟java是怎么炼成的"},
                        {id:"5",name:"菜鸟是怎么变菜的"},
                    ]
                }
            },
            methods:{
                btn_ckik(ev){
                    //自定义事件
                    this.$emit("btn_child_click",ev)
                }
            }
        }
        //父组件
        var vm =  new Vue({
            el:"#app",
            data:{
                msg:"我是父组件的信息-msg"
            },
            components:{
                chlid_temp
            },
            methods:{
                find_parent_click(ev){
    
                     console.log(ev)
                     console.log(ev.id +"  "+ev.name)
    
                }
            }
        });
    </script>
    </html>

    效果:

    4、父子通信示例

    需求:父组件里的num1和num2,和子组件里的num1和num2实现双向绑定,并且input1里的num1输入后input2里num2的值会相应的变为num1值得100倍,反之num2是num1的100分之1.

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <div id="app">
            <temp :c_num1="p_num1"
                  :c_num2="p_num2"
                  @data_cnum1_change="parent_cnum1_change"
                  @data_cnum2_change="parent_cnum2_change"
            ></temp>
        </div>
        <template id="temp">
            <div>
    
                <h3>props:{{c_num1}}</h3>
                <h3>data:{{data_cnum1}}</h3>
                <!--<input type="text" v-model="data_cnum1">-->
                input1:<input type="text" :value="data_cnum1" @input="num1_input">
                <h3>props:{{c_num2}}</h3>
                <h3>data:{{data_cnum2}}</h3>
                <!--<input type="text" v-model="data_cnum2">-->
                <!--<input type="text" :value="data_cnum2" @input="data_cnum2=$event.target.value">-->
                input2:<input type="text" :value="data_cnum2" @input="num2_input">
            </div>
        </template>
    </body>
    <script src="../../js/vue.js"></script>
    <script>
        const temp={
            template:"#temp",
            props:{
                c_num1:Number,
                c_num2:Number
    
            },
            data(){
               return{
                   data_cnum1:this.c_num1,
                   data_cnum2:this.c_num2
               }
            },
            methods:{
                num1_input(e){
                    //1 将input的value赋值到data_cnum1上
                    this.data_cnum1 = e.target.value;
                    //2 为了让父组件可以改值,发出一个事件
                    this.$emit("data_cnum1_change",this.data_cnum1);
                    //3 同事修改data_cnum2的值(data_cnum2的值是data_cnum1的100倍)
                    this.data_cnum2 = this.data_cnum1 * 100;
                    this.$emit("data_cnum2_change",this.data_cnum2)
                },
                num2_input(e){
                    this.data_cnum2 = e.target.value;
                    this.$emit("data_cnum2_change",this.data_cnum2);
                    //(data_cnum2的值是data_cnum1的100分之一倍)
                    this.data_cnum1 = this.data_cnum2 / 100;
                    this.$emit("data_cnum1_change",this.data_cnum1)
                }
            }
        }
        var vm = new Vue({
            el:"#app",
            data:{
                p_num1:1,
                p_num2:0
            },
            components:{
                temp
            },
            methods:{
                parent_cnum1_change(data_cnum1){
                    //默认传过来的是Strnig类型,需要转换成number
                    console.log(typeof data_cnum1)
    
                    this.p_num1 = parseInt(data_cnum1);
                },
                parent_cnum2_change(data_cnum2){
                    this.p_num2 = parseInt(data_cnum2);
    
                }
            }
        })
    </script>
    </html>

     

     

    二、父子组件访问方式

    1、父访问子

    • 父访问子使用使用$children或$refs

    $children的缺陷:通过$children访问子组件时,是一个数组类型,访问其中的子组件必须通过索引值。但是当子组件过多,我们需要拿到其中一个时,往往不能确定它的索引值,甚至还可能会发生变化。有时候,我们想明确获取其中一个特定的组件,这个时候就可以使用$refs$refs的使用:$refs和ref指令通常是一起使用的。首先,我们通过ref给某一个子组件绑定一个特定的ID。其次,通过this.$refs.ID就可以访问到该组件了。

    例子

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <div id="app">
         <cpn></cpn>
         <cpn></cpn>
         <cpn></cpn>
         <cpn ref="ref_name"></cpn>
        <button @click="btnClick">按钮</button>
        {{message}}
    </div>
    
    <template id="cpn">
        <div>我是子组件</div>
    </template>
    <script src="../../js/vue.js"></script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                message: '你好啊'
            },
            methods: {
                btnClick() {
                    // 1.$children
                    console.log(this.$children);
                    for (let v of this.$children) {
                      console.log(v.child_name);
                      v.childMessage();
                      this.message = v.child_name;
                    }
                    console.log(this.$children[3].child_name+'================');
                    /*console.log(this.$children[4].child_name+'++++++++++++');*/
                    // 2.$refs => 对象类型, 默认是一个空的对象 ref='ref-name'
                    console.log(this.$refs.ref_name.child_name+"----------");
                }
            },
            components: {
                cpn: {
                    template: '#cpn',
                    data() {
                        return {
                            child_name: '我是子组件的name哈哈'
                        }
                    },
                    methods: {
                        childMessage() {
                            console.log('childMessage');
                        }
                    }
                },
            }
        })
    </script>
    
    </body>
    </html>

    2、子访问父

    • 通过$parent子访问父
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    
    <div id="app">
        <button @click="rootclik()">根组件按钮</button>
        <cpn></cpn>
    </div>
    
    <template id="cpn">
        <div>
            <h2>我是cpn组件</h2>
            <ccpn></ccpn>
        </div>
    </template>
    
    <template id="ccpn">
        <div>
            <h2>我是子组件</h2>
            <button @click="btnClick">按钮</button>
        </div>
    </template>
    
    <script src="../../js/vue.js"></script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                message: '我是ccpn组件的根组件的name'
            },
            methods: {
                rootclik(){
                console.log("我是根组件root的事件")
                }
            },
            components: {
                cpn: {
                    template: '#cpn',
                    data() {
                        return {
                            name: '我是ccpn组件的父组件的name'
                        }
                    },
                    methods: {
                        parentclik(){
                            console.log("我是父组件parent的事件")
                        }
                    },
                    components: {
                        ccpn: {
                            template: '#ccpn',
                            methods: {
                                btnClick() {
                                    // 1.访问父组件$parent
                                    console.log("======parent start============")
                                    console.log(this.$parent);
                                    console.log(this.$parent.name);
                                    console.log(this.$parent.parentclik());
                                    console.log("======parent end============")
    
                                    // 2.访问根组件$root
                                    console.log("======root start============")
                                    console.log(this.$root);
                                    console.log(this.$root.message);
                                    console.log(this.$root.rootclik());
                                    console.log("======root end============")
                                }
                            }
                        }
                    }
                }
            }
        })
    </script>
    
    </body>
    </html>
  • 相关阅读:
    Linux 系统使用WordPress开启“固定链接设置”之后部分页面打不开(404)的解决办法
    WordPress安全配置
    去掉Windows2003的自动锁定
    用IP访问wordpress的css和js为何不能加载
    元素伸缩
    Cookie之获设删
    输入0开头的数字,自动纠正
    PHP入门(一)
    node.js(一)
    vue-demo-tab切换
  • 原文地址:https://www.cnblogs.com/konglxblog/p/15212571.html
Copyright © 2011-2022 走看看