提示
本文主要讲解 Vue 中的组件。@ermo
# 组件
组件(Component)是 Vue.js 最强大的功能之一。组件可以封装可重用的代码,用于扩展 HTML 代码。
# 全局组件
定义全局组件的语法为:
Vue.component(name, options);
name
为组件名,options
为组件配置。
如下是一个最简单的组件示例,全局实例都可以使用的组件:
<!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"></script>
</head>
<body>
<div id="app">
<ermo></ermo>
<ermo></ermo>
<ermo></ermo>
<ermo></ermo>
</div>
<script>
Vue.component('ermo', {
template: '<h2>文本</h2>'
});
var vm = new Vue({
el: '#app'
});
</script>
</body>
</html>
组件中的模板也可以使用 Vue.js 中的指令,组件可以重复复用。
<!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"></script>
</head>
<body>
<div id="btn-example">
<button-component></button-component>
<button-component></button-component>
<button-component></button-component>
</div>
<script>
Vue.component('button-component', {
data: function() {
return {
count: 0
}
},
template: '<button v-on:click="count++">点我{{count}}</button>'
});
var btnVm = new Vue({
el: '#btn-example'
});
</script>
</body>
</html>
上例中的 data
必须返回一个函数,这样每个组件实例调用才会返回一份独立的数据拷贝。
如果将 data
修改为如下,多个组件的数据是共享的,不建议这样使用。
data: {
count: 0
}
# 局部组件
局部组件只有当前实例可以使用:
<!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"></script>
</head>
<body>
<div id="app">
<ermo></ermo>
<ermo></ermo>
<ermo></ermo>
</div>
<script>
var child = {
template: '<h1>自定义组件</h1>'
}
var vm = new Vue({
el: '#app',
components: {
ermo: child
}
});
</script>
</body>
</html>
# 通过 Prop 向子组件传递数据
可以在父组件定义 Prop,子组件可以使用父组件中 Prop 中自定义的属性名,从而向父组件中传递数据。
<!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"></script>
</head>
<body>
<div id="app">
<ermo msg="属性值1"></ermo>
<ermo msg="属性值2"></ermo>
<ermo msg="属性值3"></ermo>
</div>
<script>
Vue.component('ermo', {
props: ['msg'],
template: '<p> 自定义属性: {{ msg }} </p>'
});
var vm = new Vue({
el: '#app'
});
</script>
</body>
</html>
# 动态绑定 Prop
在实例化子组件时可以使用 v-bind
将自定义属性动态绑定到其他元素上。这样每当子组件上的绑定值发生改变,该数据也会动态传递到父组件上。
<!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"></script>
</head>
<body>
<div id="app">
<div>
<input type="text" v-model="titleText" placeholder="输入文字">
<br>
<child v-bind:title="titleText"></child>
<child v-bind:title="titleText"></child>
<child v-bind:title="titleText"></child>
</div>
</div>
<script>
Vue.component('child', {
props: ['title'],
template: '<p>绑定数据: {{title}} </p>'
});
var vm = new Vue({
el: '#app',
data: {
titleText: ''
}
});
</script>
</body>
</html>
下例将 language
属性传递到可重复的每一个子组件中。
<!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"></script>
</head>
<body>
<div id="app">
<ol>
<language-li v-for="item in languages" v-bind:language="item"></language-li>
</ol>
</div>
<script>
Vue.component('language-li', {
props: ['language'],
template: '<li> 语言: {{ language.name }},id: {{ language.id }} </li>'
});
var vm = new Vue({
el: '#app',
data: {
languages: [
{ id: 1, name: 'java' },
{ id: 2, name: 'php' },
{ id: 3, name: 'js' }
]
}
});
</script>
</body>
</html>
# Prop 验证
组件可以为每一个 Prop 属性提供验证需求,为了定制 Prop 的验证,props
不再是一个数组,而是一个带有验证的对象,如下:
<script>
Vue.component('my-component', {
props: {
// 基础的类型检查
age: Number,
// 多个允许的类型
propB: [String, Number],
// 必填字符串
propC: {
type: String,
required: true
},
// 带有默认值的数字
propD: {
type: Number,
default: 100
},
propE: {
type: Object,
// 对象或数组必须返回一个函数
default: function () {
return { message: 'hello' }
}
},
// 自定义验证函数
propF: {
validator: function(value) {
// 必须匹配下列值中的一个
return ['success', 'error', 'warn'].indexOf(value) !== -1
}
}
}
});
</script>