理解组件化
在大型应用开发的时候,往往要有大量的页面。
这些页面,又往往会有相同的部分,比如会有相同的头部导航、相同的底部页尾。
这些相同的部分,我们就可以把它封装为一个独立的组件,然后在不同的页面中使用它,避免重复开发。
全局注册
全局注册的组件,任何Vue实例都可以引用。
演示
<div id="app">
<!-- 使用组件 -->
<counter></counter>
</div>
<script type="text/javascript">javascript">
// 定义组件
const counter = {
template: "<button @click='num++'>你戳了我{{num}}次~</button>",
data() {
return {num: 0};
}
};
// 全局注册组件(参数1:自定义组件名,参数2:真正的组件)
Vue.component("counter", counter);
// Vue实例
var app = new Vue({
el: "#app",
});
</script>
说明
❶ 组件本质上也是一个Vue实例;Vue实例也可以看成是一个组件。
❷ 组件中也可以定义data、methods、钩子函数…但是没有el属性,毕竟绑定了页面元素后还怎么复用呢?所以说:组件是一个不需要绑定页面元素的Vue实例。
❸ 组件不需要绑定模板(元素),但组件自带模板(元素)——即template属性。
❹ 组件的data非常特殊,它是一个返回对象的函数。请尝试理解一下:组件可以复用多个,但它们必须彼此独立,通过返回一个对象,每一个组件的数据也就有了一个独立的作用域。
局部注册
局部注册的组件,只有当前的Vue实例可以引用。
演示
<div id="app">
<!-- 使用组件 -->
<counter></counter>
</div>
<script type="text/javascript">javascript">
// 定义组件
const counter = {
template: "<button @click='num++'>你戳了我{{num}}次~</button>",
data() {
return {num: 0};
}
};
// Vue实例
var app = new Vue({
el: "#app",
components: {
// 局部注册组件(左侧:自定义组件名,右侧:真正的组件)
counter: counter
}
});
</script>
说明
❶ 总的看来,全局注册的组件可引用范围较大,局部注册的组件可引用范围较小。具体选择哪种注册,要具体分析某个模块所出现的区域——仅仅在一个页面的角落出现多次?还是在多个页面都会出现?
❷ 关于组件的作用域,也可以这样来理解记忆——全局注册是写在javascript当中的,所以它的作用域是任何地方;局部注册是写在vue实例当中的,vue实例绑定了一个el属性,局部注册的组件自然也被绑定在这个el元素的内部了。
❸ 没别的好说的了 >_<。
父组件向子组件通信
Demo1:子组件使用了父组件的数据(简单数据类型)
<div id="father">
<son v-bind:title="msg"></son>
</div>
<script type="text/javascript">javascript">
// 定义组件
const son = {
// 子组件中渲染了title,但子组件并没有title啊?
template: "<h2>{{title}}</h2>",
// 原来这个title是从父组件那里接收过来的!
props: ["title"]
};
// 注册组件
Vue.component("son", son);
// Vue实例
var father = new Vue({
el: "#father",
data: {
msg: "我是父组件的数据信息~"
}
});
</script>
Demo2:子组件使用了父组件的数据(复杂数据类型)
<div id="father">
<son v-bind:lolis="msg"></son>
</div>
<script type="text/javascript">javascript">
// 定义组件
const son = {
// 子组件中渲染了lolis,但子组件并没有lolis啊?
template: "<ul><li v-for='loli in lolis'>{{loli}}</li></ul>",
// 原来这个lolis是从父组件那里接收过来的!
props: {
lolis: {
// 数据类型(Array/Object)
type: Array,
// 默认值
default: []
}
}
};
// 注册组件
Vue.component("son", son);
// Vue实例
var father = new Vue({
el: "#father",
data: {
msg: ["Alice", "Hana", "Mana"]
}
});
</script>
子组件向父组件通信
Demo3:子组件中调用父组件的方法从而改变父组件的数据
<div id="father">
<h2>{{num}}</h2>
<son @incnumber="inc" @decnumber="dec" v-bind:number="num"></son>
</div>
<script type="text/javascript">javascript">
// 定义组件
const son = {
template: "<div><button @click='increase'>加1</button><button @click='decrease'>减1</button></div>",
props: ["number"],
methods: {
increase() {
return this.$emit("incnumber");
},
decrease() {
return this.$emit("decnumber");
}
}
};
// 注册组件
Vue.component("son", son);
// Vue实例
var father = new Vue({
el: "#father",
data: {
num: 0
},
methods: {
inc() {
this.num++;
},
dec() {
this.num--;
}
}
});
</script>
❤️