什么是组件化呢:其实就是对于ui界面的封装,把能够复用的ui元素封装起来
什么是模块化呢:其实就是对于代码的封装,将能够复用的代码封装起来
组件化的优势:
1. 便于复用
2. 便于维护
3. 便于分工
在Vue中注册组件的方式:
1、全局注册:
<script>
Vue.component("my-header", {
template: "<div class='top'>这是头部</div>"
})
const vm = new Vue({
el: "#app"
})
</script>
2、局部注册:
<script>
const vm = new Vue({
el: "#app",
components: {
"my-header": {
template: "<div class='top'>这是头部</div>"
}
}
})
</script>
如何使用注册的组件:在页面中使用已经注册好的组件,只需要,将组件名作为标签名,书写标签即可
<div id="app">
<my-header></my-header>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
注意:
组件名中不能包含大写字母,如果需要将多个单词分隔开,需要使用- 中划线进行分割
全局注册的,所有vue实例中都可以使用
局部注册的,只能在当前vue实例中使用
Vue组件其实就是一个特殊的vue实例,传递的参数对象,基本和vue实例的参数对象一致
区别: data 的写法不一样
组件中的data是一个函数,返回一个对象,这个对象就是数据对象!
vue组件中的data必须是个函数的目的:就是为了保证组件实例之间不会相互影响!
模板使用数据的方式,和之前在vue实例中使用数据的方式完全一样!
Vue.component("myheader", {
template: "<div>这是一个组件{{msg}}</div>",
data(){
return {
msg: "Hello world"
}
}
})
const vm = new Vue({
el: "#app"
})
组件中注册事件:
<body>
<div id="app">
<myheader></myheader>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
// 组件的模板中必须有一个根元素,否则会报错!
Vue.component("myheader", {
template: "<div><div>这是一个组件{{msg}} <button @click='clickHandler'>按钮</button></div><br> <input type='text' v-model='num1'> + <input type='text' v-model='num2'> = <span>{{result}}</span></div>",
data(){
return {
msg: "Hello world",
num1: 0,
num2: 0
}
},
methods: {
clickHandler(){
alert(123)
}
},
computed: {
result(){
return +this.num1 + +this.num2;
}
}
})
const vm = new Vue({
el: "#app"
})
</script>
</body>
组件之间的通信:
1、父 --》子 :将父组件的数据传到子组件
<body>
<div id="app">
<father></father>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
//如何把父组件中的数据传递给子组件使用? 父到子的传值(属性传值)
//1. 在父组件中使用子组件的时候,给子组件的标签中,添加一个属性,这个属性就是用来传递数据的
//2. 这个属性应该使用动态绑定的方式传递 需要加上:
//3. 在子组件的参数对象中,添加一个props属性
//4. 这个属性是一个数组,数组中存放点的,就是父组件传递数据的时候使用的属性名
//5. 在子组件中,就直接可以使用这个属性了
//注意: 父组件中的数据发生变化之后,子组件中接收到的数据也会随之变化
Vue.component("father", {
template: `<div>这是父组件:<son :msgfromfather="msg" :numfromfather="num"/></div>`,
data(){
return {
msg: "这是父组件中的数据",
num: 9999
}
}
})
Vue.component("son", {
template: "<div>这是子组件{{msgfromfather}}, {{numfromfather}}</div>",
props: ["msgfromfather", "numfromfather"]
})
const vm = new Vue({
el: "#app"
})
//子组件接收到的数据会随父组件变化
Vue.component("father", {
template: `<div>这是父组件:<input type="text" v-model="msg"/><son :msgfromfather="msg" :numfromfather="num"/></div>`,
data(){
return {
msg: "这是父组件中的数据",
num: 9999
}
}
})
Vue.component("son", {
template: "<div>这是子组件{{msgfromfather}}, {{numfromfather}}</div>",
props: ["msgfromfather", "numfromfather"]
})
const vm = new Vue({
el: "#app"
})
//子组件中修改富父组件传递过来的数据,会不会改变父组件中的数据
//父组件传递给子组件的数据,子组件是不可以进行修改的!
//单向数据流!
Vue.component("father", {
template: `<div>这是父组件:<input type="text" v-model="msg"/><son :msgfromfather="msg" :numfromfather="num"/></div>`,
data(){
return {
msg: "这是父组件中的数据",
num: 9999
}
}
})
Vue.component("son", {
template: `<div>这是子组件 <button @click="clickHandler">修改父组件的数据</button>{{msgfromfather}}, {{numfromfather}}</div>`,
props: ["msgfromfather", "numfromfather"],
methods: {
clickHandler(){
this.numfromfather = 6666;
}
}
})
const vm = new Vue({
el: "#app"
})
</script>
</body>
2、子 --》父 :将子组件的数据传到父组件
<body>
<div id="app">
<father></father>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
// 在实际开发过程中,也会遇到,需要子组件将数据传递给父组件去使用的情况
// 比如: 日期组件
// 父组件给子组件传值,用的是属性传值,而且是在标签中直接书写,代码一运行起来,数据就会传递过去
// 子组件给父组件传值,是通过事件传值的
// 在父组件中使用子组件的时候,我们需要给子组件标签,绑定一个函数,这个函数就是用来接收数据的
// 1. 需要在父组件中先声明一个函数出来,这个函数可以接收一个参数
// 2. 将这个函数通过@绑定给子组件标签
// 3. 在子组件中要给父组件传递数据的时候,通过this.$emit("绑定的函数的名称"),调用父组件中的函数,把自己的数据当做参数传递过去
// 4. 在父组件中,就可以拿到这个数据了
// 子组件给父组件传值(事件传值)
Vue.component("father", {
template: `<div>这是父组件:儿子的来信{{msgFromSon}}<son @sendmsg="getMsgFromSon"/></div>`,
data(){
return {
msgFromSon: ""
}
},
methods: {
getMsgFromSon(value){
// console.log("儿子来信了:说啥来着,看一下:" + value)
this.msgFromSon = value;
}
}
})
Vue.component("son", {
template: "<div>这是子组件 <button @click='sendMsgToFather'>发消息给父亲</button></div>",
data(){
return {
msg: "想父亲了",
}
},
methods: {
sendMsgToFather(){
// 这个点击事件中,我们需要把子组件中的msg发送给父组件去使用
this.$emit("sendmsg", this.msg)
}
}
})
const vm = new Vue({
el: "#app"
})
</script>
</body>
3、非父子组件的之间的通信:
非父子组件之间通过一个空的Vue实例来传递数据。
const bus = new Vue(); //bus:公交车 事件总线
核心逻辑 :
组件A给组件B传值:
1. 组件A给bus注册一个事件,监听事件的处理程序
2. 组件B触发bus上对应的事件,把 值当成参数来传递
3. 组件A通过事件处理程序获取数据
<body>
<div id="app">
<brother-a></brother-a>
<brother-b></brother-b>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
// globel-event-bus 全局事件总线
const bus = new Vue();
Vue.component("brotherA", {
template: "<div>这是熊大</div>",
methods: {
getMsgFromBear2(value){
console.log("熊二来信了:"+value)
}
},
created(){
// $on是用来注册事件的
// bus.$on("事件名", 事件函数)
bus.$on("getMsg", this.getMsgFromBear2)
}
})
Vue.component("brotherB", {
template: "<div>这是熊二 <button @click='sendMsgToBearBig'>通知熊大</button></div>",
data(){
return {
msg: "熊大,光头强又来砍树了"
}
},
// 触发bus事件
methods: {
sendMsgToBearBig(){
bus.$emit("getMsg", this.msg);
}
}
})
const vm = new Vue({
el: "#app"
})
</script>
</body>