1.插槽
普通插槽,具名插槽,作用域插槽
插槽允许我们在调用子组件的时候为子组件传递模板。
元素作为承载分发内容的出口。 一个不带 name 的 出口会带有隐含的名字“default”。
父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。
### 1.默认插槽
没有名字的插槽就是默认插槽
<slot>123</slot>
<slot name="default">123</slot>
### 2. 具名插槽
具有名字的插槽
<slot name="slot2">123</slot>
### 3.插槽填充
<my-com>hello</my-com>
内容填充到模板的哪个插槽中?
指定插槽
<my-com>
<template v-slot:default>
hello
</template>
<template v-slot:slot>
123
</template>
<template #slot>
123
</template>
</my-com>
### 插槽声明 {template:`<slot>插槽默认模板</slot>`}
插槽模板
### 1.默认模板
<slot>插槽默认模板</slot>
### 2.自定义模板
<my-com>
<template #name>
插槽自定义模板
</template>
</my-com>
在插槽默认模板中,可以直接访问子组件的数据,可以通过props间接访问父组件的数据
在插槽自定义模板中,可以直接访问父组件的数据,可以通过插槽属性间接访问子组件的数据(插槽作用域)
<!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/vue@2.7.10"></script>
</head>
<body>
<div id="app">
<my-a :arr="arr">
<div>我是子组件</div>
<template v-slot:header> 开始的内容</template>
<template v-slot:center> 中间的内容</template>
<template v-slot:footer> 结束的内容</template>
<template slot-scope="scope"> {{scope.row}}</template>
</my-a>
</div>
<script>
let myA = {
props: ['arr'],
data() {
return {
msg: '222'
}
},
template: `
<div>
A组件
<slot name='default'></slot>
<div class="header"><slot name='header'></slot></div>
<div class="center" >
<slot name='center'></slot>
</div>
<div class="footer"><slot name='footer'></slot></div>
<ul>
<li v-for="item in arr">
<slot v-bind:row='item'></slot>
</li>
</ul>
</div>
`
};
Vue.component('my-a', myA)
new Vue({
el: "#app",
data: {
arr: [1, 2, 3, 4]
},
methods: {}
})
</script>
</body>
</html>
2.自定义指令
directive
Vue中多有的指令都以 v- 来调用。但是,有时候Vue提供给我们的指令并不能满足我们的需求,这个时候 我们就需要自定义指令。
指令允许我们对普通 DOM 元素进行底层操作。可以全局注册也可以局部注册
全局注册
使用Vue.directive
局部注册
在Vue实例或组件中添加新的选项directives
钩子函数
钩子函数可以在指令的生命周期内的关键时刻加入代码
<!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/vue@2.7.10"></script>
</head>
<body>
<div id="app">
<input v-focus="msg" type="text" >
{{msg}}
<input v-myshow="msg" type="text" >
</div>
<script>
Vue.directive('focus',{
inserted(el){
el.focus()
},
bind(el,binding,vnode){
el.style.backgroundColor=binding.value
}
})
new Vue({
directives:{
'myshow':{
inserted(el){
},
bind(el,binding,vnode){
el.value=binding.value;
}
}
},
el:"#app",
data:{
msg:'red'
},
methods:{}
})
</script>
</body>
</html>
3.render渲染函数
Vue 推荐在绝大多数情况下使用模板来创建你的 HTML。然而在一些场景中,你真的需要 JavaScript 的完全编程的能力。这时你可以用渲染函数,它比模板更接近编译器。
<!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/vue@2.7.10/dist/vue.js"></script>
</head>
<body>
<div id="app">
<my-a :friuts="friuts">
列表
</my-a>
</div>
<script>
let myA={
props:{
friuts:{
type:Array,
}
},
beforeMount(){
alert('beforeMount')
},
mounted(){
alert('mounted')
},
render(h){
alert('2222')
let lis=this.friuts.map(item=>{
return h('li',{},item)
})
return h('ul',{},[this.$slots.default,...lis])
},
// template:`
// <div>
// <ul>
// <li v-for='item in friuts'>{{item}}</li>
// </ul>
// </div>
// `,
data(){
return {
}
}
}
new Vue({
components:{
'my-a':myA
},
el:"#app",
data:{
friuts:['苹果','香蕉','菠萝']
},
methods:{}
})
</script>
</body>
</html>
4.过滤器
Vue.js 允许自定义过滤器,可被用于一些常见的文本格式化。过滤器可以用在两个地方:双花括号插值和 v-bind表达式 (后者从 2.1.0+ 开始支持)。过滤器应该被添加在 JavaScript 表达式的尾部,由“管道”
|
符号指示:{{ message | filterMethod }}
首先引入 `moment`第三方库,再进行接下来的操作。引入moment仅供实现功能,与过滤器没有关系。
<script src="https://cdn.bootcdn.net/ajax/libs/moment.js/2.29.1/locale/af.js"></script>
<script>
// 全局注册
Vue.filter("fmtDate_global", function (date) {
return moment(date).format("YYYY-MM-DD HH:mm:ss");
// 或者return自己编写的时间处理函数
})
new Vue({...})
</script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>hello world</title>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.9/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
</head>
<body>
<div id="app">
<!-- 使用过滤器 -->
<div>{{ new Date() | fmtDate_global}}</div>
<div :title="new Date() | fmtDate_global">鼠标悬停查看时间</div>
</div>
<script>
// 全局注册过滤器
Vue.filter("fmtDate_global", function (date) {
return moment(date).format("YYYY-MM-DD HH:mm:ss");
})
new Vue({
el: '#app',
})
</script>
</body>
</html>
5.插件
plugin
插件通常用来为 Vue 添加全局功能。Vue.js 的插件应该暴露一个 install 方法。这个方法的第一个参数是 Vue 构造器,第二个参数是一个可选的选项对象:
MyPlugin.install = function (Vue, options) { // 1. 添加全局方法或 property Vue.myGlobalMethod = function () { // 逻辑... } // 2. 添加全局资源 Vue.directive('my-directive', { bind (el, binding, vnode, oldVnode) { // 逻辑... } ... }) // 3. 注入组件选项 Vue.mixin({ created: function () { // 逻辑... } ... }) // 4. 添加实例方法 Vue.prototype.$myMethod = function (methodOptions) { // 逻辑... } }
通过全局方法
Vue.use()
使用插件。它需要在你调用new Vue()
启动应用之前完成:// 调用 `MyPlugin.install(Vue)` Vue.use(MyPlugin) new Vue({ // ...组件选项 })
<!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/vue@2.7.10"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
</head>
<body>
<div id="app">
{{time | fmtTime}}
<input type="text" v-focus>
</div>
<script>
let MyPlugin = {
install(Vue, options) {
Vue.filter('fmtTime', (val) => {
return moment(val).format('YYYY--MM-DD')
}),
Vue.prototype.$message=function(val){
alert(val)
},
Vue.directive('focus', {
inserted(el) {
el.focus()
},
bind(el, binding, vnode) {
el.style.backgroundColor = binding.value
}
})
},
};
Vue.use(MyPlugin)
new Vue({
el: "#app",
data: {
time: new Date().getTime()
},
created(){
this.$message('请求成功')
},
methods: {}
})
</script>
</body>
</html>