ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
## 一:插槽内容 **插槽是指把任意内容插入指定的位置,而这个位置使用`<slot>`作为占位符。** ``` //父组件中 <navigation-link url="/profile"> Your Profile </navigation-link> ``` ``` //navigation-link组件 <a v-bind:href="url"class="nav-link"> <slot></slot> /`Your Profile`被渲染到这里 </a> ``` 当组件渲染的时候,`<slot></slot>`将会被替换为“Your Profile”。插槽内可以包含任何模板代码包括 `HTM`: ``` <navigation-link url="/profile"> // 添加一个 Font Awesome 图标 <span class="fa fa-user"></span> Your Profile </navigation-link> ``` > 如果`<navigation-link>`组件**没有**定义插槽,则`<navigation-link>`中的内容将不会被渲染。 ## 二:编译作用域 当你想在一个插槽中使用数据时,例如: ~~~ <child > <p>{{name}}</p> //name是父级的数据,会被编译为'Jack'并传递给子组件中的插槽 //但是在这里无法访问子组件的数据,想要访问子组件的数据需要使用作用域插槽:slot-scope,新语法为v-slot </child> export default { data () { return { name: 'Jack' } } } ~~~ 子组件中: ``` <template> <div class="slottwo"> <slot></slot> //会渲染出Jack </div> </template> ``` >[info] 父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。 ## 三:默认内容 **在插槽中设置默认内容**: ``` <button type="submit"> <slot>Submit</slot> //插槽中默认有Submit字符 </button> ``` 如果没有使用插槽,则默认会渲染出`Submit`: ``` <submit-button></submit-button> ``` 默认渲染`Submit`字符: ``` <button type="submit"> Submit </button> ``` ## 三:具名插槽 **具名插槽就是给插槽定义一个名字即name属性,这样当有多个插槽时可以把指定的内容插入到指定的插槽中。** `base-layout`组件: ``` <div class="container"> <header> <slot name="header"></slot> </header> <main> <slot></slot> </main> <footer> <slot name="footer"></slot> </footer> </div> ``` > 一个不带`name`的`<slot>`出口会带有隐含的名字“default”。 ``` <base-layout> <template v-slot:header> //插入到name为header的插槽中 <h1>Here might be a page title</h1> </template> <p>A paragraph for the main content.</p> //插入到默认插槽中 <p>And another one.</p> <template v-slot:footer>//插入到name为footer的插槽中 <p>Here's some contact info</p> </template> </base-layout> ``` **具名插槽的缩写:** ``` <base-layout> <template #header>//等价v-slot:header <h1>Here might be a page title</h1> </template> <p>A paragraph for the main content.</p>//等价v-slot:default <p>And another one.</p> <template #footer>//等价v-slot:footer <p>Here's some contact info</p> </template> </base-layout> ``` ## 四: [作用域插槽](https://cn.vuejs.org/v2/guide/components-slots.html#%E4%BD%9C%E7%94%A8%E5%9F%9F%E6%8F%92%E6%A7%BD "作用域插槽") **作用域插槽是用来获取子组件的数据。** 例如`<current-user>`组件: ~~~ <span> <slot>{{ user.lastName }}</slot> </span> export default { data () { return { user:{lastName :'Jack'} } } } ~~~ **当父组件想要使用`user`数据,就需要使用作用域插槽。在插槽中绑定属性传递数据,然后在父组件中使用`slot-scope`(即将废弃)或者使用`v-slot:default`接收数据** 1.在子组件中绑定属性: ``` <span> <slot :user="user"> //绑定属性传递数据 {{ user.lastName }} </slot> </span> export default { data () { return { user:{lastName :'Jack'} } } } ``` 2.在父组件中接收数据: ``` <current-user> <template v-slot:default="slotProps"> //也可以使用slot-scope="slotProps",vue3.0将不支持此语法 {{ slotProps.user.firstName }} //变量名随便起,此处slotProps变量代表user数据 </template> </current-user> ``` **独占默认插槽的缩写语法** >[danger] 当子组件只**提供默认插槽**时,就可以使用作用域插槽缩写的形式,如果提供了具名插槽就无法使用缩写形式。 ``` <current-user v-slot="slotProps">//此处的v-slot="slotProps"是作用域插槽的缩写 {{ slotProps.user.firstName }} </current-user> ``` **如果存在具名插槽无法使用缩写形式** ## 五:作用域插槽的解构赋值 `child`组件中,传递一个user对象: ``` <span> <slot :user="user"> //绑定属性传递数据 {{ user.name }} </slot> </span> export default { data () { return { user:{name:'张三',age:18} } } } ``` 父组件中: ``` <template v-slot:default="slotProps"> {{ slotProps }} //{ user:{ "name": "张三", "age": 18 }} </template> ``` 有时候我们只需要值`{ "name": "张三", "age": 18 }`,而不需要键名`user`,则可以使用对象的解构赋值。 ``` //等价于 let {user:user} = { user:{ "name": "张三", "age": 18 }} <template v-slot:default="{ user }"> {{ user}} //{ "name": "张三", "age": 18 } </template> ```