zoukankan      html  css  js  c++  java
  • Vue 2 --v-model、局部组件和全局组件、父子组件传值、平行组件传值

    一、表单输入绑定(v-model 指令)

      可以用 v-model 指令在表单 <input>、<textarea> 及 <select> 元素上创建双向数据绑定。

      详细用法参见官方文档:https://cn.vuejs.org/v2/guide/forms.html

    二、局部组件和全局组件

    1、了解根组件template模板的优先级大于el,如下方式验证:

    <div id="app">
       {{ msg }}
    </div>
    
    <script>
        // 如果仅仅是实例化vue对象中 既有el 又有template,
        // 如果template中定义了模板的内容 那么template模板的优先级大于el
        new Vue({ 
            el: '#app',
            data() {
                return {
                    msg:'alex'
                }
            },
            template: `
                <div class="app">   // 通过控制台可看到显示了template中定义的div
                    <h2>{{ msg }}</h2>
                </div>
            `
        })
    </script>

    2、局部组件的使用(声子,挂子,用子)

    <div id="app">
       <App></App>
    </div>
    
    <script>
        // 声明一个组件 相当于自定义一个标签 因此名字首字母要大写 跟已有标签区分
        // 局部组件 除了没有el属性 其他属性都与根组件(Vue实例化对象)一样
        // 另外 组件中的data一定是一个函数 且必须有返回值
        // 1、声明子组件
        let App = {
            data(){
                return {
                    text:"我是局部组件App"
                }
            },
            // 当前组件template中的标签与该组件的属性有关,跟其他组件无关
            // 子组件的template一定要写 根组件(有el属性)的template可以不写 用el
            // 组件的template中一定要用一个标签包含,也可以给他挂载子组件,并使用
            template:`
                <div>
                    <h2>{{ text }}</h2>
                </div>
            `
        };
        new Vue({
            el: '#app',
            data() {
                return {
                    msg:'alex'
                }
            },
            // 3、template中使用子组件 也可以不定义template属性 直接在el中使用
            // 以标签的形式 如<App />或者<App></App>
            template: `
                <div class="app">
                    <App />
                </div>
            `,
            // 属性components用来挂载子组件
            components:{
                // 2、挂载子组件App(可以挂载多个子组件 用逗号隔开依次书写即可)
                App  // 相当于App:App  如果键值一样,可以只写一个
            }
        })
    </script>

      总结:

        1)一个子组件挂载到哪个组件,这个组件就是我的父组件;

        2)以后模块化开发时,一个组件就是一个文件(一个组件包含了html,css,js),想使用这个组件时导入即可使用

    3、全局组件的使用

    <div id="app">
        <!-- 使用局部组件App和Vheader -->
        <App></App>
        <Vheader></Vheader>
    </div>
    
    <script>
        // 使用component方法 声明一个全局组件 全局组件不需要挂载 任一组件可使用
        // 第一参数是组件的名字 第二个参数是options
        Vue.component('VBtn',{
            data(){
                return {
    
                }
            },
            template:`
                <button>按钮</button>
            `
        });
    
        // 声明一个局部组件Vheader
        let Vheader = {
            data(){
                return {
                    text:"我是局部组件Vheader"
                }
            },
            // 使用全局组件VBtn
            template:`
                <div class="vheader">
                    <h2>{{ text }}</h2>
                    <VBtn></VBtn>
                </div>
            `
        };
    
        // 声明一个局部组件
        let App = {
            data(){
                return {
                    text:"我是局部组件App"
                }
            },
            // 使用全局组件VBtn
            template:`
                <div class="app">
                    <h2>{{ text }}</h2>
                    <VBtn></VBtn>
                </div>
            `
        };
        
        new Vue({
            el: '#app',
            data() {
                return {
                }
            },
            components:{
                App,  // 挂载局部组件App
                Vheader  // 挂载局部组件Vheader
            }
        })
    </script>

    补充:使用vue内置组件slot分发内容从而自定义按钮的值,代码修改如下:

    Vue.component('VBtn',{
        data(){
            return {
    
            }
        },
        template:`
            <button><slot></slot></button>
        `
    });
    // 声明一个局部组件Vheader
    let Vheader = {
        data(){
            return {
                text:"我是局部组件Vheader"
            }
        },
        // 使用全局组件VBtn
        template:`
            <div class="vheader">
                <h2>{{ text }}</h2>
                <VBtn>登录</VBtn>
            </div>
        `
    };

    三、父子组件之间传值

    1、父组件往子组件传值

    <div id="app">
        <App></App>   <!-- 使用局部组件App -->
    </div>
    
    <script>
        // 声明一个局部组件Vheader
        let Vheader = {
            data(){
                return {
    
                }
            },
      // 挂载父组件的属性,该组件中就可以使用,从父组件接收到的值也可再传给其子组件
            props:['msg','post'],
            template:`
                <div class="vheader">
                    <h2>子组件Vheader start</h2>
                    <p>{{ msg }}</p>
                    <p>{{ post.title }}</p>
                    <h2>子组件Vheader end</h2>
                </div>
            `
        };
    
        // 声明一个局部组件App
        let App = {
            data(){
                return {
                    text:"我是父组件App的数据",
                    app_post:{
                        id: 1,
                        title: 'hello world'
                    }
                }
            },
            //
            template:`
                <div class="app">
                    <Vheader :msg='text' :post='app_post'></Vheader>
                </div>
            `,
            components:{
                Vheader  // 挂载局部组件Vheader
            }
        };
    
        new Vue({
            el: '#app',
            data() {
                return {
                }
            },
            components:{
                App  // 挂载局部组件App
            }
        })
    </script>

     总结:

        1)在子组件中使用props声明,就可以在该组件中使用;

        2)从父组件中接收到的值也可以传递给他的子组件;

        3)父组件中绑定自定义的属性;

    2、子组件往父组件传值

    <div id="app">
        <App></App>      <!-- 使用局部组件App -->
    </div>
    
    <script>
        // 声明一个全局组件VBtn
        Vue.component('VBtn',{
            data(){
                return {}
            },
            props:['id'],  // 父组件Vheader传递过来的值
            template:`
                <button @click="clickHandler">{{ id }}</button>
            `,
            methods:{
                clickHandler(){
                    console.log(this);  // 每个组件中的this指的是当前组件对象
                    // this.$emit('父组件中声明的自定义的事件', ' 传值')
                    this.id++;
                    this.$emit('click_Handler', this.id);
                }
            }
        });
        // 声明一个局部组件Vheader
        let Vheader = {
            data(){
                return {}
            },
            props:['post'],  // 父组件App传递过来的数据
            template:`
                <div class="vheader">
                    <VBtn :id='post.id' @click_Handler="fuClickHandler"></VBtn>
                </div>
            `,
            methods:{
                fuClickHandler(val){
                    this.$emit('fatherHandler', val)  // 往父组件App传值
                }
            }
        };
        // 声明一个局部组件App
        let App = {
            data(){
                return {
                    app_post:{
                        id: 1,
                        title: 'hello world'
                    }
                }
            },
            template:`
                <div class="app">
                    {{ app_post.id }}
                    <Vheader :post='app_post' @fatherHandler="father_handler"></Vheader>
                </div>
            `,
            methods:{
              father_handler(val){
                  this.app_post.id = val
              }
            },
            components:{
                Vheader  // 挂载局部组件Vheader
            }
        };
        new Vue({
            el: '#app',
            data() {
                return {}
            },
            components:{
                App  // 挂载局部组件App
            }
        })
    </script>

      总结:

        1)子组件中,通过this.$emit('父组件中自定义的事件名', '值'),来触发父组件中自定义的事件;

        2)父组件中自定义事件(当前事件中接收子组件的),并为对应的子组件绑定(v-on)自定义的事件;

    五、平行组件之间传值

    <div id="app">
        <App></App>   <!-- 使用局部组件App -->
    </div>
    
    <script>
        // TestA ==》 TestB 传值
        // 平行组件传值前提:这两个方法必须绑定在同一个实例化对象(bus)上
        let bus = new Vue();  // 声明一个Vue对象,只是用来平行组件间传值
        // TestB要声明事件 bus.$on('事件的名字', function(val){})
        // TestA要触发事件 bus.$emit('TestA组件中声明的事件名', '')
        // 声明一个全局组件TestB
        Vue.component('TestB',{
            data(){
                return {
                    text: ""
                }
            },
            template:`
                <h2>{{ text }}</h2>
            `,
            created(){
                // 声明事件
                bus.$on('testData', (val) => {   // 注意这里用箭头函数
                    this.text = val
                })
            }
        });
        // 声明一个全局组件TestA
        Vue.component('TestA',{
            data(){
                return {
                    msg: "我是子组件TestA的数据"
                }
            },
            template:`
                <button @click="clickHandler">TestA组件中按钮</button>
            `,
            methods:{
                // 定义触发的函数
                clickHandler(){
                    console.log(bus);
                    bus.$emit('testData', this.msg)
                }
            }
        });
        // 声明一个局部组件Vheader
        let Vheader = {
            data(){
                return {}
            },
            template:`
                <div class="vheader">
                    <TestA></TestA>
                    <TestB></TestB>
                </div>
            `,
        };
        // 声明一个局部组件App
        let App = {
            data(){
                return {}
            },
            template:`
                <div class="app">
                    <Vheader></Vheader>
                </div>
            `,
            components:{
                Vheader  // 挂载局部组件Vheader
            }
        };
        // 根组件,可以没有template属性,直接在el中使用子组件
        new Vue({
            el: '#app',
            data() {
                return {}
            },
            components:{
                App  // 挂载局部组件App
            }
        })
    </script>

      总结:(以A->B传值为例)

        1)声明一个Vue对象(bus对象),只是用来平行组件间传值;

        2)B要声明事件 bus.$on('事件的名字', function(val){});

        3)A要触发事件 bus.$emit('TestA组件中声明的事件名', '值');

        4)注意:记住平行组件传值前提是这两个方法必须绑定在同一个实例化对象(bus)上;

    补充知识点

    1、关于this指向的问题,与vm实例没有任何关系,而是与箭头函数和普通函数的区别。总结两点:

      1)es5的普通函数,this指向是指向了调用者,比如vue实例的方法(在methods中声明了一个方法)是由vue实例vm调用的,所以this指向vm。

      2)箭头函数的this指向它的调用者所在的上下文,也就是vm实例所在的上下文(定义vm的父类),即window。

    2、vuejs官网中的组件注册部分解读

    3、将vue添加至chorme

  • 相关阅读:
    Apache Spark 2.2.0 中文文档
    Apache Spark 2.2.0 中文文档
    Apache Spark 2.2.0 中文文档
    Apache Spark 2.2.0 中文文档
    Apache Spark 2.2.0 中文文档
    Apache Spark RDD(Resilient Distributed Datasets)论文
    Apache Spark 2.2.0 中文文档
    Apache Spark 2.2.0 中文文档
    【机器学习实战】第10章 K-Means(K-均值)聚类算法
    [译]flexbox全揭秘
  • 原文地址:https://www.cnblogs.com/wxj1129549016/p/10034143.html
Copyright © 2011-2022 走看看