组件通信的黑魔法v-model和动态组件component以及组件插槽slot

组件通信 v-model

  • v-model 是form表单dom专用的, 用来实现双向绑定数据, 可以分成一个@input和一个:value
  • 在组件中使用v-model 然后在组件的props中定义一个value属性用来接收,
  • 传递出去的时候, 就是一个 子传父的案例, 使用this.$emit分发给一个叫input的, 这个input是与value配对的, 这样组件上的v-model就可以接收到input中的值
  • 代码示例:
<body>
    <div id="box">
        <child-input type="text" title="账号" v-model="username"></child-input>
        <child-input type="password" title="密码" v-model="password"></child-input>
        <child-input type="number" title="手机号" v-model="number"></child-input>

        <button @click="handleClick">提交</button>
    </div>
    <!-- v-model 可以分成一个 @input :value  -->
    <script>
        Vue.component("childInput",{
     
        
            props:["type","title", "value"],  // value 为v-model中拆分出来的
            template:`
            <div>   
              <label>{
      
      { title }}</label>
              <input :type="type" style=background:red @input="handleInput" :value="value"/>
            </div>
            `,
            methods:{
     
     
                handleInput(evt){
     
       // 在input标签中,发现有内容变化就会触发,
                    this.$emit("input", evt.target.value )   // 分发给 input  这个input是v-model拆分出来的,固定用法, 与属性 value 为一对
                }
            }
        })
        new Vue({
     
     
            el:"#box",
            data:{
     
     
                username:"abc",
                password:123456,
                number:15555555555
            },
            methods:{
     
     
                handleClick(){
     
     
                    console.log(this.username,this.password,this.number)
                }
            }
        }) 
    </script>
</body>

动态组件

  • 动态组件, 其实就是通过某些值的变化, 来显示指定的组件
  • 不使用component, 使用也是可以实现的,
    用法:
<component :is="组件名"></component>

在这component标签里 is 属性指定哪个组件名就显示哪个组件

代码示例: 通过点击3个按钮显示不同的组件

<body>
    <div id="box">
        <!-- keep-alive 是让组件一直存在, 不至于切换组件后被重新渲染 -->
        <keep-alive>  
            <!-- component  is 元素指定哪一个组件就显示那个组件-->
            <component :is="isWhich"></component>
        </keep-alive>
        <br><hr> 
        <button @click=" isWhich='home' ">首页</button>
        <button @click=" isWhich='list' ">List</button>
        <button @click=" isWhich='cat' ">Cat</button>
    </div>
</body>
    <script>
        Vue.component("home",{
     
     
            template:`
            <div>首页</div>
            `
        })
        Vue.component("list",{
     
     
            template:`
            <div>list
                <input type="text">
            </div>
            `
        })
        Vue.component("cat",{
     
     
            template:`
            <div>cat</div>
            `
        })
        new Vue({
     
     
            el:"#box",
            data:{
     
     
                isWhich:"home"
            }
        })
    </script>

keep-alive 使组件一直存活

  • 上面动态组件的代码中有一个组件内有一输入框, 当我们切换组件的时候, 输入框的内容会直接被清空, 其实这不是清空, 而是vue直接把组件删除了, 重新创建出新的
  • 而使用keep-alive 后, 组件就会一直存活, 切换组件的时候不会被vue所删除,以保存输入框的内容
		 <!-- keep-alive 是让组件一直存在, 不至于切换组件后被重新渲染 -->
        <keep-alive>  
            <!-- component  is 元素指定哪一个组件就显示那个组件-->
            <component :is="isWhich"></component>
        </keep-alive>

插槽slot

  • 学到现在了, 组件也会用啦, 感觉这组件使用起来和html标签差不多, 那么能不能就在这个所谓的组件标签中间加上一些html标签,

  • 就像是这样

  •       <child>       <!--   child 为组件 -->
              <div> 我是html的div标签 </div>
          </child>
    
  • 可以是可以, 不过要在组件内的模板中加上<slot></slot> 用来占位, 创建一个插槽, 这样就会把组件中的 html标签插入到这个插槽中

  • 如果有多个呢, 需要指定插槽位置的呢, 也是可以的, 在html标签中指定slot=b然后在组件模板中的<slot name=b></slot>加上 name=b,这样就可插入到指定的插槽中

代码示例:

<body>
    <div id="box">
        <home>
            <h1 slot=b>BBBBBBBBBBBB</h1>
            <h1 slot=a>AAAAAAAAAAAA</h1>
        </home>
    </div>
</body>
    <script>
        Vue.component("home",{
     
     
            template:`
            <div>
                <slot name=a></slot>
                首页
                <slot name=b></slot>
            </div>
            `
        })
        new Vue({
     
     
            el:"#box",
            data:{
     
     
                isWhich:"home"
            }
        })
    </script>

使用组件时就像是使用HTML的双标签, 当要在这个组件标签中间加上其他的HTML标签,直接加上是不行的, 因为vue解析的时候回默认删除掉, 但是可以在组件的模板中加上创建一个插槽, 这样就会把组件标签之间存在的html标签插入到这个slot插槽中,
当使用多个插槽时或者指定插槽时可以使用name属性

猜你喜欢

转载自blog.csdn.net/lxb_wyf/article/details/111803852