这是一篇学习笔记

.父子组件传值

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>父子组件传值</title>
    <style> 
    </style>
    <script src="./vue.js"></script>
</head>
<body>
    <div id="root">  
        <counter :count="0" @numberchange="handleChange"></counter>
        <counter :count="0" @numberchange="handleChange"></counter>
        <div>{{total}}</div> 
        <validate-content content="hello world"></validate-content>
    </div>
    <script> 

      //父组件向子组件传值用 props ,加:号后传递的为js表达式,示例中则为数字,不加:号代表的是字符串 
      var counter = { //局部注册 
         props:['count'],

         data:function(){//在子组件中定义数据,data不能是对象,必须是一个函数。
             return {
                 number:this.count
             }
         },
         template:'<div @click="handleClick2">{{number}}</div>',
         methods:{
            handleClick2:function(){
                this.number ++;
                //this.count++; 父组件可以传值给子组件,但子组件不可以修改父组件属性,这里这么写会报错。
                this.$emit("numberchange",this.number);//子组件向父组件传递事件,值
            }
        } 
      }

      var validateContent = {
        props:{
           //content:[Number,String] //组件参数校验,可以多选
            content:{//组件参数校验
                type:String,
                required:true,
                default:"default value",
                validator:function(value){
                    return value.length > 5
                }
            }
         },
         template:'<div >{{content}}</div>',
      }

      var vm = new Vue({
          el:'#root',
          data:{
             total:0
          },
          methods:{ 
            handleChange:function(number){ 
                console.log(number)
               // this.total +=1;
            }
          },
          components:{
             counter,  //局部注册要在根节点注册组件
             validateContent
          }
      })
    </script>
</body>
</html>

.父组件向子组件传递DOM
先看一个示例

<body>
    <div id="root">  
       <child><p>Qin</p></child>
    </div>
    <script>  
      let child = {
          template :`<div>
                     <p>hello world</p> 
               </div>`
      }
      var vm = new Vue({
          el:'#root',
          components:{
              child
          } 
      })
    </script>
</body>

打开查看器查看一下
这里写图片描述

发现Qin不见了

<p>Qin</p>

查看官方文档 ,https://cn.vuejs.org/v2/guide/components-slots.html
我们得出结论:如果 child 没有包含一个 < slot > 元素,则任何传入它的内容都会被抛弃
我们加入插槽

<body>
    <div id="root">  
       <child><p>Qin</p></child>
    </div>
    <script>  
      let child = {
          template :`<div>
                     <p>hello world</p>
                     <slot></slot>
               </div>` 
      }
      var vm = new Vue({
          el:'#root',
          components:{
              child
          } 
      })
    </script>
</body>

发现Qin能正常显示,且slot将会被替换为解析后的片段 < p > Qin < /p >
这里写图片描述

当父组件不向子组件传值的时候,slot还可以作为父组件默认值出现

<body>
    <div id="root">  
       <child></child>
    </div>
    <script>  
      let child = {
          template :`<div>
                     <p>hello world</p>
                     <slot>default value</slot>
               </div>`
      }
      var vm = new Vue({
          el:'#root',
          components:{
              child
          } 
      })
    </script>
</body>

效果图

具名插槽
如果想使用多个插槽,我们先看看效果:

<body>
    <div id="root">  
       <child>
           <header>This is header</header>
           <footer>This is footer</footer> 
       </child>
    </div>
    <script>  
      let child = {
          template :
              `<div>  
                     <slot></slot>
                     <p>Main content</p>
                     <slot></slot>
               </div>`
      }
      var vm = new Vue({
          el:'#root',
          components:{
              child
          } 
      })
    </script>
</body>

这里写图片描述

发现出现了多个header和footer,要解决这个问题就要用到具名插槽
我们修改代码如下:

<body>
    <div id="root">  
       <child>
           <header slot="header">This is header</header>
           <footer slot="footer">This is footer</footer> 
       </child>
    </div>
    <script>  
      let child = {
          template :
              `<div>  
                     <slot name="header"></slot>
                     <p>Main content</p>
                     <slot name="footer"></slot>
               </div>`
      }
      var vm = new Vue({
          el:'#root',
          components:{
              child
          } 
      })
    </script>
</body>

这里写图片描述
可以看到显示正常了

Logo

前往低代码交流专区

更多推荐