Vue系列-插槽$slot

作者: 前端切克闹 | 来源:发表于2019-08-18 21:32 被阅读3次

    在Vue中,插槽slot是可以由组件使用者来自定义内容,用来做组件的扩展。

    如下,我们封装了一个列表组件
    <template>
          ul
              li(v-for="item in list")
                    span(v-html="item.text")
    </template>
    <script>
      export default{
          props:["list"]
      }
    </script>
    
    默认该组件可以让使用者传入list,遍历显示list中每个item的text值
    但是,当使用者,不仅仅用来显示text值时,组件就要求做调整
    如果不同使用者想要呈现的方式各异,我们没理由为这不同的呈现做特殊定制
    这时候插槽就派上用场,将组件改造如下
    <template>
          ul
              li(v-for="item in list")
                  slot(:item="item")  
                      span(v-html="item.text")
    </template>
    <script>
      export default{
          props:["list"]
      }
    </script>
    
    使用者就可以自定义插槽内容,如list就是我们封装好的组件
    可以显示内容项的名字
    <list><tempalte scope="props"><span v-html="props.item.name"></span></template></list>
    可以显示内容项的图片和描述
    <list>
    <tempalte scope="props">
    <div>
        <img :src="props.item.img"/>
        <span v-html="item.desc"></span>
    </div>
    </template>
    </list>
    

    要注意的是,插槽也会带来一定的问题:Vue内部检测刷新的机制中,如果组件A中包含了插槽元素,子节点之类的,父组件更新的时候,该组件A会被强制更新。
    如果组件A中render渲染比较耗时的话,要做多一层封装;

    如下(其中test是我们上面封装好的组件)
    
    <div id="app">
              <input type="text" v-model="name"/>
               <test :list="list" @hook:updated="testUpdated"><template scope="props"><span v-html="props.item.name"></span></template></test>
    </div>
    <script>
        new Vue({
            el:"#app",
            data:{
                  list:[{name:"123"},{name:"456"},{name:"789"}],
                  name:"test"
            },
            methods:{
                  testUpdated:function(){
                           console.log("d")
                  }
            }
        })
    </script>
    
    在这里,每次修改input框值,都会触发组件test的更新
    

    相关文章

      网友评论

        本文标题:Vue系列-插槽$slot

        本文链接:https://www.haomeiwen.com/subject/jmakjctx.html