Vue.js学习笔记四

123 阅读7分钟

定义Vue组件

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

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

全局组件定义的三种方式

  1. 使用Vue.extend配合Vue.component方法:
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src='https://cdn.bootcss.com/vue/2.6.10/vue.min.js'></script>
</head>

<body>
    <div id="app">
        <!-- 如果要使用组件,直接把组件的名称,以HTML标签的形式引入到页面中即可 -->
        <my-com1></my-com1>
    </div>

    <script>
        //1.1使用Vue.extend来创建全局的Vue组件
        let com1 = Vue.extend({
            template:'<h3>这是使用Vue.extend创建的组件</h3>' //通过template属性,指定了组件要展示的HTML结构
        })
        //1.2 使用Vue.component('组件的名称',创建出来的组件模板对象)
        // Vue.component('myCom1', com1)
        //如果使用Vue.component定义全局组件的时候,组件名称使用了驼峰命名,
        //则在引用组件的时候,需要把大写的驼峰改为小写的字母,同时两个单词之间使用 - 链接

        //如果不实用驼峰,则直接拿名称来使用即可
        Vue.component('mycom1', com1)
        var vm=new Vue({
            el:'#app',
            data () {
                return{

                }
            },
            methods:{

            }
        });
    </script>
</body>

</html>
  1. 直接使用Vue.component方法:
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src='https://cdn.bootcss.com/vue/2.6.10/vue.min.js'></script>
</head>

<body>
    <div id="app">
        <!-- 还是使用标签形式来引入自己的组件 -->
        <mycom2></mycom2>
    </div>

    <script>
        //注意:不论是哪种方式创建出来的组件,组件的template属性指向的模板内容,必须有且只能有唯一的一个根元素
        Vue.component('mycom2', {
            template: '<div><h3>这是直接使用Vue.component创建出来的组件</h3><span>123</span></div>'
        })

        var vm = new Vue({
            el: '#app',
            data() {
                return {

                }
            },
            methods: {

            }
        });
    </script>
</body>

</html>
  1. 将模板字符串抽离出来:
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src='https://cdn.bootcss.com/vue/2.6.10/vue.min.js'></script>
</head>

<body>
    <div id="app">
        <my-com3></my-com3>
    </div>

    <!-- 在被控制的#app外面,使用template元素,定义组件的HTML模版结构 -->
    <template id="tmp1">
        <div>
            <h1>这是通过template元素,在外部定义的组件结构,这个方式,有代码的智能提示和高亮</h1>
            <h4>好用,不错</h4>
        </div>
    </template>

    <script>
        Vue.component('myCom3', {
            template: '#tmp1'
        })
        
        var vm = new Vue({
            el: '#app',
            data() {
                return {

                }
            },
            methods: {

            }
        });
    </script>
</body>

</html>

组件中的DOM结构,有且只能有唯一的根元素(Root Element)来进行包裹!

定义私有组件

同样的,在Vue实例里面有个components属性,在属性内部进行创建组件即可

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src='https://cdn.bootcss.com/vue/2.6.10/vue.min.js'></script>
</head>

<body>
    <div id="app">
        <my-com3></my-com3>
    </div>

    <div id="app2">
        <my-com3></my-com3>
        <login></login>
    </div>

    <!-- 在被控制的#app外面,使用template元素,定义组件的HTML模版结构 -->
    <template id="tmp1">
        <div>
            <h1>这是通过template元素,在外部定义的组件结构,这个方式,有代码的智能提示和高亮</h1>
            <h4>好用,不错</h4>
        </div>
    </template>

    <template id="tmp2">
        <div>
            <h1>这是私有的Login组件</h1>
        </div>
    </template>

    <script>
        Vue.component('myCom3', {
            template: '#tmp1'
        })

        var vm = new Vue({
            el: '#app',
            data() {
                return {

                }
            },
            methods: {

            }
        });

        var vm2 = new Vue({
            el: "#app2",
            components: {//定义实例内部私有组件的
                login: {
                    template: '#tmp2'
                }
            },
        })
    </script>
</body>

</html>

组件中的data

  • 组件可以有自己的data数据
  • 组件的data和实例的data有点不一样,实例中的data可以为一个对象,但是组件中的data必须是一个方法
  • 组件中的data除了必须为一个方法之外,这个方法内部还必须返回一个对象才行
  • 组件中的data数据,使用方式,和实例中的data使用方式完全一样
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src='https://cdn.bootcss.com/vue/2.6.10/vue.min.js'></script>
</head>

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

    <script>
        Vue.component('mycom1', {
            template:'<h1>这是全局组件 --- {{msg}}</h1>',
            data () {
                return {
                    msg:'这是组件中的data定义的数据'
                }
            }
        })

        var vm=new Vue({
            el:'#app',
            data () {
                return{

                }
            },
            methods:{

            }
        });
    </script>
</body>

</html>

组件切换的两种方式

方式一

首先在Vue实例的data属性里面设置一个flag标志,设置为false,当点击链接的时候,改变这个标识从而用v-if来对login和register标签进行条件渲染

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src='https://cdn.bootcss.com/vue/2.6.10/vue.min.js'></script>
</head>

<body>
    <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></register>
    </div>

    <script>

        Vue.component('login', {
            template:'<h3>登录组件</h3>'
        })

        Vue.component('register', {
            template:'<h3>注册组件</h3>'
        })

        var vm=new Vue({
            el:'#app',
            data () {
                return{
                    flag:false
                }
            },
            methods:{

            }
        });
    </script>
</body>

</html>

方式二

利用Vue提供的component,来展示对应名称的组件,component是一个占位符, :is 属性,可以用来指定要展示组件的名称

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src='https://cdn.bootcss.com/vue/2.6.10/vue.min.js'></script>
</head>

<body>
    <div id="app">
        <a href="" @click.prevent="comName = 'login'">登录</a>
        <a href="" @click.prevent="comName = 'register'">注册</a>

        <!-- Vue提供了component,来展示对应名称的组件 -->
        <!-- 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 () {
                return{
                    comName:'login'//当前component中的 :is绑定的组件的名称
                }
            },
            methods:{

            }
        });
    </script>
</body>

</html>

组件的切换动画

要对组件添加切换动画其实跟使用过度动画差不多,把要添加动画的内容用transition进行包裹,然后在设置动画进入和离开的style样式

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src='https://cdn.bootcss.com/vue/2.6.10/vue.min.js'></script>

    <style>
        .v-enter,
        .v-leave-to{
            opacity: 0;
            transform: translateX(150px);
        }

        .v-enter-active,
        .v-leave-active{
            transition: all 0.5s ease;
        }
    </style>
</head>

<body>
    <div id="app">
        <a href="" @click.prevent="comName = 'login'">登录</a>
        <a href="" @click.prevent="comName = 'register'">注册</a>

        <!-- 通过mode属性,来设置组件切换时候的模式 -->
        <transition mode="out-in">
            <component :is="comName"></component>
        </transition>

    </div>

    <script>

        Vue.component('login', {
            template:'<h3>登录组件</h3>'
        })

        Vue.component('register', {
            template:'<h3>注册组件</h3>'
        })

        var vm=new Vue({
            el:'#app',
            data () {
                return{
                    comName:'login'//当前component中的 :is绑定的组件的名称
                }
            },
            methods:{

            }
        });
    </script>
</body>

</html>