美文网首页
vue基础入门(3)

vue基础入门(3)

作者: 螺钉课堂 | 来源:发表于2019-12-20 10:16 被阅读0次

3.组件基础

#3.1.什么是组件?

#3.1.1.理解组件

前端组件化开发是目前非常流行的方式,什么是前端组件化开发呢?就是将页面的某一部分独立出来,将这一部分的数据、视图、以及一些控制逻辑封装到一个组件内部,暴露一些开箱即用的函数或者属性供外部组件调用。这种组织代码的开发方式我们称为组件化开发。通俗的说,我们需要把一个页面拆分成若干的小单元,每个小单元就是一个小组件,例如,一个网页,我们可以做如下拆分

image

组件开发的好处就是可以复用代码,下面是组件库举例

image

点击查看,Element UI

#3.1.2.vue中的组件

在vue中,所有的 Vue 组件同时也都是 Vue 的实例,所以可接受相同的选项对象 (除了一些根级特有的选项) 并提供相同的生命周期钩子。Vue组件带有一个名字,在根实例中,组件被定义为元素使用,下面我们来定义一个button计数器组件

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<div id="app">
    <button-counter></button-counter>
    <button-counter></button-counter>
    <button-counter></button-counter>
    <button-counter></button-counter>
    <button-counter></button-counter>
</div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>

    Vue.component('button-counter',{
        data(){
           return {
               num: 0
           }
        },
        methods:{
            fn(){
               this.num++
            }
        },
        template:'<button @click="fn">点击我,自己加1:{{num}}</button>'
    });
    let vm = new Vue({
        el: '#app'
    });
</script>
</body>
</html>

注意:组件中的data必须写成函数的形式,如果不写成函数的形式,组件间数据改变会相互影响

#3.1.3.组件定义实例

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        body {
            margin: 0;
        }
    </style>
</head>
<body>
<div id="app">
    <header-component></header-component>
    <main-component></main-component>
    <footer-component></footer-component>
</div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    //头部组件
    Vue.component('header-component', {
        template: "<div :style='styles'>这里是头部区域</div>",
        computed: {
            styles() {
                return {
                    width: '100%',
                    height: '100px',
                    backgroundColor: 'black',
                    color: 'white',
                    textAlign: 'center',
                    lineHeight: '100px',
                    fontSize: '30px'
                }
            }
        }
    });
    Vue.component('main-component', {
        template: `<div :style="styles">
                    <mainleft-component></mainleft-component>
                    <mainright-component></mainright-component>
                    </div>`,
        computed: {
            styles() {
                return {
                    width: '100%',
                    height: '500px',
                    backgroundColor: 'orangered',
                    paddingTop: '50px'
                }
            }
        }
    });
    Vue.component('mainleft-component', {
        template: '<div :style="styles"></div>',
        computed: {
            styles() {
                return {
                    width: '35%',
                    height: '400px',
                    backgroundColor: 'green',
                    float: 'left'
                }
            }
        }
    });
    Vue.component('mainright-component', {
        template: '<div :style="styles"></div>',
        computed: {
            styles() {
                return {
                    width: '60%',
                    height: '400px',
                    backgroundColor: 'blue',
                    float: 'right'
                }
            }
        }
    });
    Vue.component('footer-component', {
        template: '<div :style="styles">这里是底部区域</div>',
        computed: {
            styles() {
                return {
                    width: '100%',
                    height: '150px',
                    backgroundColor: 'black',
                    color: 'white',
                    textAlign: 'center',
                    lineHeight: '150px',
                    fontSize: '30px'
                }
            }
        }
    });
    let vm = new Vue({
        el: '#app'
    });
</script>
</body>
</html>

#3.1.4.组件的父子关系

image

#3.2.父组件向子组件传数据

组件有自己的作用域,并且相互之间是相互独立的,这样就涉及到组件间的通信问题,在子组件中是不能直接使用父组件中的数据的,要在子组件中使用父组件的数据,可以在子组件注册的时候用props选项来声明一个自定义属性,然后在使用组件的时候,通过这个自定义属性来绑定数据

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<div id="app">
    <button @click="showLogin">登录</button>
    <button @click="showRegister">注册</button>
    <template v-if="flagLogin">
        <dialog-component :title="loginTitle"></dialog-component>
    </template>
    <template v-if="flagRegister">
        <dialog-component :title="registerTitle"></dialog-component>
    </template>

</div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    Vue.component('dialog-component', {
        template: '<div :style="box"><div :style="boxTitle">{{title}}</div></div>',
        computed: {
            box() {
                return {
                    width: '300px',
                    height: '300px',
                    border: '1px solid black'
                }
            },
            boxTitle() {
                return {
                    backgroundColor: 'green',
                    textAlign: 'center',
                    height: '30px',
                    lineHeight: '30px',
                    color: 'white'
                }
            }
        },
        props:['title']
    });
    let vm = new Vue({
        el: '#app',
        data: {
            flagLogin: false,
            flagRegister: false,
            loginTitle: '登录',
            registerTitle: '注册'
        },
        methods: {
            showLogin() {
                this.flagLogin = true
            },
            showRegister(){
                this.flagRegister = true
            }
        }
    });
</script>
</body>
</html>

实例2: 新闻列表渲染

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<div id="app">
    <news-component :newsdata="newsdata"  :newstype="newstype"></news-component>
