组件化开发:就是把一类功能的元素组合到一起,将css(样式)/js(功能)/html(结构)包装到一起,供后续复用
Vue组件注册语法:
// 定义一个名为 button-counter 的新组件
Vue.component('button-counter', {
data: function () {
return {
count: 0
}
},
template: ''
})
new Vue({ el: '#app' })
组件是可复用的 Vue 实例,且带有一个名字:在这个例子中是
。我们可以在一个通过 new Vue 创建的 Vue 根实例中,把这个组件作为自定义元素来使用:
<div id="app">
<button-counter>button-counter>
div>
例如:
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Documenttitle>
head>
<body>
<div id="app">
<compiles>compiles>
div>
body>
<script src="./js/vue.js">script>
<script>
Vue.component('compiles', {
data: () => {
return {
sum: 0
}
},
template: ''
})
var vm = new Vue({
el: '#app'
})
script>
html>
注意:因为组件是可复用的 Vue 实例,所以它们与 new Vue 接收相同的选项,例如 data、computed、watch、methods 以及生命周期钩子等。仅有的例外是像 el 这样根实例特有的选项
组件注册注意事项:
new Vue({
el: '#app',
components: {
HelloWorld: {
data: () => ({ }),
template: ``
}
}
})
组件之间的数据交互:
通过 Prop 向子组件传递数据
Prop 是你可以在组件上注册的一些自定义属性。当一个值传递给一个 prop 属性 的时候,它就变成了那个组件实例的一个属性。为了给组件传递一个标题,我们可以用一个 props 选项将其包含在该组件可接受的 prop 列表中:
Vue.component('blog-post', {
props: ['title'],
template: '{{ title }}
'
})
<blog-post title="My journey with Vue">blog-post>
<blog-post title="Blogging with Vue">blog-post>
<blog-post title="Why Vue is so fun">blog-post>
补充说明:
props在定义时,可以指定固定的类型
Vue.component('User', {
props: {
name: String,
age: {
type: Number,
default: 18, // 默认值
required: true, // 是否必传
},
isMarry: Boolean, // 这个布尔值有点特殊,只要你在HTML中加了这个属性,就是true,反之false
},
})
// 在HTML中使用时
//
子向父传值:
鉴于存在单向数据流的规范,我们子组件向父组件进行数据交互时,就不能直接操作,需要借助事件机制来通知父组件,让父组件自己操作自己的数据:
范例(带事件参数):
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
head>
<body>
<div id="app">
<user-name-input @name-send="onNameSend($event)">user-name-input>
<br>
{{ msg }}
div>
<script src="./js/vue.js">script>
<script>
Vue.component('UserNameInput', {
data: () => ({ name: '' }),
methods: {
send() {
// 触发自定义事件,用来通知父组件
this.$emit('name-send', this.name)
// 如果需要传递多个数据,可以使用数据或对象的形式
// this.$emit('name-send', [this.name, 'hehe', 123, 456])
}
},
template: `
`,
})
new Vue({
el: '#app',
data: {
msg: '',
},
methods: {
onNameSend(eventData) {
console.log(' 子组件 触发了 name-send 事件' , eventData);
this.msg = `hello, ${eventData} ~`
}
}
})
script>
body>
html>
补充说明:
兄弟或(祖孙)组件传值:
<div id="app">
<div>父组件div>
<div>
<button @click='handle'>销毁事件button>
div>
<test-tom>test-tom>
<test-jerry>test-jerry>
div>
<script type="text/javascript" src="js/vue.js">script>
<script type="text/javascript">
/*
兄弟组件之间数据传递
*/
//1、 提供事件中心
var hub = new Vue();
Vue.component('test-tom', {
data: function(){
return {
num: 0
}
},
template: `
TOM:{{num}}
`,
methods: {
handle: function(){
//2、传递数据方,通过一个事件触发hub.$emit(方法名,传递的数据) 触发兄弟组件的事件
hub.$emit('jerry-event', 2);
}
},
mounted: function() {
// 3、接收数据方,通过mounted(){} 钩子中 触发hub.$on(方法名
hub.$on('tom-event', (val) => {
this.num += val;
});
}
});
Vue.component('test-jerry', {
data: function(){
return {
num: 0
}
},
template: `
JERRY:{{num}}
`,
methods: {
handle: function(){
//2、传递数据方,通过一个事件触发hub.$emit(方法名,传递的数据) 触发兄弟组件的事件
hub.$emit('tom-event', 1);
}
},
mounted: function() {
// 3、接收数据方,通过mounted(){} 钩子中 触发hub.$on()方法名
hub.$on('jerry-event', (val) => {
this.num += val;
});
}
});
var vm = new Vue({
el: '#app',
data: {
},
methods: {
handle: function(){
//4、销毁事件 通过hub.$off()方法名销毁之后无法进行传递数据
hub.$off('tom-event');
hub.$off('jerry-event');
}
}
});
script>