zoukankan      html  css  js  c++  java
  • 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>

     

  • 相关阅读:
    联想 Vibe Shot(Z90-3) 免recovery 获取ROOT权限 救砖 VIBEUI V3.1_1625
    联想 Z5S(L78071)免解锁BL 免rec 保留数据 ROOT Magisk Xposed 救砖 ZUI 10.5.370
    联想 Z5(L78011) 免解锁BL 免rec 保留数据 ROOT Magisk Xposed 救砖 ZUI 10.5.254
    联想 S5 Pro(L78041)免解锁BL 免rec 保留数据 ROOT Magisk Xposed 救砖 ZUI 5.0.123
    第二阶段 冲刺八
    第二阶段 冲刺七
    第二阶段 冲刺六
    第二阶段 冲刺五
    代码大全阅读笔记03
    学习进度十二
  • 原文地址:https://www.cnblogs.com/usherwang/p/14151645.html
Copyright © 2011-2022 走看看