vue2中对插槽的介绍,花了大量的章节篇幅,可想而知,它在框架中的重要性。 slot
及slot-scope
自 2.6.0 起被废弃。新推荐的语法请查阅v-slot
,就语法我们这里就一笔带过,主要学习新的语法
你不能不知道的slot知识点
插槽的作用,主要是实现内容分发。文字描述很抽象,我们看代码
- 示例1 -
普通用法
/**
* 注册一个全局组件* */
Vue.component("alert-box", {template: `<div class="demo-alert-box"><strong>Error!</strong><slot><strong>Something went wrong</strong></slot></div>`,
});
使用方法
<alert-box>this is a alert box.</alert-box><alert-box></alert-box>
- 示例2 -
编译作用域
/**** @name 默认插槽* */
Vue.component("navigation-link", {props: ["url"],template: `<a :href="url"class="nav-link"><slot></slot></a>`,
});
<navigation-link url="https://www.baidu.com">Clicking here will send you
</navigation-link>
此时,在组件里面是可以访问这个url
属性,但是在父级组件中是无法使用url
属性的,像下面这样会报错
<navigation-link url="https://www.baidu.com">Clicking here will send you to: {{ url }} Baidu<!-- Clicking here will send you -->
</navigation-link>
- 后备内容
这个比较简单,不用过多说了
<v-button>Click me</v-button><v-button></v-button>
Vue.component("v-button", {template: `<button><slot>submit</slot></button>`,
});
具名插槽
/**
** @name 具名插槽** */Vue.component("base-layout", {template: `<div class="container"><header><slot name="header"></slot></header><main><slot></slot></main><footer><slot name="footer"></slot></footer></div>`,
});
使用方式
<base-layout><template v-slot:header><h2>这是头部标题</h2></template><p>A paragraph for the main content.</p><p>And another one.</p><template v-slot:footer><h3>Here's some contact info</h3></template>
</base-layout>
作用域插槽
自 2.6.0 起有所更新。已废弃的使用 slot-scope attribute 的语法
- 让插槽访问子组件作用域内的数据,有时候也是存在这个需求的
Vue.component("current-user", {template: `<span><slot>{{ user.lastName }}</slot></span>`,data() {return {user: {firstName: "zhang",lastName: "sanfeng",},};},
});
这里,页面会显示sanfeng
但是,如果我要显示的firstName
那该怎么处理,下面这样写,是不会生效的,因为user
在父级组件中找不到,也方访问不到子组件内的user
<current-user>{{ user.firstName }}
</current-user>
解决上面的需求,我们要进行这样的改写,
Vue.component("current-user", {template: `<span><slot :user="user">{{ user.lastName }}</slot></span>`,data() {return {user: {firstName: "zhang",lastName: "sanfeng",},};},
});
注意: <slot :user="user"> {{ user.lastName }} </slot>
这里要给slot绑定一个prop,被称为插槽 prop
<current-user><template v-slot="slotProps">{{ slotProps.user.lastName }}</template>
</current-user>
这样,我们实现了在父组件中,读取子组件内部属性的需求。
- 代码优化
- 属性简写,v-slot 直接#default
<current-user><template #default="slotProps">{{ slotProps.user.firstName }}</template>
</current-user>
- slotProps可以结构
<current-user><template #default="{ user }">{{ user.firstName }}</template>
</current-user>
- 如果子组件内只有一个插槽,默认插槽,
独占默认插槽的缩写语法
,在上述情况下,当被提供的内容只有默认插槽时,组件的标签才可以被当作插槽的模板来使用。这样我们就可以把 v-slot 直接用在组件上:
<current-user #default="{ user }">{{ user.firstName }} -- simple-mode
</current-user>
自定义渲染的html标签
<!-- 自定义渲染的html标签 -->
<goods-lists #default="{item}" :lists="lists"><span> {{ item.name }} </span>
</goods-lists>
<goods-lists #default="{item}" :lists="lists"><li>{{ item.name }}</li>
</goods-lists>
Vue.component("goods-lists", {props: {lists: {type: Array,default() {return [];},},},template: `<div><template v-for="item in lists"><slot :item="item"></slot></template></div>`,
});
这样,我们根据业务需要,来渲染不同的html元素。在组件封装的时候,很实用。