Vue组件

了解Vue组件

is

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
<!DOCTYPE html>
<html lang="en">
<head>
<title>组件使用中的细节点</title>
<meta charset="utf-8">
<script src="./vue.js"></script>
</head>
<body>
<div id="root">
<table>
<tbody>
<tr is="row"></tr>
<tr is="row"></tr>
<tr is="row"></tr>
</tbody>
</table>
</div>
<script>
//html5语法table下面必须有tr,不然我们的模板无法处于table内
Vue.component("row",{
template:'<tr><td>This is a row</td></tr>'
});
var vm = new Vue({
el: "#root"
})
</script>
</body>
</html>

ref及子组件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
47
48
49
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>组件使用中的细节点</title>
<script src='./vue.js'></script>
</head>
<body>

<div id="root">
<counter ref="one" @change="handleChange"></counter>
<counter ref="two" @change="handleChange"></counter>
<div>{{total}}</div>
</div>

<script>
//子组件data必须是函数,保证多个相同子组件数据互不干涉
Vue.component('counter', {
template: '<div @click="handleClick">{{number}}</div>',
data: function() {
return {
number: 0
}
},
methods: {
handleClick: function() {
this.number ++
this.$emit('change')
}
}
})

var vm = new Vue({
el: '#root',
data: {
total: 0
},
methods: {
handleChange: function() {
//写在html上是获取文档
//在组件上是获取整个实例
this.total = this.$refs.one.number + this.$refs.two.number
}
}
})
</script>

</body>
</html>

父子组件的数据传递

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
47
48
49
50
51
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>父子组件传值</title>
<script src='./vue.js'></script>
</head>
<body>

<div id="root">
<counter :count="3" @inc="handleIncrease"></counter>
<counter :count="2" @inc="handleIncrease"></counter>
<div>{{total}}</div>
</div>

<script>

var counter = {
props: ['count'],
data: function() {
return {
number: this.count
}
},
template: '<div @click="handleClick">{{number}}</div>',
methods: {
handleClick: function() {
this.number = this.number + 2;
this.$emit('inc', 2)
}
}
}

var vm = new Vue({
el: '#root',
data: {
total: 5
},
components: {
counter: counter
},
methods: {
handleIncrease: function(step) {
this.total += step
}
}
})
</script>

</body>
</html>

组件参数校验与非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
27
28
29
30
31
32
33
34
35
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>组件参数校验与非Props特性</title>
<script src='./vue.js'></script>
</head>
<body>

<div id="root">
<child content="hell"></child>
</div>

<script>
Vue.component('child', { //父给子组件传递数据,不接收(非props特性)
// props: { //父给子组件传递数据,进行接收(props特性)
// content: {
// type: String, //类型接收限制,多类型用数组
// // required: false,
// // default: 'default value', //参数必须传递
// // validator: function(value) { //函数自定义检验
// // return (value.length > 5)
// // }
// }
// },
template: '<div>hello</div>'
})

var vm = new Vue({
el: '#root'
})
</script>

</body>
</html>

组件绑定原生事件

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>给组件绑定原生事件</title>
<script src='./vue.js'></script>
</head>
<body>

<div id="root">
<child @click.native="handleClick"></child> <!--.native 绑定原生事件-->
</div>

<script>

Vue.component('child', {
template: '<div>Child</div>',
})

var vm = new Vue({
el: '#root',
methods: {
handleClick: function() {
alert('click')
}
}
})
</script>

</body>
</html>

非父子组件间的传值

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
47
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>非父子组件的传值</title>
<script src="./vue.js"></script>
</head>
<body>

<div id="root">
<child content="childOne"></child>
<child content="childTwo"></child>
</div>

<script>
// bus 总线 进行非父子组件的传值

Vue.prototype.bus = new Vue()

Vue.component('child', {
props: ['content'],
data: function() {
return {
myContent: this.content
}
},
template: '<div @click="handleClick">{{myContent}}</div>',
methods: {
handleClick: function() {
this.bus.$emit('change', this.myContent)
}
},
mounted: function() {
var this_ = this;
this.bus.$on('change', function(content) {
this_.myContent = content
})
}
})

var vm = new Vue({
el: "#root"
})
</script>

</body>
</html>

插槽

单个插槽

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>插槽 - 单个插槽</title>
<script src="./vue.js"></script>
</head>
<body>

<div id="root">
<child>
<h1>hello</h1>
</child>
</div>

<script>

var child = {
template: '<div><slot>默认插槽的内容</slot></div>'
}

var vm = new Vue({
components: {
child: child
},
el: "#root"
})
</script>

</body>
</html>

具名插槽

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>插槽 - 具名插槽</title>
<script src="./vue.js"></script>
</head>
<body>

<div id="root">
<child>
<h1 slot="header">header</h1>
<h1 slot="footer">footer</h1>
</child>
</div>

<script>

var child = {
template: `<div>
<slot name="header"></slot>
<div>
<h2>content</h2>
</div>
<slot name="footer"></slot>
</div>`
}

var vm = new Vue({
components: {
child: child
},
el: "#root"
})
</script>

</body>
</html>

作用域插槽

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue中的作用域插槽</title>
<script src='./vue.js'></script>
</head>
<body>

<div id="root">
<child>
<template slot-scope="props">
<h1>{{props.item}}</h1>
</template>
</child>
</div>

<script>

Vue.component('child', {
data: function() {
return {
list: [1, 2, 3, 4]
}
},
template: `<div>
<ul>
<slot
v-for="item of list"
:item=item
></slot>
</ul>
</div>`
})

var vm = new Vue({
el: '#root'
})
</script>

</body>
</html>

动态组件与v-once指令

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>动态组件与v-once指令</title>
<script src='./vue.js'></script>
</head>
<body>

<div id="root">
<!-- <component :is="type"></component> -->
<child-one v-if="type ==='child-one'"></child-one>
<child-two v-if="type ==='child-two'"></child-two>
<button @click="handleBtnClick">change</button>
</div>

<script>

Vue.component('child-one', {
template: '<div v-once>child-one</div>'
})

Vue.component('child-two', {
template: '<div v-once>child-two</div>'
})

var vm = new Vue({
el: '#root',
data: {
type: 'child-one'
},
methods: {
handleBtnClick: function() {
this.type = (this.type === 'child-one' ? 'child-two': 'child-one');
}
}
})
</script>

</body>
</html>