</div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    Vue.component('news-component', {
        template: `<div :style="wrap">
                        <div :style="wrapTitle">{{newstype}}</div>
                        <div :style="content">
                            <ul v-for="item in newsdata">
                                 <li>{{item.title}}</li>
                            </ul>
                        </div>
                    </div>`,
        computed: {
            wrap() {
                return {
                    width: '300px',
                    height: '400px',
                    border: '1px solid black',

                }
            },
            wrapTitle() {
                return {
                    padding: '15px',
                    width: '100%',
                    borderBottom: '1px solid black',
                    boxSizing: 'border-box'
                }
            },
            content(){
                return {
                    padding: '10px'
                }
            }
        },
        props:['newsdata', 'newstype']
    });
    let vm = new Vue({
        el: '#app',
        data: {
            newstype: '国内新闻',
            newsdata: [
                {'title': '国家药监局:武汉生物百白破疫苗不合格属偶发'},
                {'title': '下月起 这部分人群的抚恤补助标准将再次提高'},
                {'title': '85岁老人40万买保健品 身无分文流落街头称继续买'}
            ]

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

进一步拆分组件

Vue.component('news-component', {
        template: `<div :style="wrap">
                        <div :style="wrapTitle">{{newstype}}</div>
                        <div :style="content">
                            <news-list :news="newsdata"></news-list>
                        </div>
                    </div>`,
        computed: {
            wrap() {
                return {
                    width: '300px',
                    height: '400px',
                    border: '1px solid black',

                }
            },
            wrapTitle() {
                return {
                    padding: '15px',
                    width: '100%',
                    borderBottom: '1px solid black',
                    boxSizing: 'border-box'
                }
            },
            content() {
                return {
                    padding: '10px'
                }
            }
        },
        props: ['newsdata', 'newstype']
    });
    Vue.component('news-list', {
        template: `<ul>
                        <template v-for="item in news">
                            <li>{{item.title}}</li>
                        </template>
                   </ul>`,
        props:['news']
    });
    let vm = new Vue({
        el: '#app',
        data: {
            newstype: '国内新闻',
            newsdata: [
                {'title': '国家药监局:武汉生物百白破疫苗不合格属偶发'},
                {'title': '下月起 这部分人群的抚恤补助标准将再次提高'},
                {'title': '85岁老人40万买保健品 身无分文流落街头称继续买'}
            ]

        }
    });

#3.3.子组件向父组件传数据

#3.3.1.自定义事件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app"><button-component v-on:myevent="sayhi"></button-component></div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    Vue.component('button-component', {
        template: `<button @click="$emit('myevent', 'nodeing')">点击</button>`
    });
    new Vue({
        el: '#app',
        methods: {
            sayhi(name){
                alert('hi,' + name)
            }
        }
    })
</script>
</body>
</html>

注意: v-on 事件监听器在 DOM 模板中会被自动转换为全小写 (因为 HTML 是大小写不敏感的),因此,在定义事件名字的时候就不要用大写了,例如: myEvent,如果定义的名字为myEvent,在绑定事件的时候,v-on:myEvent会转成 v-on:myevent,这样就不会触发事件了

#3.3.2.实例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <input type="text" v-model="inputValue">
    <button @click="add">增加</button>
    <ul >
        <list-item
                v-for="(todo,index) in todos"
                :key="index"
                :todo="todo"
                v-on:del="del_todo"
        ></list-item>
    </ul>
</div>

<script src="node_modules/vue/dist/vue.js"></script>
<script>
    Vue.component('list-item', {
        template: `<li @click="$emit('del',todo)">{{todo}}</li>`,
        props: ['todos', 'todo']
    });

    new Vue({
        el: '#app',
        data: {
            inputValue: '',
            todos: []
        },
        methods: {
            add(){
                this.todos.push(this.inputValue);
                this.inputValue = ''
            },
            del_todo(todo){
                this.todos = this.todos.filter((item)=>{
                    return item !== todo
                })

            }

        }
    })
</script>
</body>
</html>

相关文章

  • vue基础入门

    vue基础入门

  • Python 高端课程培训,CMDB自动化运维培训!

    1、入门小基础(8个课时): 1、沙盒环境,py环境安装使用 2、vue 基础语法与组件学习 3、vue + el...

  • vue基础入门(3)

    3.组件基础 #3.1.什么是组件? #3.1.1.理解组件 前端组件化开发是目前非常流行的方式,什么是前端组件化...

  • Vue.js基础入门

    今天,给大家分享下Vue.js基础入门,我主要由了解Vue.js、开始起步、语法三个部分简单的写了基础入门知识,希...

  • Vue.js基础入门

    今天,给大家分享下Vue.js基础入门,我主要由了解Vue.js、开始起步、语法三个部分简单的写了基础入门知识,希...

  • VUE基础知识入门

    VUE基础知识入门 VUE官方文档教程链接:VUE 1.什么是Vue.js Vue.js(读音 /vjuː/, 类...

  • 渐进式框架 Vue.js 基础入门及简单编程演示

    渐进式框架 Vue.js 基础入门及简单编程演示 ---------------------- 概念基础 ----...

  • 01vue-安装vue

    资源 1.Vue.js2.0从入门到放弃---入门实例(一)2.Vue.js入门学习(一)3.Vue官方中文Api...

  • 2018-09-11 Vue day01

    1、Git2、Vue入门学习(练习)注:先引入vue.js(1)入门练习 (2)练习2 (3)练习3

  • Vue的基础入门

    Vue的基础入门 一、Vue的基础入门 简介作者:尤雨溪 版本:2.X版本 预估4-5月份3.0版本会发布 官网...

网友评论

      本文标题:vue基础入门(3)

      本文链接:https://www.haomeiwen.com/subject/dnubnctx.html