Vue学习:组件学习

一、什么是组件

  组件的出现,就是为了拆分Vue实例的代码量的,能够让我们以不同的组件,来划分不同的功能模块,将来我们需要什么样的功能,就可以去调用对应的组件即可; 组件化和模块化的不同:

  • 模块化: 是从代码逻辑的角度进行划分的;方便代码分层开发,保证每个功能模块的职能单一;
  • 组件化: 是从UI界面的角度进行划分的;前端的组件化,方便UI组件的重用

二、组件的创建

  • 创建方式1
var test_yk = Vue.extend({
      template: '<h1>创建组件</h1>'
    });
    Vue.component('testYk', test_yk );
  • 方式2
   Vue.component('testYk', Vue.extend({
            template: '<h3>创建组件</h3>'
        }));
  • 方式3
<template id="test">
        <h4>创建组件</h4>
    </template>
    Vue.component('testYk', Vue.extend({
            template: '#test'
        }));
  •  渲染:
   <!-- 有大字的要转成驼峰-->
        <test-yk></test-yk>

在这里插入图片描述

  • 创建私有组件
 <div id="app1">
        <test></test>
    </div>
    
<template id="yk1">
        <div>
            <h3>我是私有组件</h3>
        </div>
    </template>

        var vm = new Vue({
            el: '#app1',
            data: {
            },
            methods: {
            },
            // 定义实例内部私有组件的
            components: { 
                test: {
                    template: '#yk1'
                }
            }
        })

在这里插入图片描述

三、组件中的data

<body>
    <div id="app">
        <my></my>
    </div>
    <script>
        //组件中的data必须是一个有返回值的方法,和实例中的data使用不一样
        Vue.component('my', {
            template: '<h3>这是全局组件 --- {{msg}}</h3>',
            data: function () {
                return {
                    msg: '我是vue中的data----组件中的data必须有一个返回值,和实例中的data使用不一样'
                }
            }
        })
        var vm = new Vue({
            el: '#app',
            data: {
            },
          methods:{
            //组件方法
          }
        })
    </script>
</body>

在这里插入图片描述

四、使用components属性定义局部子组件

<body>
    <div id="app">
        <account>
            <login></login>
        </account>
    </div>
    <script>
        var vm = new Vue({
            el: '#app',
            data: {},
            methods: {},
            components: { // 定义子组件
                account: { // account 组件
                    template: '<div><h1>这是Account组件{{name}}</h1><login></login></div>', // 在这里使用定义的子组件
                    components: { // 定义子组件的子组件
                        login: { // login 组件
                            template: "<h3>这是登录组件</h3>"
                        }
                    }
                }
            }
        });
    </script>
</body>

在这里插入图片描述

五、组件的切换

  • 使用component实现组件的切换
<body>
    <div id="app">
        <!-- 组件需要加上单引号,不然应该是以字符串输出了-->
        <a href="" @click.prevent="comName='login'">登录</a>
        <a href="" @click.prevent="comName='register'">注册</a>
<!-- component 是一个占位符, :is 属性,可以用来指定要展示的组件的名称 -->
        <component :is="comName"></component>
    </div>
    <script>
        Vue.component('login', {
            template: '<h3>登录组件</h3>'
        })
        Vue.component('register', {
            template: '<h3>注册组件</h3>'
        })
        var vm = new Vue({
            el: '#app',
            data: {
                // 当前 component 中的 :is 绑定的组件的名称
                comName: 'login' 
            }
        })
    </script>
</body>
  • 使用v-if和v-else实现组件的切换
 <div id="app">
        <a href="" @click.prevent="flag=true">登录</a>
        <a href="" @click.prevent="flag=false">注册</a>
        <login v-if="flag"></login>
        <register v-else="flag"></register>
    </div> 
    <script>
        Vue.component('login', {
            template: '<h3>登录组件</h3>'
        })
        Vue.component('register', {
            template: '<h3>注册组件</h3>'
        })
        var vm = new Vue({
            el: '#app',
            data: {
                flag: false
            }
        })
    </script>

在这里插入图片描述
在这里插入图片描述

这里需要加上.prevent,防止预设行为,不然切换到注册的一瞬间就又切换回来了。

