Vue全家桶之组件(component)

1、Vue的标准开发方式

【1】Vue推荐的开发方式是 ------------- SPA(Single Page (Web) Application ) 单页面 Web 应用

【2】什么是 SPA (单页面应用) ?

单页面应用 :就是日后项目中只有一张页面 =========== 》》 》 index . html

【3】为什么Vue推荐开发方式SPA(单页面应用)的开发方式?

a、引入Vue js 文件

b、在现有的页面中创建一个Vue实例对象

一个页面中只能存在一个 Vue 实例

Vue 推荐的开发方式 : 一个应用中只能存在一个Vue实例

【4】使用现有的手段严格遵循SPA存在问题?

a、现有的开发方式会导致项目中唯一一个页面中代码会越来越多,不利于维护

b、现有开发方式导致项目中唯一 一个页面中完成全部业务功能,导致当前页面每次加载的速度非常的慢

【5】为了严格遵循SPA开发方式在Vue中提供了 Vue 组件(component)

组件作用:

1、减少Vue根实例的代码量

2、一个组件负责完成项目中的一个功能或一组功能实现业务功能隔离

3、组件还可以在Vue实现复用

【6】组件如何使用?

a、全局组件:直接注册到vue根实例的组件

Vue.component( ' ' ) // 注册这个就是全局组件

b、局部组件:只能在注册组件中使用的组件

const app = new Vue({

el:" ";

data:{ },

methods:{ },

computed:{ },

created(){ },

components:{ } , // 注册局部组件

})

最大的不同: 作用范围不同 ,如果是全局的,任何地方可用; 如果是局部的,当前组件可用

【7】组件的基本使用

a、全局组件的使用

1)定义组件

Vue.component('login', { //两个参数:参数一:组件名 参数二:组件的配置对象 ​ template: <h2>用户登录</h2>, //用来书写该组件的html代码 ​ });

2)使用组件

< login> < /login>

<body>
    <div id="app">
        <h1>{{msg}}</h1>
        <!-- 登录 -->
        <login></login>
        <!-- 注册 -->
        <register></register>
    </div>
</body>

</html>
<script src="../../js/vue.js"></script>
<script>
    //1、定义一个登录的全局组件
    Vue.component('login', { //两个参数:参数一:组件名   参数二:组件的配置对象
        template: `<h2>用户登录</h2>`, //用来书写该组件的html代码
    });


    //1、定义一个注册的全局组件
    Vue.component('register', { //两个参数:参数一:组件名   参数二:组件的配置对象
        template: `<h2>用户注册</h2>`, //用来书写该组件的html代码
    });
</script>

b、局部组件的使用

1)定义组件

    //定义一个局部组件
    components: {
        add: { // 语法:   组件名:{ template:` `}
            template: `<h2>用户添加</h2>`
        }
    }

2)使用组件

    <!-- 添加 -->
    <add></add>
<body>
    <div id="app">
        <!-- 添加 -->
        <add></add>
    </div>
</body>

</html>
<script src="../../js/vue.js"></script>
<script>
    const app = new Vue({
        el: "#app",
        data: {
            msg: "Vue中组件使用"
        },
        methods: {

        },
        computed: {

        },
        created() {

        },
        
        //定义一个局部组件
        components: {
            add: { // 语法:   组件名:{ template:` `}
                template: `<h2>用户添加</h2>`
            }
        }
    })
</script>

【8】Vue组件中定义组件数据data 、methods、computed、components

组件的生命周期分为四个阶段:

  • create(创建)

  • mount(挂载)

  • update(更新)

  • destroy(销毁)

组件中可以定义自己的data 、methods、computed、components、生命周期函数、以及自己的子组件。

<body>
    <div id="app">
        <h1>{{msg}}</h1>
        <!-- 使用登录组件 -->
        <login></login>
        <register></register>
    </div>
</body>

</html>
<script src="../../js/vue.js"></script>
<script>
    
    // 定义一个全局组件

    Vue.component('register', {
        template: `<h1>我是全局组件</h1>`
    })
    
    
    
    //定义一个局部组件
    
    const login = {
        template: `<div><h1>用户登录</h1><h2>{{count}}--------------{{countSqrt}}</h2><h2>{{msg}}</h2><aa></aa><register></register><button @click="add">点我count++</button></div>`,
        data() { //用来给当前组件定义属于组自己的数据               组件中定义的data必须是一个函数
            return { //在return中可以定义数据
                count: 0,
                msg: "我是组件的msg",
            }
        },
        methods: {
            add() {
                this.count++;
            }
        },
        computed: {
            countSqrt() {
                return this.count * this.count;
            }
        },
        components: {
            aa: {
                template: `<h1>我是aa子组件</h1>`
            }
        }
    };
    const app = new Vue({
        el: "#app",
        data: {
            msg: "Vue组件中定义组件的data、methods、components等"
        },
        // 定义一个局部组件
        components: { //用来定义局部组件
            login,
        }
    })
</script>

【9】Vue中父组件向子组件传递数据props

