zoukankan      html  css  js  c++  java
  • Vue.js-----轻量高效的MVVM框架(十、父子组件通信)

    #1、父链

    html:

    <h3>#父链</h3>
    <div>
        <div>子组件可以用 this.$parent 访问它的父组件。根实例的后代可以用 this.$root 访问它。父组件有一个数组 this.$children,包含它所有的子元素。</div>
        <div>
            尽管可以访问父链上任意的实例,不过子组件应当避免直接依赖父组件的数据,尽量显式地使用 props 传递数据。另外,在子组件中修改父组件的状态是非常糟糕的做法,因为:
            <ul>
                <li>这让父组件与子组件紧密地耦合;</li>
                <li>只看父组件,很难理解父组件的状态。因为它可能被任意子组件修改!理想情况下,只有组件自己能修改它的状态。
                </li>
            </ul>
        </div>
        <div id="dr01">
            <child01></child01>
        </div>
    </div>

    js: dr01作为父代组件,child01作为子代组件,grandson01作为孙代组件

    //***************************************************************
    //父链
    //自定义子代组件child01
    Vue.component("child01", {
        data: function() {
            return {
                cMsg: "this is child msg!",
                cParentMsg: this.$parent.dr01Msg, //child01的上级信息就是dr01的dr01Msg
                cRootMsg: this.$root.rootMsg, //child01的根信息就是dr01的rootMsg
            }
        },
        template: "<div>cMsg: {{cMsg}}, cParentMsg: {{cParentMsg}}, cRootMsg: {{cRootMsg}}</div>"
            +"<grandson01 :s-parent-msg='cMsg'></grandson01>"
    });
    //自定义孙代组件grandson01,
    Vue.component("grandson01", {
        data: function() {
            return {
                sMsg: "this is grandsonMsg1",
                sRootMsg: this.$root.rootMsg, //grandson01根信息就是dr01的rootMsg
            }
        },
        //grandson01上级信息就是child01的cMsg,
      //在这里使用props属性,将子代cMsg赋给孙代的“sParentMsg”,示例:在子代模板中:<grandson01 :s-parent-msg='cMsg'></grandson01>
    props:["sParentMsg"], template: "<div>sMsg: {{sMsg}}, sParentMsg: {{sParentMsg}}, sRootMsg: {{sRootMsg}}</div>" }) var dr01 = new Vue({ el: "#dr01", data: { dr01Msg: "this is dr01Msg!", rootMsg: "this is rootMsg!", }, });

     结果:

    #2、自定义事件

    html:

    <h3>#自定义事件</h3>
    <template id="dr02-temp">
        <input v-model="msg" placeholder="please input your message!" />
        <button @click="notifyAdd(msg)">Dispatche Event</button>
    </template>
    <div id="dr02">
        <div>
            <span>每个 Vue 实例都是一个事件触发器:</span>
            <ol>
                <li>使用 $on() 监听事件;</li>
                <li>使用 $emit() 在它上面触发事件;</li>
                <li>使用 $dispatch() 派发事件,事件沿着父链冒泡;</li>
                <li>使用 $broadcast() 广播事件,事件向下传导给所有的后代。</li>
            </ol>
        </div>
        <p>Messages: {{messages|json}}</p>
        <child02></child02>
    </div>

    js:

    //***************************************************************
        //自定义事件
        Vue.component("child02", {
            //定义模板中初始化的值
            data: function() {
                return {
                    msg: "hello",
                }
            },
            //指定模板为id为"dr02-temp"标签
            template: "#dr02-temp",
            methods: {
                //当点击按钮时会触发的事件
                notifyAdd: function(msg) {
                    console.log("invoke notifyAdd()");
                    if (msg.trim()) {
                        //将事件分发到vm实例中的"addMsg"事件中
                        this.$dispatch("addMsg", msg);
                        this.msg = "";
                    }
                }
            }
        });
        var dr02 = new Vue({
            el: "#dr02",
            //初始化messages数组
            data: {
                messages: [],
            },
            events: {
                //分发事件到vm实例中, 在创建实例时 `events` 选项简单地调用 `$on`
                addMsg: function(msg) {
                    console.log("invoke events's addMsg()");
                    this.messages.push(msg);
                }
            },
        });

    结果:

      

    #3、使用v-on绑定自定义事件

    html:

    <h3>使用v-on绑定自定义事件</h3>
    <template id="dr03-temp">
        <input v-model="msg" placeholder="input msg..." />
        <button @click="dispatchMsg(msg)">处理msg</button>
    </template>
    <div id="dr03">
        <p>Messages: {{messages|json}}</p>
        <child03 v-on:dispatchMsg="addMsg"></child03>
    </div>

    js:

       //***************************************************************
        //使用v-on绑定自定义事件(在这里测试的时候发现,在dispatchMsg方法中依然要写this.$dispatch,不然只能监听到dispatchMsg方法,并不能向上冒泡)
        //这里哪儿不对,问题出现在哪里????
        //这里选择使用局部注册组件的方式测试。
        var child03 = Vue.extend({
            data: function() {
                return {
                    msg: 'hello, child03!',
                }
            },
            template: "#dr03-temp",
            methods: {
                dispatchMsg: function() {
                    console.log("invoke dispatchMsg()");
                    if (this.msg.trim()) {
                //尽管使用了v-on绑定了自定义事件dispatchMsg到vm实例中的addMsg方法中,但是依然不会向上冒泡,这里事实上是有问题的。
    this.$dispatch("addMsg", this.msg); this.msg = ''; } } } }); var dr03 = new Vue({ el: "#dr03", data: { messages: [], }, events: { addMsg: function(msg) { console.log("invoke addMsg() msg: " + msg); this.messages.push(msg); } }, components: { "child03": child03, } });

    结果与上面类似,只是多了控制台的输出

      

    #子组件索引

    html:

    <h3>子组件索引</h3>
    <div id="dr04">
        <div>
            尽管有 props 和 events,但是有时仍然需要在 JavaScript 中直接访问子组件。为此可以使用 v-ref 为子组件指定一个索引 ID。
        </div>
        <child03 v-ref:c03></child03>
        <child04 v-ref:c04></child04>
    </div>

     js:

    //***************************************************************
    //字组件索引
    Vue.component("child03", {
        template: "<div>this is child03</div>"
    });
    Vue.component("child04", {
        template: "<div>this is child04</div>"
    });
    var dr04 = new Vue({
        el: "#dr04"
    });
    var child03 = dr04.$refs.c03;
    var child04 = dr04.$refs.c04;
    console.log("child03.$el: ");
    console.log(child03.$el);
    console.log("child04.$el: ");
    console.log(child04.$el);

    结果展示:

      

  • 相关阅读:
    Git 上传本地项目
    virtual和override
    ASP .NET依赖注入理解
    dotnet不是内部或外部的命令,也不是可运行的程序或批处理文件
    C++ 简单选择排序
    C++ 排序
    iOS UIDynamic
    iOS Modal
    C++ 折半查找
    C++ 二叉链表
  • 原文地址:https://www.cnblogs.com/wrcold520/p/5530414.html
Copyright © 2011-2022 走看看