六、父子组件的传值

  • 父组件传值给子组件
  <div id="app">
          <!-- 父传子可以通过属性绑定方式传值 -->
        <yk :parentmsg="msg"></yk>
    </div>
    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                msg: '我是父组件的数据'
            },
            methods: {
            },
            components: {
                //子组件是无法直接获取父组件中的data上的数据和methods 中的方法
                yk: {
                    template: '<h3 @click="change">我是子组件 --- {{parentmsg}}</h3>',
                    // props 中的数据都是父组件传来的,都是只读的,无法重新赋值
                    props: ['parentmsg'],
                    methods: {
                        //即使强制修改,VUE会报错
                        change() {
                            this.parentmsg = '被修改了'
                        }
                    }
                }
            }
        })
    </script>

  • 父组件传方法给子组件
  <div id="app">
        <!-- 父组件向子组件传递方法,使用的是事件绑定机制v-on, 当我们自定义了一个事件属性之后,那么子组件就能够通过某些方式来调用传递进去的方法了 -->
        <!-- 如果show()带括号就是将调用完show的方法的结果返回给func,不带括号的就将show的方法给func-->
        <com2 @func="show"></com2>
    </div>
    <template id="tmpl">
        <div>
            <h1>这是 子组件</h1>
            <input type="button" value="这是子组件中的按钮 - 点击它,触发父组件传递过来的func方法" @click="myclick">
        </div>
    </template>
    <script>
        var com2 = {
            template: '#tmpl',
            methods: {
                myclick() {
                  this.$emit('func')
                }
            }
        }
        var vm = new Vue({
            el: '#app',
            data: {
                msg: '我是父组件的数据'
            },
            methods: {
                show() {
                    console.log('调用了父组件身上的 show 方法: --- ');
                }
            },
            //加载组件
            components: {
                com2
            }
        })
    </script>

在这里插入图片描述

  • 子组件传值给父组件(子组件需要使用父组件的方法传值)
 <div id="app">
        <com2 @func="show"></com2>
    </div>
    <template id="tmpl">
        <div>
            <h1>这是 子组件</h1>
            <input type="button" value="这是子组件中的按钮 - 点击它,触发 父组件传递过来的 func 方法" @click="myclick">
        </div>
    </template>


    <script>
        var com2 = {
            template: '#tmpl',
            data() {
                return {
                    sonmsg: { name: '张三', age: 16 }
                }
            },
            methods: {
                myclick() {
                    //调用父组件的方法并且穿值给组件
                    // this.$emit('func', 123)
                     //传对象
                    this.$emit('func', this.sonmsg)
                }
            }
        }
        var vm = new Vue({
            el: '#app',
            data: {
                msg: '我是父组件的数据'
            },
            methods: {
                show(data) {
                     //获取子组件传来的值
                   // console.log('调用了父组件身上的 show 方法: ---获取子组件传的值 ' + data);
                    //获取子组件传的对象 
                    this.msg = data
                    console.log("使用子组件的值 " + this.msg.name+" "+this.msg.age);
                }
            },
            //加载组件
            components: {
                com2
            }
        })
    </script>


在这里插入图片描述

七、使用ref获取组件和DOM元素

 vue不推荐直接操作dom元素

<body>
    <div id="app">
        <input type="button" value="获取" @click="getElement" ref="mybtn">
        <h3 ref="myH3"> 学习使用ref获取组件和DOM元素</h3>
        <hr>
        <!-- 组件也是可以通过ref引用的 -->
        <login ref="mylogin"></login>
    </div>
    <script>
        var login = {
            template: '<h1>登录组件</h1>',
            data() {
                return {
                    msg: '我是子组件的数据'
                }
            },
            methods: {
                show() {
                    console.log('调用了子组件的方法')
                }
            }
        }
        var vm = new Vue({
            el: '#app',
            data: {

            },
            methods: {
                getElement() {
                    //获取dom元素数据
                    console.log(this.$refs.myH3.innerText)
                    //通过ref调用子组件的数据
                    console.log(this.$refs.mylogin.msg);
                    //通过ref调用子组件的方法
                    this.$refs.mylogin.show()
                }
            },
            components: {
                login
            }
        })
    </script>
</body>
posted @ 2020-04-07 22:11  无话可说丶  阅读(528)  评论(0编辑  收藏  举报