文章目录
一 插槽的简单用法
1.1 用处和用法
当自定义组件没有slot
元素的时候,则该标签开始至结束之间的全部内容都会被丢弃。
当使用插槽slot
的时候,插槽内可以包含任意内容,包括HTML
,如:
<div id="app">
<my_div>
input:
<input type="button" value="按钮">
</my_div>
</div>
new Vue({
el: '#app',
components: {
my_div: {
template: `
<div>
<slot></slot>
</div>
`
}
}
})
1.2 编译作用域
重要:VUE的作用域应该好好整理下
插槽不在标签作用域的范围内,比如这里的{{message}}
就没有用,VUE
会报错
[Vue warn]: Property or method “message” is not defined on the instance but referenced during render.
<div id="app">
<my_div message="你好哇,李银河">
author:{{message}}{{author}}
<input @click='display_alert' type="button" value="按钮">
</my_div>
</div>
而定义在VUE
实例中的属性则可以使用(和native html
一样)
new Vue({
el: '#app',
data: {
author: "王小波"
},
methods:{
display_alert:function(){
alert("Dont worry! Be Happy!")
}
},
components: {
my_div: {
props: {
message: {
type: String
}
},
template: `
<div>
{{message}}<br>
<slot></slot>
</div>
`
}
}
})
1.3 使用默认内容
对于自定义组件my_button
来说,在html
中,若不定义插槽,则显示“默认内容”:
<div id="app">
<my_button></my_button>
</div>
若提供内容,则替换
<div id="app">
<my_button>世说新语</my_button>
</div>
new Vue({
el: '#app',
components: {
my_button: {
methods: {
display_alert: function () {
alert("DONT WORRY! BE HAPPY!!")
}
},
template: `
<button type = "submit" @click='display_alert'>
<slot>默认内容</slot>
</button>
`
}
}
})
二 具名插槽
通过<slot name="xxx"><slot>
的方式来定义一个具名插槽
通过<template v-slot:xxx></template>
的方式来使用具名插槽,效果如下:.html
<div id=app>
<base_layout>
<template v-slot:header>
标题,在组件中定义好了格式
</template>
这一部分是段落内容<br>
不需要使用`template v-slot`来定义<br>
<template v-slot:contact>
<a href="mailto:someone@example.com">someone@example.com</a>
</template>
</base_layout>
</div>
自定义组件的内容:
<div class="container">
<header>
<h1><slot name="header"></slot></h1>
</header>
<main>
<slot></slot>
<br>
</main>
<footer>
联系方式部分:
<slot name="contact"></slot>
</footer>
</div>
三 作用域插槽
在1.2
中提到插槽的编译作用域提到:插槽内容是不能访问子组件数据的。那要怎么才能用到呢?
作用域插槽需要具名插槽的帮助:
- 通过
v-solt:插槽名="prop对象集合名"
- 用prop对象集合名调用
某一个prop
- 在模板中通过
<slot v-bind:obj="object" :da="date"></slot>
绑定将子组件的一个属性和父组件prop绑定
<div id="app">
<my_greet date="星期一" object="王小波">
<template v-slot:default="test">
{{test.da}}的{{test.obj}}
</template>
</my_greet>
</div>
new Vue({
el: '#app',
components: {
my_greet: {
props: ['date','object'],
template: `
<div>
你好,
<slot v-bind:obj="object" :da="date"></slot>
</div>
`
}
}
})
3.1 解构插槽Prop(?)
教程
什么是解构?
四 动态插槽名(?)
动态参数一节的教程
疑问:使用dynamicSlotName
的时候,使用什么呢?试了直接用dynamicSlotName.xxx
会报错?因为可能不怎么用这个功能,所以就先跳过了。
<template v-slot:[dynamicSlotName]>
...
</template>
五 缩写
5.1 具名插槽的缩写
(v-slot:)
替换为字符 #
。例如 v-slot:header
可以被重写为 #header
5.2 默认插槽的缩写
<current-user v-slot:default="slotProps">
{{ slotProps.user.firstName }}
</current-user>
缩写为:
<current-user v-slot="slotProps">
{{ slotProps.user.firstName }}
</current-user>
六 示例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id=app>
<todo_list v-bind:todos="todos">
<template #default="props">
<span v-if="props.todo.isComplete">✓</span>
{{ props.todo.text }}
</template>
</todo_list>
</div>
<script type="text/javascript">
new Vue({
el: '#app',
data:{
todos:[
{id:1, text:"内容一", isComplete:false},
{id:2, text:"内容二", isComplete:false},
{id:3, text:"内容三", isComplete:true}
]
},
components: {
todo_list: {
props:['todos'],
template: `
<ul>
<li
v-for="todo in todos"
v-bind:key="todo.id"
>
<slot :todo="todo">
{{ todo.text }}
</slot>
</li>
</ul>
`
}
}
})
</script>
</body>
</html>
官方文档无法查看效果的问题在于:
文档中应该是v-if="todo.todo.isCompletet"
和{{todo.todo.text}}
<todo-list v-bind:todos="todos">
<template v-slot:todo="{ todo }">
<span v-if="todo.isComplete">✓</span>
{{ todo.text }}
</template>
</todo-list>
#疑问
1. 页面渲染的详细、具体过程
比如这一段话:
然而上述代码不会正常工作,因为只有
<current-user>
组件可以访问到user
而我们提供的内容是在父级渲染的。
什么是父级渲染?
来源:CSDN
作者:Wby_Nju
链接:https://blog.csdn.net/Wby_Nju/article/details/104405874