Skip to content

Latest commit

 

History

History
393 lines (317 loc) · 9.3 KB

什么是组件.md

File metadata and controls

393 lines (317 loc) · 9.3 KB

什么是组件?

组件:组件的出现,就是为了拆分vue实例的代码量的,能够让我们以不同组件,来划分不同功能之间的模块,将来我们需要什么样的功能,就去调用什么样的组件。

模块化和组件化的区别

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

全局组件的定义和注册

组件(Component)是Vue最强大的功能之一,组件可扩展HTML元素,封装可重用的代码。

全局组件定义的方法有三种方式:

方法一

使用Vue.extend方法定义组件,使用Vue.commponent方法

<!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="vue.js"></script>
</head>

<body>
    <div id="app">
        <!-- 使用组件 -->
        <account></account>
    </div>

    <script>
        //第一步使用 Vue.extend定义组件
        var myconn = Vue.extend({
            //通过templat属性 指定了组件要展示html的结构 template是vue内置关键字 不可更改
            template: `
            <div>
                <h2>登录页面</h2>
                <h2>注册页面</h2>
            </div> `
        })
        //第二步使用Vue.component注册组件
        Vue.component('account', myconn); //第一个参数是组件的名称,第二个参数是组件的模板


        let vm = new Vue({
            el: "#app",
            data: {}
        })
    </script>
</body>

</html>

如果在注册时,组件的名称是驼峰命名比如:

Vue.component('myComponent',myAccount);//第一个参数是组件的名称,第二个参数是模板对象

在标签中使用组件时,需要把大写的驼峰改为小写的字母,同时两个单词用 - 进行连接

<my-component></my-component>

为了避免组件名不一致问题,直接在注册组件的时候使用-进行注册:

Vue.component('my-component',myAccount)

使用template的时候要用一个大的根元素进行包裹,直接写<template><h2>登录页面</h2><h2><注册压面/h2></template> 会报错

方法二

直接使用Vue.component方法定义、注册组件。一步到位

  Vue.component('account', {
            template: `
                <div>
                    <h2>登录页面</h2>
                    <h2>注册页面</h2>   
                </div>`
        })

方法三

推荐使用第三种方法这样有利用html的书写

<!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="vue.js"></script>
</head>

<body>
    <!--定义模板 -->
    <template id="myCount">
        <div>
            <h2>登录组件</h2>
            <h2>注册组件</h2>
        </div>
    </template>
    <div id="app">
        <!-- 使用组件 -->
        <acount></acount>
    </div>

    <script>
        //定义、注册组件
        Vue.component('acount', {
            template: '#myCount'
        })
        let vm = new Vue({
            el: "#app",
            data: {

            }
        })
    </script>
</body>

</html>

使用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="vue.js"></script>
</head>

<body>
    <!--定义模板 -->
    <template id="myCount">
        <h3>这是私有login组件</h3>
    </template>
    <div id="app">
        <!-- 使用组件 -->
        <my-login></my-login>
    </div>

    <script>
        //定义、注册组件
        // Vue.component('acount', {
        //     template: '#myCount'
        // })
        let vm = new Vue({
            el: "#app",
            data: {

            },
            components: { //定义注册Vue实例内部的私有组件
                myLogin: {
                    template: "#myCount"
                }

            }
        })
    </script>
</body>

</html>

为组件添加data和methods

组件是一个页面,那么就会需要动态的功能

<!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="vue.js"></script>
</head>

<body>
    <!-- 定义组件模板 -->
    <template id="myCount">
        <div>
            {{ myDate}}
            <a href="#" @click="login">登录1</a>
            <h2>登录页面</h2>
            <h3>注册页面</h3>
        </div>
    </template>
    <div id="app">
        <!-- 第一次使用组件 -->
        <acount></acount>
        <!-- 第二次使用组件 -->
        <acount></acount>
    </div>

    <script>
        Vue.component('acount', {
            template: "#myCount",
            data: function () {
                return {
                    myDate: 'Ljfy',
                }
            },
            //组件中的methods
            methods: {
                login: function () {
                    document.write(1);
                }
            }
        })
        let vm = new Vue({
            el: "#app",
        })
    </script>
</body>

</html>

在为组件添加数组时data不在是对象了,而是function,而且要通return的形式返回,否则页面上无法看到效果的。通过function返回的兑现的形式来定义data,作用是:

  • 组件中<account>被调用了两次(不像根组件那样只能调用一次,每个组件中myData都是独立的,不产生冲突
  • 通过函数返回对象的目的,是为了让每个组件都有自己独立的数据存储,而不是共享一套数据

为什么data必须是一个function

function Component(){
    this.data = this.data
}
Component.prototype.data = {
    name:"jack",
    age:22
}

实例他们的构造函数内的this内容是不一样的

Component.prototype这类底下的方法或者值,都是所有实例公开的

function Component(){
    
}
Component.prototype.data = {
    name:"jack",
    age:22
}
var componentA = new Component();
var componentB = new Component();
componentA.data.age = 55
console.log(componentA,componentB);

此时componentAcomponentBdata之间指向了同一个内存地址,age变成了55,导致了问题

接下就很好解释vue组件需要function

function Component(){
    this.data = this.data()
}
Component.prototype.data = function(){
    return{
        name:"jack",
        age:22
    }
}
var componentA = new Component();
var componentB = new Component();
componentA.data.age = 55
console.log(componentA,componentB);

此时的componentAcomponentA是相互独立的,data的age分别是55和22

组件的切换

v-ifv-else结合flag进行切换

<!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="vue.js"></script>
</head>

<body>
    <div id="app">
        <!-- .prevent阻止超链接的默认事件 -->
        <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>'
        })
        let vm = new Vue({
            el: "#app",
            data: {
                flag: false
            }
        })
    </script>
</body>

</html>

v-if..else只能控制一个,两个切换,那么三个,四个怎么办呢?

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="vue.js"></script>
</head>

<body>
    <div id="app">
        <!-- vue提供了component 来展示对象的组件
        :is 指定要展示组件的名称
        -->
        <a href="" @click.prevent="comName='login'">登录</a>
        <a href="" @click.prevent="comName='register'">注册</a>

        <component :is="comName"></component>
    </div>

    <script>
        Vue.component('login', {
            template: '<h3>登录组件</h3>'
        })
        Vue.component('register', {
            template: '<h3>注册组件</h3>'
        })
        let vm = new Vue({
            el: "#app",
            data: {
                comName: 'login'
            }
        })
    </script>
</body>

</html>