Table of contents
Three, render rendering function
1. Slot
Slots can be divided into default slots, named slots (slots with a name), and scoped slots. Slots allow us to pass templates for subcomponents when calling them.
1. Default slot
A slot without a name is the default slot, and a <slot> outlet without a name will have the implicit name "default".
<slot></slot>
或者
<slot name="default"></slot>
The content inside the component tag will be rendered to the default slot:
<body>
<div id="app">
<!-- 组件标签里面的内容需要使用插槽来接收,否则无法渲染出来,
而里面的内容会默认渲染到默认插槽中 -->
<my-a>hello vue</my-a>
</div>
<script>
// 定义组件
let myA={
template:`
<div>
<p>1111111</p>
<slot></slot>
<slot></slot>
<p>3333333</p>
</div>
`
}
new Vue({
el:"#app",
//局部注册组件
components:{
"my-a":myA
}
})
</script>
</body>
The result is as follows:
2. Named slot
A slot with a name is a named slot.
When we need to render the corresponding content in the component tag to the corresponding slot, we use the named slot. At this time, we need to use the template template in the component tag:
<slot name='header'></slot>
<template v-slot:header>头部内容</template>
<body>
<div id="app">
<my-a>
<!-- 使用 v-slot:插槽名 ,这样就可以把相应内容放到相应插槽中 -->
<template v-slot:footer>底部内容</template>
<!-- default 表示默认插槽 -->
<template v-slot:default>hello vue</template>
<template v-slot:center>中间内容</template>
<!-- <template v-slot:header>头部内容</template> -->
<!-- v-slot: 可以简写成 # -->
<template #header>头部内容</template>
</my-a>
</div>
<script>
// 定义组件
let myA={
template:`
<div>
<p>1111111</p>
<slot></slot>
<slot></slot>
<p>3333333</p>
<hr/>
<slot name='header'></slot>
<slot name='center'></slot>
<slot name='footer'></slot>
</div>
`
}
new Vue({
el:"#app",
components:{
"my-a":myA
}
})
</script>
</body>
The result is as follows:
3. Scope slots
We use slots to pass data in subcomponents, and the passed data needs to be obtained using scoped slots in component tags.
<slot :row='item'></slot>
<template slot-scope="scope">{
{scope}}</template>
<body>
<div id="app">
<!-- 父组件给子组件传递数据 :arr="arrs" -->
<my-a :arr="arrs">
<!-- v-slot对应插槽的name,这样就可以把相应内容放到相应插槽中 -->
<template v-slot:footer>底部内容</template>
<div>hello vue</div>
<template v-slot:center>中间内容</template>
<!-- <template v-slot:header>头部内容</template> -->
<!-- v-slot: 可以简写成 # -->
<template #header>头部内容</template>
<!-- 作用域插槽 slot-scope="变量" 该变量用于接收数据-->
<template slot-scope="scope">
{
{scope}}
</template>
</my-a>
</div>
<script>
// 定义组件
let myA={
// 接收父组件传递过来的数据
props:['arr'],
template:`
<div>
<p>1111111</p>
<slot></slot>
<slot></slot>
<p>3333333</p>
<hr/>
<slot name='header'></slot>
<slot name='center'></slot>
<slot name='footer'></slot>
<hr/>
<ul>
<li v-for='item in arr'>
<slot :row='item'></slot>
</li>
</ul>
</div>
`
}
new Vue({
el:"#app",
data:{
arrs:[
{id:1,name:'zhangsan'},
{id:1,name:'lisi'},
{id:1,name:'wangwu'},
]
},
components:{
"my-a":myA
}
})
</script>
</body>
The result is as follows:
As you can see, the "hello vue" of the default slot is not rendered, because the scope slot has no name, so it is also a default slot. The scope slot will overwrite the previous default slot content. The solution is to add a name to the scope slot:
<slot name="content" :row='item'></slot>
<!-- v-slot:插槽名字="变量" -->
<template v-slot:content="scope">{
{scope}}</template>
2. Custom commands
Most commands in Vue are called with v-. However, sometimes the instructions provided by Vue do not meet our needs, and at this time we need custom instructions.
Directives allow us to perform low-level operations on ordinary DOM elements. It can be registered globally or locally:
Global registration:
View.directive()
Partial registration:
Add option directives in Vue instance or component
Hook function:
An instruction definition object can provide the following hook functions (all optional):
-
bind
: Called only once, when the directive is bound to the element for the first time. One-time initialization settings can be performed here. -
inserted
: Called when the bound element is inserted into the parent node (only the parent node is guaranteed to exist, but not necessarily inserted into the document). -
update
: Called when the component's VNode is updated, but it may happen before its child VNode is updated . The value of the directive may or may not have changed. But you can ignore unnecessary template updates by comparing the values before and after the update.
-
componentUpdated
: Called after the VNode of the component where the command is located and its child VNodes are all updated. -
unbind
: Called only once, when the directive is unbound from the element.
The parameters of the hook function are el
, binding
, vnode
and oldVnode。
el
: The element bound to the instruction can be used to directly manipulate the DOM.binding
: An object containing the following properties:name
: Command name, excludingv-
the prefix.value
: the binding value of the directiveoldValue
: The previous value to which the directive was bound, only available inupdate
andcomponentUpdated
hooks. Available whether or not the value has changed.expression
: Instruction expression in string form.arg
: Parameters passed to the command, optional.modifiers
: An object containing modifiers.
vnode
: The virtual node generated by Vue compilation.oldVnode
: Previous virtual node, only available inupdate
and hooks.componentUpdated
<body>
<div id="app">
<!-- 自定义指令 v-focus -->
用户名:<input type="text" v-focus="bgColor">
<!-- 自定义指令 v-myshow -->
<input type="text" v-myshow="msg">
</div>
<script>
// 全局注册自定义指令 Vue.directive('指令名称',{配置对象})
Vue.directive('focus', {
inserted(el, binding) {
// console.log(el,binding);
// 让输入框自动聚焦
el.focus()
},
// 执行一次性的初始化设置
bind(el, binding, vnode) {
console.log(el,binding,vnode);
el.style.backgroundColor = binding.value
}
})
new Vue({
// 局部注册自定义指令
directives:{
// 指令名称:{配置对象}
'myshow': {
bind(el,binding,vnode){
el.value = binding.value
}
}
},
el: "#app",
data: {
bgColor: 'pink',
msg: 'hello'
}
})
</script>
</body>
The result is as follows:
The parameter binding prints the result:
Three, render rendering function
Vue recommends using templates to create your HTML in most cases. In some scenarios, however, you really need the full programming capabilities of JavaScript. At this point you can use render functions , which are closer to the compiler than templates.
When defining a component, we generally use template to create a template, and use template to create a template, which will eventually be compiled into a render function, and the render function will create a template.
example:
Use template to create a template:
<body>
<div id="app">
<my-a></my-a>
</div>
<script>
let myA = {
template:`
<div>
<ul>
<li v-for='item in arrs'>
{
{item.name}}
</li>
</ul>
</div>
`,
data(){
return {
msg:"我是一个div标签",
arrs:[
{id:1, name:'zhangsan', age:12},
{id:2, name:'lisi', age:13},
{id:3, name:'wangwu', age:14},
]
}
}
}
new Vue({
el:"#app",
components:{
'my-a': myA
}
})
</script>
</body>
result:
Use the render function:
<body>
<div id="app">
<my-a></my-a>
</div>
<script>
let myA = {
render(h){
//遍历创建li标签
let lis = this.arrs.map(item => {
return h('li', {}, item.name)
})
//三个参数:
// 第一个参数:创建的标签名称,
// 第二个参数:一个数据对象,可以设置标签样式、属性等
// 第三个参数:标签内容,可以写成数组
return h('ul', {
style:{
backgroundColor: 'pink'
}
}, lis)
},
data(){
return {
msg:"我是一个div标签",
arrs:[
{id:1, name:'zhangsan', age:12},
{id:2, name:'lisi', age:13},
{id:3, name:'wangwu', age:14},
]
}
}
}
new Vue({
el:"#app",
components:{
'my-a': myA
}
})
</script>
</body>
The result is as follows:
4. Filter
Vue.js allows custom filters that can be used for some common text formatting. Filters can be used in two places: double curly brace interpolation and v-bind expressions. Filters should be added at the end of JavaScript expressions, indicated by the pipe symbol " | ".
Global registration filter:
View.filter()
Partial registration:
Add option filters to Vue instance or component
Example:
Use filters for timestamps and text:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<!-- 引入momentjs -->
<script src="https://cdn.bootcdn.net/ajax/libs/moment.js/2.29.4/moment.min.js"></script>
</head>
<body>
<div id="app">
<!-- 在插值语法中使用 -->
{
{time | fmtDate}}
<!-- 在v-bind中使用 -->
<div :title="msg | upper">鼠标悬浮查看</div>
</div>
<script>
// 全局注册过滤器 Vue.filter('过滤器名称',过滤器格式处理函数)
Vue.filter('fmtDate', function(val){
// 参数val就是需要过滤的值,即管道符前面的值
// 使用momentjs库将时间戳转换为年月日时分秒 (需要引入monentjs库)
return moment(val).format('YYYY-MM-DD HH:mm:ss')
})
new Vue({
// 局部注册过滤器
filters:{
upper(val){
// 转成大写
return val.toUpperCase()
}
},
el:"#app",
data:{
time: new Date().getTime(),
msg: 'hello'
}
})
</script>
</body>
</html>
The result is as follows: