赞
踩
Vue插槽是一种特殊的语法,用于在组件中定义可复用的模板部分。它允许开发者在组件的标记中声明一个或多个插槽,然后在使用该组件时,可以根据自己的需求将内容插入到这些插槽中。
Vue插槽分为默认插槽和具名插槽两种。
要在页面中显示一个对话框,封装成一个组件,组件内容能够自定义
MyDialog.vue
- <template>
- <div class="dialog">
- <div class="dialog-header">
- <h3>友情提示</h3>
- <span class="close">✖️</span>
- </div>
-
- <div class="dialog-content">
- <!-- 1. 在需要定制的位置,使用slot占位 -->
- <slot></slot>
- </div>
- <div class="dialog-footer">
- <button>取消</button>
- <button>确认</button>
- </div>
- </div>
- </template>
-
- <script>
- export default {
- data () {
- return {
-
- }
- }
- }
- </script>
-
- <style scoped>
- * {
- margin: 0;
- padding: 0;
- }
- .dialog {
- width: 470px;
- height: 230px;
- padding: 0 25px;
- background-color: #ffffff;
- margin: 40px auto;
- border-radius: 5px;
- }
- .dialog-header {
- height: 70px;
- line-height: 70px;
- font-size: 20px;
- border-bottom: 1px solid #ccc;
- position: relative;
- }
- .dialog-header .close {
- position: absolute;
- right: 0px;
- top: 0px;
- cursor: pointer;
- }
- .dialog-content {
- height: 80px;
- font-size: 18px;
- padding: 15px 0;
- }
- .dialog-footer {
- display: flex;
- justify-content: flex-end;
- }
- .dialog-footer button {
- width: 65px;
- height: 35px;
- background-color: #ffffff;
- border: 1px solid #e1e3e9;
- cursor: pointer;
- outline: none;
- margin-left: 10px;
- border-radius: 3px;
- }
- .dialog-footer button:last-child {
- background-color: #007acc;
- color: #fff;
- }
- </style>
App.vue
- <template>
- <div>
- <!-- 2. 在使用组件时,组件标签内填入内容 -->
- <MyDialog>
- <div>你确认要删除么</div>
- </MyDialog>
-
- <MyDialog>
- <p>你确认要退出么</p>
- </MyDialog>
- </div>
- </template>
-
- <script>
- import MyDialog from './components/MyDialog.vue'
- export default {
- data () {
- return {
-
- }
- },
- components: {
- MyDialog
- }
- }
- </script>
-
- <style>
- body {
- background-color: #b3b3b3;
- }
- </style>
main.js
- import Vue from 'vue'
- import App from './App.vue'
-
- Vue.config.productionTip = false
-
- new Vue({
- render: h => h(App),
- }).$mount('#app')
设置插槽默认显示内容
在<slot>标签内,放置内容,作为默认显示内容
外部使用组件时,不传内容,则会显示后备内容,否则后备内容被替换
MyDialog.vue
- <template>
- <div class="dialog">
- <div class="dialog-header">
- <h3>友情提示</h3>
- <span class="close">✖️</span>
- </div>
-
- <div class="dialog-content">
- <!-- 往slot标签内部,编写内容,可以作为后备内容(默认值) -->
- <slot>
- 我是默认的文本内容
- </slot>
- </div>
- <div class="dialog-footer">
- <button>取消</button>
- <button>确认</button>
- </div>
- </div>
- </template>
-
- <script>
- export default {
- data () {
- return {
-
- }
- }
- }
- </script>
-
- <style scoped>
- * {
- margin: 0;
- padding: 0;
- }
- .dialog {
- width: 470px;
- height: 230px;
- padding: 0 25px;
- background-color: #ffffff;
- margin: 40px auto;
- border-radius: 5px;
- }
- .dialog-header {
- height: 70px;
- line-height: 70px;
- font-size: 20px;
- border-bottom: 1px solid #ccc;
- position: relative;
- }
- .dialog-header .close {
- position: absolute;
- right: 0px;
- top: 0px;
- cursor: pointer;
- }
- .dialog-content {
- height: 80px;
- font-size: 18px;
- padding: 15px 0;
- }
- .dialog-footer {
- display: flex;
- justify-content: flex-end;
- }
- .dialog-footer button {
- width: 65px;
- height: 35px;
- background-color: #ffffff;
- border: 1px solid #e1e3e9;
- cursor: pointer;
- outline: none;
- margin-left: 10px;
- border-radius: 3px;
- }
- .dialog-footer button:last-child {
- background-color: #007acc;
- color: #fff;
- }
- </style>
App.vue
- <template>
- <div>
- <MyDialog></MyDialog>
-
- <MyDialog>
- 你确认要退出么
- </MyDialog>
- </div>
- </template>
-
- <script>
- import MyDialog from './components/MyDialog.vue'
- export default {
- data () {
- return {
-
- }
- },
- components: {
- MyDialog
- }
- }
- </script>
-
- <style>
- body {
- background-color: #b3b3b3;
- }
- </style>
main.js
- import Vue from 'vue'
- import App from './App.vue'
-
- Vue.config.productionTip = false
-
- new Vue({
- render: h => h(App),
- }).$mount('#app')
默认插槽只有一个定制位置
具名插槽支持多个定制位置
MyDialog.vue
- <template>
- <div class="dialog">
- <div class="dialog-header">
- <!-- 一旦插槽起了名字,就是具名插槽,只支持定向分发 -->
- <slot name="head"></slot>
- </div>
-
- <div class="dialog-content">
- <slot name="content"></slot>
- </div>
- <div class="dialog-footer">
- <slot name="footer"></slot>
- </div>
- </div>
- </template>
-
- <script>
- export default {
- data () {
- return {
-
- }
- }
- }
- </script>
-
- <style scoped>
- * {
- margin: 0;
- padding: 0;
- }
- .dialog {
- width: 470px;
- height: 230px;
- padding: 0 25px;
- background-color: #ffffff;
- margin: 40px auto;
- border-radius: 5px;
- }
- .dialog-header {
- height: 70px;
- line-height: 70px;
- font-size: 20px;
- border-bottom: 1px solid #ccc;
- position: relative;
- }
- .dialog-header .close {
- position: absolute;
- right: 0px;
- top: 0px;
- cursor: pointer;
- }
- .dialog-content {
- height: 80px;
- font-size: 18px;
- padding: 15px 0;
- }
- .dialog-footer {
- display: flex;
- justify-content: flex-end;
- }
- .dialog-footer button {
- width: 65px;
- height: 35px;
- background-color: #ffffff;
- border: 1px solid #e1e3e9;
- cursor: pointer;
- outline: none;
- margin-left: 10px;
- border-radius: 3px;
- }
- .dialog-footer button:last-child {
- background-color: #007acc;
- color: #fff;
- }
- </style>
App.vue
- <template>
- <div>
- <MyDialog>
- <!-- 需要通过template标签包裹需要分发的结构,包成一个整体 -->
- <template v-slot:head>
- <div>我是大标题</div>
- </template>
-
- <template v-slot:content>
- <div>我是内容</div>
- </template>
-
- <template #footer>
- <button>取消</button>
- <button>确认</button>
- </template>
- </MyDialog>
- </div>
- </template>
-
- <script>
- import MyDialog from './components/MyDialog.vue'
- export default {
- data () {
- return {
-
- }
- },
- components: {
- MyDialog
- }
- }
- </script>
-
- <style>
- body {
- background-color: #b3b3b3;
- }
- </style>
main.js
- import Vue from 'vue'
- import App from './App.vue'
-
- Vue.config.productionTip = false
-
- new Vue({
- render: h => h(App),
- }).$mount('#app')
给插槽绑定数据
封装表格组件
MyTable.vue
- <template>
- <table class="my-table">
- <thead>
- <tr>
- <th>序号</th>
- <th>姓名</th>
- <th>年纪</th>
- <th>操作</th>
- </tr>
- </thead>
- <tbody>
- <tr v-for="(item, index) in data" :key="item.id">
- <td>{{ index + 1 }}</td>
- <td>{{ item.name }}</td>
- <td>{{ item.age }}</td>
- <td>
- <!-- 1. 给slot标签,添加属性的方式传值 -->
- <slot :row="item" msg="测试文本"></slot>
-
- <!-- 2. 将所有的属性,添加到一个对象中 -->
- <!--
- {
- row: { id: 2, name: '孙大明', age: 19 },
- msg: '测试文本'
- }
- -->
- </td>
- </tr>
- </tbody>
- </table>
- </template>
-
- <script>
- export default {
- props: {
- data: Array
- }
- }
- </script>
-
- <style scoped>
- .my-table {
- width: 450px;
- text-align: center;
- border: 1px solid #ccc;
- font-size: 24px;
- margin: 30px auto;
- }
- .my-table thead {
- background-color: #1f74ff;
- color: #fff;
- }
- .my-table thead th {
- font-weight: normal;
- }
- .my-table thead tr {
- line-height: 40px;
- }
- .my-table th,
- .my-table td {
- border-bottom: 1px solid #ccc;
- border-right: 1px solid #ccc;
- }
- .my-table td:last-child {
- border-right: none;
- }
- .my-table tr:last-child td {
- border-bottom: none;
- }
- .my-table button {
- width: 65px;
- height: 35px;
- font-size: 18px;
- border: 1px solid #ccc;
- outline: none;
- border-radius: 3px;
- cursor: pointer;
- background-color: #ffffff;
- margin-left: 5px;
- }
- </style>
App.vue
- <template>
- <div>
- <MyTable :data="list">
- <!-- 3. 通过template #插槽名="变量名" 接收 -->
- <template #default="obj">
- <button @click="del(obj.row.id)">
- 删除
- </button>
- </template>
- </MyTable>
-
- <MyTable :data="list2">
- <template #default="{ row }">
- <button @click="show(row)">查看</button>
- </template>
- </MyTable>
- </div>
- </template>
-
- <script>
- import MyTable from './components/MyTable.vue'
- export default {
- data () {
- return {
- list: [
- { id: 1, name: '张小花', age: 18 },
- { id: 2, name: '孙大明', age: 19 },
- { id: 3, name: '刘德忠', age: 17 },
- ],
- list2: [
- { id: 1, name: '赵小云', age: 18 },
- { id: 2, name: '刘蓓蓓', age: 19 },
- { id: 3, name: '姜肖泰', age: 17 },
- ]
- }
- },
- methods: {
- del (id) {
- this.list = this.list.filter(item => item.id !== id)
- },
- show (row) {
- // console.log(row);
- alert(`姓名:${row.name}; 年纪:${row.age}`)
- }
- },
- components: {
- MyTable
- }
- }
- </script>
main.js
- import Vue from 'vue'
- import App from './App.vue'
-
- Vue.config.productionTip = false
-
- new Vue({
- render: h => h(App),
- }).$mount('#app')
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。