组件化
1、定义全局组件
1、要在父实例中使用某个组件,组件必须在实例值之前定义
2、组件其实也是一个Vue实例,因此它在定义时也会接收:data、methond、生命周期函数等
3、不同的组件不会与页面的元素绑定,否则就无法复用了因此也没有el属性
4、组件渲染需要html模板,所以增加了template属性,值就是HTML模板,模板的内容必须由html双标记包裹
5、全局组件定义完毕,任何vue实例都可以直接在html中通过组件名称来使用组件了
6、data定义方式比较特殊,必须是一个函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>全局组件</title>
</head>
<body>
<div id="app">
<!--使用定义好的全局组件-->
<counter></counter>
<counter></counter>
</div>
</body>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
// 定义全局组件,两个参数:1、组件名词 2、组件参数
Vue.component("counter",{
template:`<button v-on:click="count++">你点了我{{count}}下</button>`,
data(){
return{
count:0
}
}
});
var app = new Vue({
el:"#app"
});
</script>
</html>
2、组件的复用
定义好的组件可以任意复用多次
<div id="app">
<!--使用定义好的全局组件-->
<counter></counter>
<counter></counter>
<counter></counter>
</div>
3.局部注册
一旦全局注册,就意味着即便你以后不再使用这个组件,它依然会随着Vue的加载而加载,因此,对于
一些并不频繁使用的的组件,我们采用局部注册
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>局部组件</title>
</head>
<body>
<div id="app">
<increase></increase>
<br>
<increase></increase>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
const increase = {
template:`<button v-on:click="count++">点我加{{count}}</button>`,
data(){
return{
count:0
}
}
};
var app = new Vue({
el:"#app",
components:{
increase: increase //将定义的对象注册为组件
/*
* components就是当前vue对象子组件集合
其中key就是子组件名称
其值就是组件对象的属性
* */
}
});
</script>
</body>
</html>
4、组件的通信
4.1 父向子简单通信
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>父向子通信</title>
</head>
<body>
<div id="app">
<h1>大家好,给大家介绍一下</h1>
<!--使用子组件,同时传递title属性-->
<sun title="我来自火星"></sun>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
Vue.component("sun",{
//直接使用props接收到的属性来渲染页面
template:`<h1>{{title}}</h1>`,
props:['title'] //通过props来接收一个父组件传递的属性
});
var app = new Vue({
el:"#app"
});
</script>
</body>
</html>
4.2 父向子复杂通信
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>父向子复杂的通信</title>
</head>
<body>
<div id="app">
<h2>我喜欢这些语言:</h2>
<!--使用子组件的同时,传递属性,这里使用了v-bind,指向了父组件自己的属性,language-->
<my-list :items="language"/>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
//定义一个子组件
let myList = {
template:`<ul>
<li v-for="item in items" :key="item.id">{{item.id}}:{{item.name}}</li>
</ul>`,
props:{
items:{
type:Array, //限定父组件传递来的必须是数组,否则报错
default:[] //默认值
}
}
};
var app = new Vue({
el:"#app",
components:{
myList //当key和value一样时,可以只写一个
},
data:{
language:[
{id:1,name:'Java'},
{id:2,name:'JavaScript'},
{id:3,name:'C语言'},
{id:4,name:"Python"}
]
}
});
</script>
</body>
</html>
4.3 子向父通信
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>子向父通信</title>
</head>
<body>
<div id="app">
<h2>num: {{num}}</h2>
<!--使用子组件的时候,传递num到子组件中-->
<!--通过v-on指令将父组件的函数绑定到子组件上-->
<counter :num="num" @inc="increase" @dec="decrease"></counter>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
Vue.component("counter",{
//定义组件,定义两个按钮,点击数字num或加或减
template:`<div>
<button @click="plus">+</button>
<button @click="reduce">-</button>
</div>`,
//当子组件中的按钮被点击时,调用绑定的函数
methods:{
plus(){
this.$emit("inc"); //vue提供的内置的this.$emit函数,用来调用父组件绑定的函数
},
reduce(){
this.$emit("dec");
}
}
});
var app = new Vue({
el:"#app",
data:{
num:0
},
methods:{//父组件定义操作num的方法
increase(){
this.num ++;
},
decrease(){
this.num --;
}
}
});
</script>
</body>
</html>