组件的概念
组件是一个html 、 css 、js 、img 等的一个聚合体
组件的作用
为了将来项目的维护、更新变得更简单代码的复用
组件的拓展
通过Vue.extend()来拓展的
ƒ
Vue (options
) {
if (!(this instanceof Vue)
) {
warn('Vue is a constructor and should be called with the `new` keyword');
}
this._init(options
);
}
ƒ
VueComponent (options
) {
this._init(options
);
}
组件的注册
全局注册
var Hello
= Vue
.extend({
template
: '<div> hello 组件 </div>',
})
Vue
.component('Hello',Hello
)
局部注册
var Hello
= Vue
.extend({
template
: '<div> 晚上嗨起来 </div>'
})
new Vue({
el
: '#app',
components
: {
'Hello': Hello
}
})
组件的选项
components:局部注册template:定义组件模板
template标签的直接子元素只能有一个 data:数据
面试题: data选项为什么是函数?
组件是一个整体,那么它的数据也应该是独立的,函数形式可以给一个独立作用域返回值为什么是对象呢?
我们vue特点是什么呢? 深入响应式,data选项要做劫持【 es5的Object.defineProperty的getter和setter设置 】 methods:方法computed:计算属性watch:侦听属性
is属性
html中哪些规定了自己的直接子元素的标签,是不能直接放组件的,但可以通过is属性来绑定。
组件的嵌套
全局嵌套
<body>
<div id="app">
<Father></Father>
</div>
<template id="father">
<div>
<h3> father
</h3>
<hr>
<Son/>
</div>
</template>
<template id="son">
<h5> son
</h5>
</template>
</body>
<script src="../../../lib/vue.js"></script>
<script>
Vue.component('Father',{
template: '#father'
})
Vue.component('Son',{
template: '#son'
})
new Vue({
el: '#app'
})
</script>
局部嵌套
new Vue({
el
: '#app',
components
: {
'Father': {
template
: '#father',
components
: {
'Son': {
template
: '#son'
}
}
}
}
})
组件的通信
父子组件通信
父组件将自己的数据同 v-bind 绑定在 子组件身上,子组件通过 props属性接收
<body>
<div id="app">
<Father></Father>
</div>
<template id="father">
<div>
<Son :aa = "money" />
</div>
</template>
<template id="son">
<div>
<p>老爸给了我 {{ aa }} 块
</p>
<p> {{ aa + 20 }}
</p>
</div>
</template>
</body>
<script src="../../../lib/vue.js"></script>
<script>
Vue.component('Father',{
template: '#father',
data () {
return {
money: 4000
}
}
})
Vue.component('Son',{
template: '#son',
props: {
'aa': {
validator ( val ) {
return val > 3000
}
}
}
})
new Vue({
el: '#app'
})
</script>
子父组件通信
通过自定义事件
<body>
<div id="app">
<Father></Father>
</div>
<template id="father">
<div>
<h1>Father
</h1>
<p> 我儿子给我发了{{ sifangqian }} 块的红包
</p>
<Son @givemoney='get'></Son>
</div>
</template>
<template id="son">
<div>
<h1>Son
</h1>
<button @click='give'>发红包
</button>
</div>
</template>
</body>
<script src="../../lib/vue.js"></script>
<script>
Vue.component('Father', {
template: '#father',
data() {
return {
sifangqian: 0
}
},
methods: {
get(val) {
this.sifangqian = val
}
}
})
Vue.component('Son', {
template: '#son',
data() {
return {
money: 2000
}
},
methods: {
give() {
this.$emit('givemoney', this.money)
}
}
})
new Vue({
el: '#app'
})
</script>
非父子组件通信-ref绑定
<body>
<div id="app">
<Father></Father>
</div>
<template id="father">
<div>
<h1>Father
</h1>
<Sister :k='getSon'></Sister>
<Son ref='son'></Son>
</div>
</template>
<template id="son">
<div>
<h1>Son
</h1>
<img v-if='flag' src="https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=3872048339,4140466773&fm=26&gp=0.jpg" alt="">
<img v-else src="https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=2438534582,3797477605&fm=26&gp=0.jpg" alt="">
</div>
</template>
<template id="sister">
<div>
<h1>Sister
</h1>
<button @click='hite'>hite
</button>
</div>
</template>
</body>
<script src="../../lib/vue.js"></script>
<script>
Vue.component('Father', {
template: '#father',
methods: {
getSon() {
this.$refs.son.changeFlag()
}
}
})
Vue.component('Son', {
template: '#son',
data() {
return {
flag: true
}
},
methods: {
changeFlag() {
this.flag = !this.flag
}
}
})
Vue.component('Sister', {
template: '#sister',
props: ['k'],
methods: {
hite() {
this.k()
}
}
})
new Vue({
el: '#app'
})
</script>
非父子组件通信-bus总线
<body>
<div id="app">
<Father></Father>
</div>
<template id="father">
<div>
<h1>Father
</h1>
<Sister></Sister>
<Son></Son>
</div>
</template>
<template id="son">
<div>
<h1>Son
</h1>
<img v-if='flag' src="https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=3872048339,4140466773&fm=26&gp=0.jpg" alt="">
<img v-else src="https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=2438534582,3797477605&fm=26&gp=0.jpg" alt="">
</div>
</template>
<template id="sister">
<div>
<h1>Sister
</h1>
<button @click='hite'>hite
</button>
</div>
</template>
</body>
<script src="../../lib/vue.js"></script>
<script>
var bus = new Vue()
Vue.component('Father', {
template: '#father',
})
Vue.component('Son', {
template: '#son',
data() {
return {
flag: true
}
},
mounted() {
var _this = this
bus.$on('cry', function() {
_this.flag = !_this.flag
})
}
})
Vue.component('Sister', {
template: '#sister',
methods: {
hite() {
bus.$emit('cry')
}
}
})
new Vue({
el: '#app'
})
</script>
组件上实现原生事件
绑定时使用.native修饰符
<Hello :name = "name" @click.native = "changeName">
</Hello>
动态组件
<component :is = "val">
</component>
动态缓存
<keep-alive :include = "val">
<component :is = "val">
</component>
</keep-alive>
过渡效果
Vue框架使用css3过渡效果或是js动画 Vue内部提供了一个叫做transition的过渡组件 使用transition包裹过渡元素,那么会自动添加 6 个类名 8个钩子函数
默认 类名 开头 v如果有name属性,那么使用 这个name属性值作为类名开头实现方式
在 CSS 过渡和动画中自动应用 class 【 自己写 】可以配合使用第三方 CSS 动画库,如 Animate.css在过渡钩子函数中使用 JavaScript 直接操作 DOM可以配合使用第三方 JavaScript 动画库,如 Velocity.js 第一种 [ 在 CSS 过渡和动画中自动应用 class 【 自己写 】 ]第二种: animate.css 【 推荐 】
<div id="app">
<button @click = "changeFlag"> changeFlag
</button>
<transition
name = "xige"
mode = "in-out"
enter-active-class = "animated fadeIn"
leave-active-class = "animated fadeOut"
>
<p v-if = "flag">
</p>
</transition>
</div>
第三种: Vue提供了8个javascript钩子,我们需要自定义js动画第四种: 使用第三方插件: Velocity.js
过滤器
作用 是对已经有的数据做数据格式化使用格式 已有数据 | 过滤器名称(arg1,arg2)定义
<body>
<div id="app">
<button @click='getTime'>getTime
</button>
<p> {{ time | showTime('-') }}
</p>
</div>
</body>
<script src="../../lib/vue.js"></script>
<script>
// 全局定义
// Vue.filter('showTime', function(val, type) {
// var date = new Date(val)
// if (val) {
// return date.getFullYear() + type + (date.getMonth() + 1) + type + date.getDate()
// } else {
// return ''
// }
// })
new Vue({
el: '#app',
data: {
time: ''
},
methods: {
getTime() {
this.time = new Date()
}
},
// 局部定义
filters: {
showTime(val, type) {
var date = new Date(val)
if (val) {
return date.getFullYear() + type + (date.getMonth() + 1) + type + date.getDate()
} else {
return ''
}
}
}
})
```
插槽
普通插槽
<div id="app">
<Hello> <p> 你好
</p> </Hello>
</div>
<template id="hello">
<div>
<h3> hello组件
</h3>
<slot></slot>
</div>
</template>
具名插槽
<div id="app">
<Hello>
<header slot = "header"> 头部
</header>
<footer slot = "footer">底部
</footer>
</Hello>
</div>
<template id="hello">
<div>
<slot name = "header">
</slot>
<h3> hello组件
</h3>
<slot name = "footer">
</slot>
</div>
</template>
作用域插槽
<div id="app">
<Hello>
<template v-slot:default = "scope">
<p> {{ scope.money }}
</p>
</template>
</Hello>
</div>
<template id="hello">
<div>
<slot :money = "money">
</slot>
</div>
</template>