日后 Vue开发: 一切皆组件

(1) props 机制:

1、定义:Vue中提供一个特有数据传递机制

2、作用:在使用Vue组件时,如果需要通过父组件给组件传递数据可以通过 props 进行实现

(2) props的使用:

作用:props用来给组件传递相应静态数据或者是动态数据

a、传递静态数据: 在组件使用的标签上声明静态数据 key = value 在组件定义的内部使用props进行接收数据

注意:使用props机制接收数据就相当于自己组件data中声明一个这样的数据

<body>
    <div id="app">
        <h1>{{msg}}</h1>
        <login title="我是标题" count="0"></login>
    </div>
</body>
<script src="../../js/vue.js"></script>
<script>
    //定义组件对象
    const login = {
        props: ['title', 'count'],
        template: `<div><h1>{{title}} ----------- {{loginTitle}} ----------- {{count}}</h1></div>`,
        data() {
            return {
                loginTitle: this.title,
            }
        },

    };

    const app = new Vue({
        el: "#app",
        data: {
            msg: "组件之间的数据传递",
        },
        components: {
            login,
        }
    })
</script>

b、传递动态数据

根据属性绑定来实现

单项数据流

<body>
    <div id="app">
        <h1>{{msg}}</h1>
        <input type="text" v-model="name">
        <!-- 向子组件传递一个动态数据 -->
        <login :name="name" :msg="msg"></login>
    </div>
</body>
<script src="../../js/vue.js"></script>
<script>
    //定义组件对象
    const login = {
        props: ['name', 'msg'],
        template: `<div><h1>{{name}} ----------- {{msg}}</h1></div>`,
        data() {
            return {

            }
        },
    };
    const app = new Vue({
        el: "#app",
        data: {
            msg: "组件之间的传递",
            name: "我是vue实例管理数据"
        },
        components: {
            login,
        }
    })
</script>

【10】Vue中父组件向子组件传递事件并通过事件子组件传递数据到父组件

 

(1)Vue中父组件向子组件传递事件

在使用组件时,向组件传递事件

1、直接在对应的组件标签上定义 传递的事件即可 @key = value

<body>
    <div id="app">
        <h1>{{msg}}</h1>
        <login @aa="testParent"></login>
    </div>
</body>

<script src="../../js/vue.js"></script>
<script>
    const login = {
        template: `<div><h3>用户登录</h3> <button @click="testChild">点我去掉父组件中某个事件</button></div>`,
        methods: {
            testChild() {
                alert("我是子组件中定义的事件");
                //调用父组件中的testParent
                this.$emit('aa'); //用来调用父组件传递过来的事件
            }
        }
    };

    const app = new Vue({
        el: "#app",
        data: {
            msg: "组件之间的事件传递",
        },
        methods: {
            testParent() {
                alert("我是父组件上的事件")
            }
        },
        components: {
            login,
        }
    })
</script>

(2)通过事件子组件传递数据到父组件

1、 标签里边 @aa = " 父级事件 " ,在子组件中通过 this.$emit('aa' ,this.count ) 获取 aa 以及 父级事件,并将子组件中的数据this.count 传入到 父级事件以参数形式接收。

<body>
    <div id="app">
        <h1>{{msg}}{{count}}</h1>
        <login @aa="testParent"></login>
    </div>
</body>

<script src="../../js/vue.js"></script>
<script>
    //子组件
    const login = {
        template: `<div><h3>用户登录</h3> <button @click="testChild">点我去掉父组件中某个事件</button></div>`,
        data() {
            return {
                count: 19,
            }
        },
        methods: {
            testChild() {
                alert("我是子组件中定义的事件");
                //调用父组件中的testParent
                this.$emit('aa', this.count); //用来调用父组件传递过来的事件
            }
        }
    };

    //父组件
    const app = new Vue({
        el: "#app",
        data: {
            msg: "组件之间的事件传递",
            count: 0,
        },
        methods: {
            testParent(count) {
                alert("我是父组件上的事件");
                console.log(count);
                this.count = count;
            }
        },
        components: {
            login,
        }
    })
</script>

【11】组件的插槽使用slot

插槽 : slot

作用:用来扩展现有的组件,让组件变得更加灵活

插槽:占位

具名插槽 :带有名字的插槽

默认插槽 :默认插入全部插槽中

<body>
    <div id="app">
        <h1>{{msg}}</h1>
        <!-- 
        插槽:占位
        具名插槽  :带有名字的插槽
        默认插槽  :默认插入全部插槽中
        -->
        <login></login>
        <login><span slot="bb">欢迎进入我们的网站{{msg}}</span></login>
        <hr>
        <login><span slot="aa">Welcome come to aa</span></login>
    </div>
</body>

<script src="../../js/vue.js"></script>
<script>
    const login = {
        template: `<div><slot name="aa"></slot><h3>用户登录</h3><slot name="bb"></slot></div>`,
    }
    const app = new Vue({
        el: "#app",
        data: {
            msg: "组件的slot(插槽)使用"
        },
        components: {
            login,
        }
    })
</script>