vue(3-2)
1. 组件化应用构建
组件系统是 Vue
的另一个重要概念,因为它是一种抽象,允许我们使用小型、独立和通常可复用的组件构建大型应用。仔细想想,几乎任意类型的应用界面都可以抽象为一个组件树。
在 Vue 里,一个组件本质上是一个拥有预定义选项的一个 Vue 实例。在 Vue 中注册组件很简单:
通过
Vue.component()
方法直接创建1
2
3
4// 定义名为 todo-item 的新组件
Vue.component('todo-item', {
template: '<li>这是个待办项</li>'
})通过将模板字符串定义到
script
标签中1
2
3
4
5
6
7
8<script id="tpl" type="text/x-template">
<h2>这里是待办事项</h2>
</script>
<script>
Vue.component('my-com', {
template: '#tpl'
});
</script>1
2
3
4<div id="app">
<!-- 创建一个 my-com 组件的实例 -->
<my-com></my-com>
</div>
组件化和模块化的不同:
- 模块化: 是从代码逻辑的角度进行划分的;方便代码分层开发,保证每个功能模块的职能单一;
- 组件化: 是从UI界面的角度进行划分的;前端的组件化,方便UI组件的重用;
2. 组件展示数据和响应事件
组件可以有自己的data,Vue实例中的data可以是一个对象,但是组件中的data必须是一个方法,而且这个方法内部还必须返回一个对象。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46<!-- 以下内容在body标签内部**公共组件和私有组件的区别 -->
<div id="app">
<my-com></my-com>
</div>
<div id="app2">
<my-com></my-com>
<inner></inner>
</div>
<template id="tlp">
<!--注意:template属性指定的内容,只能有一个根元素-->
<div>
<h3>这是利用组件模板创建的待办事项</h3>
<span>没毛病。。。</span>
</div>
</template>
<script id="tlp2" type="text/x-template">
<h2>i am a priority component, do not forget the SPACE</h2>
</script>
<script src="./lib/vue-2.4.0.js"></script>
<script>
// 公用组件
Vue.component('myCom', {
template: '#tlp'
});
let vm = new Vue({
el: '#app',
data: {},
methods: {}
});
let vm2 = new Vue({
el: '#app2',
data: {},
methods: {},
filters: {},
directives: {},
components: { // 定义内部私有组件,注意是复数
inner: {
template: '#tlp2' // 不能有空格否则id找不到
}
}
})
</script>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35<!-- 以下内容在body标签内部**data必须是一个方法并且返回一个对象 -->
<div id="app">
<my-com></my-com>
<my-com></my-com>
</div>
<template id="tlp">
<div>
<button @click="add">click me +1</button>
<h5>{{ count }}</h5>
</div>
</template>
<script src="./lib/vue-2.4.0.js"></script>
<script>
let outData = {count: 0};
Vue.component('myCom', {
template: '#tlp',
data: function () {
// return outData; // 如果返回了外部的对象,那么两次创建的组件会同步变化
return { count: 0 } // 这样的返回值才能保证组将之间互不影响
},
methods: {
add() {
this.count ++
}
}
});
let vm = new Vue({
el: '#app',
data: {},
methods: {
}
});
</script>利用组件实现登录/注册的切换
1
2
3
4
5
6
7
8
9.v-enter,
.v-leave-to {
opacity: 0;
transform: translateX(100px);
}
.v-enter-active,
.v-leave-active {
transition: all .8s ease;
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31<div id="app">
<a href="" @click.prevent="cName='login'">登录</a>
<a href="" @click.prevent="cName='register'">注册</a>
<!-- 通过 mode 属性,设置组件切换时候的 模式 -->
<transition mode="out-in">
<!-- Vue提供了 component ,来展示对应名称的组件 -->
<!-- component 是一个占位符, :is 属性,可以用来指定要展示的组件的名称 -->
<component :is="cName"></component>
</transition>
<!-- 总结:当前学习了的 Vue 提供的标签 -->
<!-- component, template, transition, transitionGroup -->
</div>
<script src="./lib/vue-2.4.0.js"></script>
<script>
Vue.component('login', {
template: '<h2>登录</h2>'
});
Vue.component('register', {
template: '<h2>注册</h2>'
});
let vm = new Vue({
el: '#app',
data: {
cName: 'login'
},
methods: {}
});
</script>
2.1 父组件向子组件传值
利用
props
定义属性1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26<div id="app">
<!-- 父组件可以通过 属性绑定(v-bind:)的形式把数据传递给子组件 -->
<com1 v-bind:fathermsg="msg"></com1>
</div>
<script src="./lib/vue-2.4.0.js"></script>
<script>
let vm = new Vue({
el: '#app',
data: {
msg: '父组件内容'
},
methods: {},
components: {
com1: {
template: '<h2>子组件内容 -- {{ fathermsg }}</h2>',
data() { // 这里的data是子组件自身私有的,可以是通过ajax请求来的数据,这些数据时可以读写的
return {
content: 'test content'
}
},
// 组件中props属性中的数据都是通过父组件传递过来的,这里面的数据是只读的
props: ['fathermsg']
}
}
});
</script>
2.2 子组件向父组件传值
父组件把方法传递给子组件,同时传递参数给子组件,这样达到传递数据的目的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45<div id="app">
<!-- 父组件向子组件传递方法,使用v-on, 自定义一个事件属性之后,组件就能通过$emit()调用这个方法了 -->
<com2 @func="getData"></com2>
</div>
<script type="text/x-template" id="tpl">
<div>
<h2>子组件的内容</h2>
<button @click="sonClick">点击调用父组件中的方法并传参</button>
</div>
</script>
<script src="./lib/vue-2.4.0.js"></script>
<script>
let com2 = {
template: '#tpl',
data(){
return { // 需要传递的数据
sonData: {
name: 'jack',
age: 18
}
}
},
methods: { // 组件中的点击事件
sonClick(){
// emit 是发出,触发的意思。这个方法将触发func方法并将参数传递给父组件
this.$emit('func', this.sonData)
}
}
};
let vm = new Vue({
el: '#app',
data: {
dataFromSon: null // 定义一个变量准备接受子组件传递过来的数据
},
methods: {
getData(data){
// 将子组件传递过来的值赋值给父组件
this.dataFromSon = data;
}
},
components: {
com2 // com2组件定义在外部
}
});
</script>