• vue——组件(二)


    一、组件化开发基础

    1 组件是什么
        扩展 HTML 元素,封装可重用的代码,目的是复用
        -例如:有一个轮播,可以在很多页面中使用,一个轮播有js,css,html
        -组件把js,css,html放到一起,有逻辑,有样式,有html
    2 分类
        -全局组件
        -局部组件
    3 工程化以后
        一个组件就是一个  xx.vue
        
    4 element ui 其实就是写了一堆好看的组件,以后我们直接拿过来用就可以了

    5 在vue中,实例就是对象

    1.1定义全局组件并使用

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <script src="js/vue.js"></script>
        <title>Title</title>
    </head>
    <body>
    
    <div id="box">
    
        <div @click="handleClick">我是根组件的div</div>
        <!--    全局组件使用-->
        <child></child>
        <ul>
            <li v-for="i in 4">{{i}}</li>
        </ul>
        <div>
            <child></child>
        </div>
    
    </div>
    
    
    </body>
    <script>
        //创建组件对象(全局组件)---注意写法
        Vue.component('child', {
            //组件的模板
            template: `
                <div>
                    <div style="background: red" @click="handleClick">我是头部</div>
                    <div v-if="isShow">显示消失</div>
                </div>
            `,
            // 组件的方法
            methods:{
                handleClick(){
                    console.log('我被点击了')
                    this.isShow=!this.isShow
                }
            },
            //组件的数据
            data(){
                return {
                    isShow:true
                }
            },
        })
        var vm = new Vue({
            el: '#box',
            data: {
                isShow:true,
            },
            methods:{
                  handleClick(){
                    console.log('根组件我被点击了')
                }
            }
        })
    </script>
    </html>

    1.2定义局部组件并使用

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <script src="js/vue.js"></script>
        <title>Title</title>
    </head>
    <body>
    
    <div id="box">
    
    <child></child>
    
    </div>
    
    
    </body>
    <script>
        //在根组件或全局组件 中定义出来局部组件(可定义多个,但必须注册)
        var vm = new Vue({
            el: '#box',
            data: {
                isShow: true,
            },
            methods: {
                handleClick() {
                    console.log('根组件我被点击了')
                }
            },
            //局部组件,对象里的key值是主键名
            components:{
                child:{  //child组件名
                    template:`
                    <div @click="handleClick">{{name}}</div>
                    `, //组件模板
                    methods:{
                        handleClick(){
                            console.log('我被点了')
                        }
                    },
                    data(){
                        return{
                            name:'lili'
                        }
                    },
                },
            }
    
        })
    
    </script>
    </html>

     二、组件编写方式与Vue实例的区别与联系

    1 自定义组件需要有一个root element(即根element),一般包裹在一个div中,跟vue实例(对象)一样
    2 父子组件的data是无法共享
    3 组件可以有data,methods,computed....,但是data 必须是一个函数
    
    总结:全局组件可以定义局部组件,局部组件只能在这个全局组件里使用;data返回的必须是个函数;数据或函数都是不共享的

    代码演示

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <script src="js/vue.js"></script>
        <title>Title</title>
    </head>
    <body>
    
    <div id="box">
        <navbar></navbar>
    </div>
    
    </body>
    <script>
        Vue.component('navbar', {
            template: `
            <div>
                <button @click="handleClick">返回</button>
                我是NavBar{{aa}}
                <button style="background: red">主页</button>
                <br>
                <child></child>
            </div>
        `,
            methods: {
                handleClick() {
                    console.log('nav nav')
                },
            },
            components: {
                child: {
                    template: `<button>儿子</button>`,
                }
    
            },
            data() {
                return {
                    aa: 'lili'
                }
            },
        })
    
        var vm = new Vue({
            el: '#box',
            data: {
                isShow: true,
            },
            methods: {
                handleClick() {
                    console.log('根组件我被点击了')
                }
            },
        })
    
    </script>
    </html>

    三、组件通信之父传子通信

    在全局组件中自定义属性(注意三种方式的不同):
        <global myname="name" myage="18"></global>
        <global :myname="name" :myage="19"></global>
        <global :myname="'Alice'" :myage="20"></global>
    
    在组件中获取:{{myname}}   {{myage}}

    代码演示

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>组件</title>
        <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></script>
    </head>
    <body>
    
    <div id="box">
        <!-- myName是自定义属性 -->
        <global myname="name" myage="18"></global>
        <global :myname="name" :myage="19"></global>
        <global :myname="'Alice'" :myage="20"></global>
    </div>
    
    </body>
    <script>
        // 创建1个组件对象(全局组件/子组件)
        Vue.component('global', {
            template: `
                <div>
                    <div style="background: red">全局组件/子组件</div>
                    {{myname}}
                    {{myage}}
                </div>
            `,
            props: ['myname', 'myage']
        })
        // 父组件
        let vm = new Vue({
            el: '#box',
            data: {
                name: 'lili'
            },
        })
    </script>
    </html>

    3.1属性验证

    #限制父传子的变量类型
    props: {
        myname: String,
        isshow: Boolean
    }
    #父传子时候注意以下区别
    <global :myname="name" :is_show="'false'"></global>
    <global :myname="name" :is_show="false"></global>
    <global :myname="name" :is_show="is_show"></global>

    代码演示

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>组件</title>
        <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></script>
    </head>
    <body>
    
    <div id="box">
        <!-- myName是自定义属性 -->
        <!--    <global :myname="name" :is_show="'false'"></global>-->
        <global :my_name="name" :is_show="is_show"></global>
        <global :my_name="name" :is_show="false"></global>
    </div>
    
    </body>
    <script>
        // 创建1个组件对象(全局组件/子组件)
        Vue.component('global', {
            template: `
                <div>
                    <div style="background: red">我是子组件:{{is_show}}</div>
                    <span>{{my_name}}</span>
                </div>
            `,
            props: {
                my_name: String,
                is_show: Boolean
            }
        })
        // 父组件
        let vm = new Vue({
            el: '#box',
            data: {
                name: 'lili',
                is_show: true
            },
        })
    </script>
    </html>

     四、组件通信之子父通信

    子传父(控制子组件的显示和隐藏)
    点击子组件,就会触发父组件的某个函数执行

    代码演示

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>子传父</title>
        <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></script>
    </head>
    <body>
    
    <div id="box">
        <global @my_event="handleClick($event)"></global>
    </div>
    
    </body>
    <script>
        // 创建1个组件对象(全局组件/子组件)
        Vue.component('global', {
            template: `
                <div>
                    <div style="background: red">全局组件/子组件</div>
                    <button @click="handleNav">点我</button>
                </div>
            `,
            data() {
                return {
                    name: 'lili'
                }
            },
            methods: {
                handleNav() {
                    console.log('我是子组件的函数')
                    this.$emit('my_event', 666, 777, this.name)
                }
            }
        })
        // 父组件
        let vm = new Vue({
            el: '#box',
            data: {},
            methods: {
                handleClick(a,b,c) {
                    console.log('我是父组件的函数')
                    console.log(a)
                    console.log(b)
                    console.log(c)
                }
            }
        })
    </script>
    </html>

    4.1 小案例

    • 子组件有1个按钮和1个输入框,子组件输入完内容后,数据在父组件中展示
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>子传父 小案例</title>
        <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></script>
    </head>
    <body>
    
    <div id="box">
        <global @my_event="handleShow($event)"></global>
        <br>
        <div>父组件接收到的数据:{{name}}</div>
    </div>
    
    </body>
    <script>
        // 创建1个组件对象(全局组件/子组件)
        Vue.component('global', {
            template: `
                <div>
                    <input type="text" v-model="myText">
                    <button @click="handleClick">点我传数据</button>
                </div>
            `,
            data() {
                return {
                    myText: ''
                }
            },
            methods: {
                handleClick() {
                    this.$emit('my_event', this.myText)
                }
            }
        })
        // 父组件
        let vm = new Vue({
            el: '#box',
            data: {
                name: ''
            },
            methods: {
                handleShow(a) {
                    this.name = a
                }
            }
        })
    </script>
    </html>

    五、ref属性

    #ref属性(也可实现组件间通信,子父,父子都可以使用)
    
    ref放在标签上,拿到的是 原生的DOM节点
    ref放在组件上,拿到的是 组件对象
        通过这种方式实现子传父(this.$refs.mychild.text)
        通过这种方式实现父传子(调用子组件方法传参数)

    代码演示

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>ref属性</title>
        <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></script>
    </head>
    <body>
    
    <div id="box">
        <input type="text" ref="myRef">
        <button @click="handleButton">点我</button>
    </div>
    
    </body>
    <script>
        // 创建1个组件对象(全局组件/子组件)
        Vue.component('global', {
            template: `
                <div>
                    <input type="text" v-model="myText">
                </div>
            `,
            data() {
                return {
                    myText: ''
                }
            },
            methods: {
                handleClick() {
                    this.$emit('my_event', this.myText)
                    this.$emit('my_event', this.innerHTML)
                }
            }
        })
        // 父组件
        let vm = new Vue({
            el: '#box',
            data: {
                name: ''
            },
            methods: {
                handleShow(a) {
                    this.name = a
                },
                handleButton() {
                    console.log(this.$refs)
                    console.log(this.$refs.myRef)
                    console.log(this.$refs.myRef.value)
                }
            }
        })
    </script>
    </html>

    六、事件总线

    即:不同层级的不同组件通信

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>事件总线</title>
        <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></script>
    </head>
    <body>
    
    <div id="box">
        <global1></global1>
        <hr>
        <global2></global2>
    </div>
    
    </body>
    <script>
        // 定义1个时间总线
        let bus = new Vue({})
    
        // 组件1
        Vue.component('global1', {
            template: `
                <div>
                    <h3>组件1</h3>
                    <input type="text" v-model="myText">
                    <button @click="handleClick1">点我传递数据到另一个组件</button>
                </div>
            `,
            data() {
                return {
                    myText: ''
                }
            },
            methods: {
                handleClick1() {
                    console.log(this.myText)
                    bus.$emit('any', this.myText)  // 通过事件总线发送
                }
            }
        })
        // 组件2
        Vue.component('global2', {
            template: `
                <div>
                    <h3>组件2</h3>
                    收到的消息是:{{recvText}}
                </div>
            `,
            data() {
                return {
                    recvText: ''
                }
            },
            mounted() { // 组件的挂载(生命周期钩子函数中的1个),开始监听时间总线上的:any
                bus.$on('any', (item) => {
                    console.log('收到了', item,)
                    this.recvText = item
                })
            },
            methods: {}
        })
        // 父组件
        let vm = new Vue({
            el: '#box',
            data: {},
        })
    </script>
    </html>

    七、动态组件

    keep-alive可以让输入框内有的内容一致保持,不会因为切换而重置

    代码演示

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></script>
        <title>Title</title>
    </head>
    <body>
    
    <div id="box">
    
        <ul>
            <li @click="who='child1'">首页</li>
            <li @click="who='child2'">商品</li>
            <li @click="who='child3'">订单</li>
        </ul>
        <!--<component :is="who"></component>-->
        <keep-alive>
            <component :is="who"></component>
        </keep-alive>
    </div>
    
    </body>
    <script>
    
        var vm = new Vue({
            el: '#box',
            data: {
                who: 'child1'
            },
            components: {
                child1: {
                    template: `
                    <div>我是首页 
                    <input type="text">
                    </div>
                    `,
    
                },
                child2: {
                    template: `
                    <div>我是商品 </div>
                    `,
    
                },
                child3: {
                    template: `
                    <div>我是订单 </div>
                    `,
                }
            }
        })
    
    </script>
    </html>

    keep-alive可以让输入框内有的内容一致保持,不会因为切换而重置

  • 相关阅读:
    redis 基本操作-python 使用redis-手机验证接口-发送短信接口
    登录-注册页面修订
    10-29 课堂笔记
    git 协作开发
    git 常规使用
    luffy-city 基础环境搭建(至轮播图前后台交互实现)-步骤目录
    偏移分页-游标(加密)分页-自定义过滤器-第三方过滤器插件(django-filter)
    drf 大总结
    739. Daily Temperatures
    617. Merge Two Binary Trees
  • 原文地址:https://www.cnblogs.com/guojieying/p/14150481.html
Copyright © 2020-2023  润新知