目录
插槽
普通插槽,具名插槽,作用域插槽
插槽允许我们在调用子组件的时候为子组件传递模板。
<slot> 元素作为承载分发内容的出口。 一个不带 name 的 <slot> 出口会带有隐含的名字"default"。
父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。
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.14/dist/vue.js"></script>
</head>
<body>
<div id="app">
<my-a>
{{msg}}
<!-- 父组件调用子组件提供了一个模版 -->
<div :title="msg">我是块级元素</div>
<img width="150px" src="../../HTML&CSS/images/ad10.jpg">
<!-- <header>头部内容</header>
<article>中间内容</article>
<footer>底部内容</footer> -->
<!-- 父组件调用子组件提供了具体的模版 -->
<!-- <template v-slot:header> -->
<!-- 绑定具名插槽时可以简写为#header -->
<template #header>
<!-- <template v-slot:header> -->
<h1>头部的内容</h1>
</template>
<template v-slot:article>
<p>我是文章内容</p>
<p>我是文章内容</p>
</template>
<template v-slot:footer>
<div>我是底部的内容</div>
</template>
<!-- 作用域插槽 -->
<template v-slot:default="scope">
<!-- <template v-slot="scope"> -->
<!-- <template slot-scope = "scope"> -->
<div>
{{scope}}
</div>
</template>
</my-a>
</div>
<script>
let myA = {
template:`
<div>
myA组件
<slot name='default'>submit</slot>
<hr>
<header>
<slot name='header'></slot>
</header>
<article>
<slot name='article'></slot>
</article>
<footer>
<slot name='footer'></slot>
</footer>
<slot v-bind:subMsg='subMsg'></slot>
</div>
`,
data(){
return{
msgA:'我是子组件',
subMsg:'我是子组件的属性'
}
}
}
new Vue({
components:{
'my-a':myA
},
el:'#app',
data:{
msg:'我是父组件中msg',
},
methods:{},
})
</script>
</body>
</html>
自定义指令
directive
Vue中多有的指令都以 v- 来调用。但是,有时候Vue提供给我们的指令并不能满足我们的需求,这个时候 我们就需要自定义指令。
指令允许我们对普通 DOM 元素进行底层操作。可以全局注册也可以局部注册
全局注册
使用Vue.directive
局部注册
在Vue实例或组件中添加新的选项directives
钩子函数
钩子函数可以在指令的生命周期内的关键时刻加入代码
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"></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>
render渲染函数
Vue 推荐在绝大多数情况下使用模板来创建你的 HTML。然而在一些场景中,你真的需要 JavaScript 的完全编程的能力。这时你可以用渲染函数,它比模板更接近编译器。
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>
过滤器
Vue.js 允许自定义过滤器,可被用于一些常见的文本格式化。过滤器可以用在两个地方:双花括号插值和 v-bind 表达式 (后者从 2.1.0+ 开始支持)。过滤器应该被添加在 JavaScript 表达式的尾部,由"管道"
|
符号指示:<!-- 在双花括号中 --> {{ message | filterMethod }} <!-- 在 `v-bind` 中 -->
javascript
//首先引入 `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>
插件
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({ // ...组件选项 })
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"></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>