• vue框架之组件通信及插槽简介等相关内容-113


    1 定义局部组件

    2 组件编写方式与Vue实例的区别

    1 自定义组件需要有一个root element,一般包裹在一个div中,跟vue实例一样
    2 父子组件的data是无法共享
    3 组件可以有data,methods,computed....,但是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>
      {{aa}}
    </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: 'lqz'
              }
          },
      })
       var vm = new Vue({
           el: '#box',
           data: {
               isShow: true,
          },
           methods: {
               handleClick() {
                   console.log('根组件我被点击了')
              }
          },
      })

    </script>
    </html>

    3 组件通信之父传子通信

    1 父子通信
    2 在全局组件上自定义属性
    <navbar myname="lqz" age="18"></navbar>
    3 在组件中获取
    props: ['myname','age']  #myname=lqz   age=18
           
    4 区分开这两种赋值方式
        <navbar myname="lqz" age="18"></navbar>
        <navbar :myname="'ffff'" age="19"></navbar>
        <navbar :myname="name" age="19"></navbar>
    <!DOCTYPE html>
    <html lang="en">
    <head>
       <meta charset="UTF-8">
       <script src="js/vue.js"></script>
       <title>Title</title>
    </head>
    <body>
    <div id="box">
       <!--myname是自定义属性-->
       <navbar myname="lqz" age="18"></navbar>
       <navbar :myname="'ffff'" age="19"></navbar>
    </div>
    </body>
    <script>
       Vue.component('navbar', {
           template: `
           <div>
               <button @click="handleClick">返回</button>
               我是NavBar---{{age}}
               <button style="background: red">{{myname}}</button>
           </div>
       `,
           props: ['myname','age']
      })

       var vm = new Vue({
           el: '#box',
           data: {
               name: 'xxx',
          },
      })

    </script>
    </html>

     

    属性验证

    1 限制父传子的变量类型
     props: {
               myname:String,
               isshow:Boolean
          }
    2 父传子时注意以下的区别
       <navbar myname="lqz" :isshow="isshow"></navbar>
       <navbar myname="lqz" :isshow="false"></navbar>

     

    <!DOCTYPE html>
    <html lang="en">
    <head>
       <meta charset="UTF-8">
       <script src="js/vue.js"></script>
       <title>Title</title>
    </head>
    <body>

    <div id="box">
       <!--myname是自定义属性-->
    <!--   <navbar myname="lqz" isshow="false"></navbar>-->
       <navbar myname="lqz" :isshow="isshow"></navbar>
       <navbar myname="lqz" :isshow="false"></navbar>

    </div>


    </body>
    <script>
       Vue.component('navbar', {
           template: `
           <div>
               <button>返回</button>
               我是NavBar---{{isshow}}
               <button style="background: red">{{myname}}</button>
           </div>
       `,
           props: {
               myname:String,
               isshow:Boolean
          }
      })

       var vm = new Vue({
           el: '#box',
           data: {
               name: 'xxx',
               isshow:true,
          },
      })

    </script>
    </html>

    4 组件通信之子父通信

    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">
    <navbar @myevent="handleClick"></navbar>
    </div>
    </body>
    <script>
       Vue.component('navbar', {
           template: `
           <div>
               <button @click="handleNav">点我,触发父组件的某个函数执行</button>
           </div>
       `,
           data(){
               return {
                   name:'lqz'
              }
          },
           methods:{
               handleNav(){
                   console.log('我是nav的函数,我执行了')
                   this.$emit('myevent',100,this.name,99)
              }
          }
      })
       var vm = new Vue({
           el: '#box',
           data: {
          },
           methods:{
               handleClick(ev,a,b){
                   console.log('我是父组件的函数,我执行了')
                   console.log(ev)
                   console.log(a)
                   console.log(b)
              }
          }


      })


    </script>
    </html>

    小案例

    子组件有一个按钮,有一个输入框,当输入完内容,点击按钮,数据在父组件中展示

    <!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 @myevent="handle"></child>
       <hr>
      {{name}}
    </div>

    </body>
    <script>
       Vue.component('child', {
           template: `
           <div>
           <input type="text" v-model="mytext">
           <button @click="handleClick">点我</button>
           </div>
       `,
           data() {
               return {
                   mytext: ''
              }
          },
           methods: {
               handleClick() {
                   this.$emit('myevent', this.mytext)
              }
          }
      })
       var vm = new Vue({
           el: '#box',
           data: {
               name: ''
          },
           methods: {
               handle(a) {
                   this.name = a
              }
          }
      })
    </script>
    </html>

    5 ref属性(也可实现组件间通信,子父,父子都可以使用)

    ref放在标签上,拿到的是原生节点
    ref放在组件上,拿到的是组件对象,
    通过这种方式实现子传父(this.$refs.mychild.text)
    通过这种方式实现父传子(调用子组件方法传参数)

    使用

    <!DOCTYPE html>
    <html lang="en">
    <head>
       <meta charset="UTF-8">
       <script src="js/vue.js"></script>
       <title>Title</title>
    </head>
    <body>

    <div id="box">
       <input type="text" ref="myref">

       <child ref="mychild"></child>
       <hr>
       <button @click="handleButton">点我</button>
    </div>

    </body>
    <script>
       Vue.component('child', {
           template: `
           <div>
           <input type="text" v-model="mytext">
           <hr>
           我是子组件的input
           </div>
       `,
           data() {
               return {
                   mytext: ''
              }
          },
           methods:{
               add(a){
                   console.log('我是子组件的add方法')
                   console.log(a)
                   return '返回了'
              }
          }
      })

       var vm = new Vue({
           el: '#box',
           data: {
               name: 'asdf'
          },
           methods: {
               handle(a) {
                   this.name = a
              },
               handleButton(){
                   console.log(this.$refs.mychild.mytext)
                   console.log(this.$refs.mychild.add(this.name))
              }
          }


      })


    </script>
    </html>

    6 事件总线

     不同层级的不通组件通信
    <!DOCTYPE html>
    <html lang="en">
    <head>
       <meta charset="UTF-8">
       <script src="js/vue.js"></script>
       <title>Title</title>
    </head>
    <body>

    <div id="box">

       <child1></child1>
       <hr>
       <child2></child2>

    </div>

    </body>
    <script>

       //定义一个事件总线
       var bus=new Vue()


       //组件1
       Vue.component('child1', {
           template: `
           <div>
           <input type="text" v-model="text">
           <button @click="handleClick">点我传递数据到另一个组件</button>
           </div>
       `,
           data() {
               return {
                   text: ''
              }
          },
           methods: {
               handleClick() {
                   console.log(this.text)
                   bus.$emit('suibian',this.text) //通过事件总线发送
              }
          }
      })
       //组件2
       Vue.component('child2', {
           template: `
           <div>
           收到的消息是:{{recv_text}}
           </div>
       `,
           data(){
               return {
                   recv_text:''
              }
          },
           mounted(){//组件挂载(生命周期钩子函数中的一个),开始监听事件总线上的随便
               bus.$on('suibian',(item)=>{
                   console.log('收到了',item)
                   this.recv_text=item
              })

          },
      })

       var vm = new Vue({
           el: '#box',
           data: {},

      })


    </script>
    </html>

    7 动态组件

    <!DOCTYPE html>
    <html lang="en">
    <head>
       <meta charset="UTF-8">
       <script src="js/vue.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>

    8 slot插槽

    8.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">
       <child1>
           <ul>
               <li v-for="i in 4">{{i}}</li>
           </ul>
       </child1>
       <hr>
       <child2></child2>
       <hr>
       <child3></child3>
    </div>

    </body>
    <script>

       var vm = new Vue({
           el: '#box',
           data: {
               who: 'child1'
          },
           components: {
               child1: {
                   template: `

                   <div>


                   <slot></slot>
                   <hr>
                   我是首页

                   <input type="text">

                   </div>
                   `,

              },
               child2: {
                   template: `
                   <div>我是商品 </div>
                   `,

              },
               child3: {
                   template: `
                   <div>我是订单 </div>
                   `,

              }
          }

      })


    </script>
    </html>

     

    8.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">
       <child1>
           <button @click="isShow=!isShow">点我隐藏child2</button>
       </child1>
       <hr>
       <child2 v-if="isShow"></child2>
    </div>

    </body>
    <script>

       var vm = new Vue({
           el: '#box',
           data: {
               isShow: true,
          },
           components: {
               child1: {
                   template: `

                   <div>
                   <slot></slot>
                   </div>
                   `,

              },
               child2: {
                   template: `
                   <div>
                    <ul>
                    <li v-for="i in 4">{{i}}</li>
                   </ul>
                    </div>
                   `,

              },
        }

      })


    </script>
    </html>

     

    8.3 具名插槽(指定标签放到组件的某个插槽中)

    <!DOCTYPE html>
    <html lang="en">
    <head>
       <meta charset="UTF-8">
       <script src="js/vue.js"></script>
       <title>Title</title>
    </head>
    <body>

    <div id="box">
       <child1>
           <button @click="isShow=!isShow" slot="button1">点我隐藏child2</button>

           <div slot="div1">我是div</div>
       </child1>
       <hr>
       <child2 v-if="isShow"></child2>
    </div>

    </body>
    <script>

       var vm = new Vue({
           el: '#box',
           data: {
               isShow: true,
          },
           components: {
               child1: {
                   template: `

                   <div>
                   <slot name="button1"></slot>
                   <hr>
                   我是华丽的分割线
                   <hr>
                   <slot name="div1"></slot>
                   </div>
                   `,

              },
               child2: {
                   template: `
                   <div>
                    <ul>
                    <li v-for="i in 4">{{i}}</li>
                   </ul>
                    </div>
                   `,

              },
        }

      })


    </script>
    </html>

     

  • 相关阅读:
    Redis基础知识补充及持久化、备份介绍
    Redis基础认识及常用命令使用
    Docker实战(7):Docker无日志(无*-json.log文件)
    Linux实战(11):Centos安装Jenkins
    Linux实战(13):Centos8 同步时间
    Docker实战(6): 导出docker镜像离线包
    Linux实战(13):Centos8安装FFmpeg
    Linux实战(12):解决Centos7 docker 无法自动补全
    Linux实战(11):Centos后期添加网卡配置
    Linux实战(11):配置PPPOE拨号
  • 原文地址:https://www.cnblogs.com/usherwang/p/14151645.html
Copyright © 2020-2023  润新知