zoukankan      html  css  js  c++  java
  • Vuejs之Component slot 插槽详解

    Vuejs的component的数据进行了沙箱隔离,除js全局变量如Math, Date之类外无法访问用户自定义的变量,所以使用component写组件或嵌套组件时明白变量的访问非常重要

    编译作用域

    在看componnent的使用之前,来看下component编译作用域,明白作用域范围才能顺利写出想要的组件

    假设我们有一个组件child-component,在父组件中代码如下:

    <child-component>
      {{ message }}
    </child-component>

    编译时message的作用域应该是父组件还是子组件呢,答案是父组件

    父组件模板的内容在父组件作用域内编译;子组件模板的内容在子组件作用域内编译

    Vue.component('child-component', {
      // 有效,因为是在正确的作用域内
      template: '<div v-show="someChildProperty">Child</div>',
      data: function () {
        return {
          someChildProperty: true
        }
      }
    })

    slot在component中有单slot,具名slot和作用域slot之分,先来看看最简单的单slot应用

    单个slot

    直接上代码,其中的name字段会在父组件中初始化并赋值

    父组件
    <div id="test">
    <test-slot>
          <h3>{{name}}</h3>
          <p>Something bad happened.</p>
    </test-slot>
    </div>

    组件 Vue.component("test-slot",{ // 插槽允许有默认内容 template: `<div> <strong>Error!</strong> <slot></slot> </div> `, data:function () { return { name:"perry" } } }); new Vue({ el:"#test" data:{name:"500 error"} }); 结果: <div> <strong>Error!</strong> <h3>500 error</h3> <p>Something bad happened.</p> </div>

    具名slot

    具名插槽比较有意思,在模板制定时非常好用,比如我们要写一个模板包含头尾和内容部分,希望在模板中定义好一部分公共的东西

     具名slot通过name来管理多个slot的解析,其中没有name的slot会被归为default slot放到没有name的节点下面,default slot会无视散落在不同地方的html的位置,都将放到default slot的

    模板位置中来

    Vue.component("slot-name",{
               template:
                   `<div>
                          <header>
                                <slot name="header"></slot>
                          </header>
                         <main>
                            <slot ></slot>
                         </main>
                         <footer>
                            <slot name="footer"></slot>
                         </footer>
     
                    </div>
                   `
    });
    
    <slot-name>
           <h3>开始</h3>
        <p>Default slot内容1</p> <template slot="header"> <ul> <li>主页</li> <li>分诊</li> <li>护理</li> <li>病历</li> </ul> </template> <template slot="footer"> <p>结尾</p> </template> </slot-name>

    运行结果:

     作用域slot

     作用域插槽在解决需要动态生成字符串模板时非常有用,特别针对控件编写者

    例如实现一个简单的datagrid控件,控件在页面component中相当于子控件,使用者希望只关注表头和每行数据业务上,直接上代码

    控件代码
    Vue.component("datagrid",{
                props:{
                    data:null
                },
                template:`
                   <table>
                        <thead>
                            <slot name="headslot"></slot>
                        </thead>
                        <tbody>
                            <tr  v-for="item in data">
                                <slot name="bodyslot" :item="item">{{item.text}</slot>
                            </tr>
                       </tbody>
                   </table>
               `
     });
    
    
    在父组件中(页面上)使用如下:
    <datagrid :data="todos">
           <template slot="headslot">
                  <tr>
                        <td>id</td>
                         <td>text</td>
                         <td>isTrue</td>
                   </tr>
           </template>
          <template slot="bodyslot" slot-scope="{item}">
                        <td>{{item.id}}</td>
                        <td>{{item.text}}</td>
                        <td>{{item.isTrue}}</td>
          </template>
    </datagrid>

    如上代码,简单的datagrid就实现了,在父组件中只需要在head中指定table的head具体内容,对应的body中tr的每个td的字段绑定,其它交给控件处理

    其中数据源是datagrid中的data属性,与slot通信是通过slot-scope来实现数据域传递,这点非常关键

    控件中 :item="item" 与父组件slot-scope="{item}" 完成数据访问的传递,其中slot-scope="{item}"语句也可以通过"slot-scope="slotProps"来实现数据传递,slotProps对像相当于当slot对象上

    所有props属性的根,通过slotProps对象都能访问到

    在js调用如下:

    var vm = new Vue({
                    el:"#app",
                    data:{
                        todos:[
                            {text:"A",id:1,isTrue:true},
                            {text:"B",id:2,isTrue:true},
                            {text:"C",id:3,isTrue:false},
                            {text:"D",id:4,isTrue:true},
                        ]
                    }
                }); 

    在data中的todos属性已经与页面的table形成了关联,只要todos属性发生变化,页面的table会自动更新tbody中的数据行,这就是数据驱动的精髓

  • 相关阅读:
    在nginx环境下搭建基于ssl证书的websocket服务转发,wss
    在nginx环境下搭建https服务,代理到本地web项目
    java CountDownLatch报错java.lang.IllegalMonitorStateException: null
    https本地自签名证书添加到信任证书访问
    10013: An attempt was made to access a socket in a way forbidden by its access permissions
    chrome 报错 ERR_CERT_AUTHORITY_INVALID
    SDKMAN一个基于命令行界面的SDK用户环境管理程序
    springboot放到linux启动报错:The temporary upload location [/tmp/tomcat.8524616412347407692.8111/work/Tomcat/localhost/ROOT/asset] is not valid
    netty-websocket-spring-boot-starter关闭报错 io/netty/channel/AbstractChannel$AbstractUnsafe io/netty/util/concurrent/GlobalEventExecutor
    HTML DOM addEventListener() 方法
  • 原文地址:https://www.cnblogs.com/johnx/p/9777099.html
Copyright © 2011-2022 走看看