组件与实例
组件和实例的区别
- 组件的使用和实例极其相似,实例所拥有的,组件几乎一应俱全
唯一需要注意的是data的使用
var vm= new Vue({});//实例
Vue.component//组件
# 全局组件
```js
Vue.component("merciBeaucoup", {
//组件必须要有该属性
template: "<h1> {{hello}} this is a {{msg}} {{value}} <h1>",
//组件的data是一个方法
data() {
//一般写法是定义数据,然后集中return
var msg="child";
var value="components";
//此处返回的是一个对象,所以即使只有一个数据,也需要将数据放到{}里面
// return value;//此处会报错
return {
msg:"niubi",
value:58,
hello:"hello"
}
},
mounted(){
获取数据
var msg =this.msg;
var msg2=this.$data.msg;
//解构赋值
var {msg,value}=this.$data;
console.log(msg==msg2);
}
})
全局组件-模板
可以使用模板生成指定格式的html数据,并可以传入数据
1.定义模板
<template id="testTemp">
<div>
<!-- 再提示,组件不识别驼峰 -->
<!-- {{msg}} this is a test temp {{parentmsg}} -->
{{obj}}{{obj.username }}
</div>
</template>
2.关联指定模板
Vue.component("merciBeaucoup", {
//其实就是把template独立出来
template: "#testTemp",
//父子传值 记得很重要的东西,组件不识别驼峰
// 父给子传值,可以传对象,数组,还有方法
// props:["parentmsg","obj"],
//props可以设定值的默认值/类型,但是在传递的时候,依然可以把其他值传递进来
props:{
parentmsg:{
type:String,
default:"mamamia"
}
},
data() {
var msg="child";
var value="components";
return {
msg,
value,
hello:"hello"
}
}
})
局部组件
局部组件其实与全局组件义指,只是写在vue里面
var vm = new Vue({
el: "#app",
data:{
parentMsg:"this is parent msg",
obj:{
username:"niubi",
age:10
}
},
//与全局组件一模一样
components:{
"zengyu1":{
template:"<h1> this is {{msg}} {{obj.username}}--{{obj.age}}</h1>",
data(){
return {
msg:"zengyu1"
}
},
props:["obj"]
},
"zengyu2":{
template:"<h1> this is zengyu2</h1>"
}
}
})
- 总结:
组件中data是唯一一个函数,且必须要返回一个对象
组件没有el属性
template代表的是页面结构,故只能有一个根节点,即根节点标签不能有多个
组件使用时不支持驼峰命名(例如merciBeaucoup) ,一般是merci-beaucoup
组件的名称可以用驼峰,但是使用时必须要用横线隔开,并小写
template:"<h1></h1><h2></h2>"
父子组件–传值
子获取父:
1.在data中定义属性用于接收并保存父类数据
2.在mounted中定义使用this.$parent来获取父类数据
注意:子组件中
//最外层绑定为组件名称
Vue.component("compon1",{
template:"#temp1",
data(){
var childmsg="i am a child compon1";
var childuser={
name:"child",
age:100
};
fatherusershowchild={
type:String,
default:""
}
return{
childmsg,
childuser,
fatherusershowchild
}
},
mounted(){
//通过this.$father中获取数据
this.fatherusershowchild=this.$parent.parentUser;
}
});
父获取子:与上述类似,也是在mounted中获取数据
1.在data中定义属性用于保存数据
2.在mounted中通过this.KaTeX parse error: Expected '}', got '#' at position 57: … el:"#̲app", …children[0].childuser);
this.childUserShowFather=this.$children[0].childuser;
}
});
父子组件调用
这里有两个重要的属性
props:父组件可以使用 props 把数据传给子组件
$emit:子组件可以使用
e
m
i
t
触
发
父
组
件
的
自
定
义
事
件
v
m
.
emit 触发父组件的自定义事件 vm.
emit触发父组件的自定义事件vm.emit( event, arg ) //触发当前实例上的事件
vm.$on( event, fn );//监听event事件后运行 fn;
子组件传递数据给父组件
子组件向父组件传递数据
1.子组件中mounted中使用$.emit定义传递
$.emit(eventname,value)
第一个参数是传递名。(不能是驼峰)
第二个参数是传递的值,可以传递多个
this.$emit("niupi","i am a child component","i am very powerful");
2.子组件自定义一个执行,来连接父实例的方法
此处的niupi就是定义的传递名
clickMe是是父组件的一个方法
//子组件自定义一个执行,来连接父实力的方法
<component1 @niupi="clickMe"></component1>
//1.组件传值时,属性不能用大写
// 2.子组件触发父组件方法时,父组件的注册绑定事件名称,不能用大写
Vue.component("component1", {
template: "#testTemp1",
data() {
var msg="child";
var value="components";
return {
msg,
value,
hello:"hello"
}
},
mounted(){
//记得不是驼峰
//可以传入多个参数,后面加上即可
this.$emit("niupi","i am a child component","i am very powerful");
}
});
父组件向子组件传递数据
子组件中props定义数据用于接收数据;
父组件中可以在data中定义数据,当父组件时间产生变化时,子组件的数据会进行变更
注意:此数据传递时单向的,当父组件变更时,子组件数据会变更,但是子组件数据变更,父组件不会有影响,为了防止子组件修改父组件的状态
//子组件
Vue.component("component1", {
template: "#testTemp1",
props:{
obj:{
type:String,//设定数据类型
default:""
}
}
});
-//父组件:
//data中定义数据,变更时,组件值会变化
var vm = new Vue({
el: "#app",
data:{
parentMsg:"this is parent msg",
obj:{
username:"niubi",
age:10
}
},
组件间传值
常用
组件间主要是通过获取$.parent.children[i]来获取
例如我定义两个组件,并且两个组件同一个div下:
<div id="app">
<yu1></yu1>
<yu2></yu2>
</div>
组件一中,定义了clickme方法,
{temp1Msg}=this.
p
a
r
e
n
t
.
parent.
parent.children[0]:表示当前元素的第一个同胞(其实就是自己)。
this.
p
a
r
e
n
t
.
parent.
parent.children[1].triggerMethod(temp1Msg),然后执行当前元素的第二个同胞的triggerMethod方法,并将方法传入,这就是组件间传值
<script>
Vue.component("yu1",{
template:"#temp1",
data(){
var temp1Msg="tem1Msg";
//不能直接返回值,需要返回对象,不然data的值会没有key
// return temp1Msg="temp1Msg"
return {
temp1Msg
}
},
methods:{
clickMe(){
//解构也经常用
var {temp1Msg}=this.$parent.$children[0];
this.$parent.$children[1].triggerMethod(temp1Msg);
console.log(temp1Msg);
}
}
});
Vue.component("yu2",{
template:"#temp2",
data(){
return {temp2Msg:"temp2Msg"};
},
methods:{
triggerMethod(value){
alert(value);
}
}
});
var vm = new Vue({
el: "#app",
})
</script>
PS: 组件间传值,有的时候,也会使用外部实例传值,例如使用外部vue实例进行传值,或者是通过js外部的对象进行传值。只是比较少用,再次不做赘述
全代码
父子组件传值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<title>组件 父子组件传值</title>
</head>
<body>
<div id="app">
<div>{{parentMsg}} 儿子的名字是 {{childUserShowFather.name}}</div>
<compon1>
</compon1>
</div>
<template id="temp1">
<div>
{{childmsg}} 父亲的名字是{{fatherusershowchild.name}}
</div>
</template>
<script>
//最外层绑定为组件名称
Vue.component("compon1",{
template:"#temp1",
data(){
var childmsg="i am a child compon1";
var childuser={
name:"child",
age:100
};
fatherusershowchild={
type:String,
default:""
}
return{
childmsg,
childuser,
fatherusershowchild
}
},
mounted(){
//通过this.$father中获取数据
this.fatherusershowchild=this.$parent.parentUser;
}
});
var vm = new Vue({
el:"#app",
data:{
parentMsg:"i am a parent",
parentUser:{
name:"father",
age:56
},
childUserShowFather:{
}
},
//在mounted中,通过children来获取子组件的值
mounted(){
// console.log(this.$children[0].childuser);
this.childUserShowFather=this.$children[0].childuser;
}
});
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<title>父子组件方法调用</title>
</head>
<body>
<div id="app">
<div @click="showName">{{parentMsg }} </div>
<!-- <component1 @click="clickMe"> -->
<!-- 通过子组件自定义一个执行,来连接父实例的方法 -->
<component1 @niupi="clickMe">
</component1>
</div>
<template id="testTemp1">
<div>
this is temp1
</div>
</template>
<script>
//1.组件传值时,属性不能用大写
// 2.子组件触发父组件方法时,父组件的注册绑定事件名称,不能用大写
Vue.component("component1", {
template: "#testTemp1",
props:{
obj:{
type:String,//设定数据类型
default:""
}
},
data() {
var msg="child";
var value="components";
return {
msg,
value
}
},
mounted(){
//记得不是驼峰
//可以传入多个参数,后面加上即可
this.$emit("niupi","i am a child component","i am very powerful");
}
});
var vm = new Vue({
el: "#app",
data:{
parentMsg:"this is parent msg",
obj:{
username:"niubi",
age:10
}
},
methods:{
showName(){
console.log(this.obj.username)
},
// clickMe(param){
// console.log("this father's function,param:"+param)
// }
//...很常用,记得用
clickMe(...param){
console.log(param);
}
}
})
</script>
</body>
</html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<title>组件间传值 常用</title>
</head>
<body>
<div id="app">
<yu1></yu1>
<yu2></yu2>
</div>
<template id="temp1">
<div>
<h1>{{temp1Msg}}</h1>
<button @click="clickMe">clickMe</button>
</div>
</template>
<template id="temp2">
<div>
{{temp2Msg}}
</div>
</template>
<script>
Vue.component("yu1",{
template:"#temp1",
data(){
var temp1Msg="tem1Msg";
//不能直接返回值,需要返回对象,不然data的值会没有key
// return temp1Msg="temp1Msg"
return {
temp1Msg
}
},
methods:{
clickMe(){
//解构也经常用
var {temp1Msg}=this.$parent.$children[0];
this.$parent.$children[1].triggerMethod(temp1Msg);
console.log(temp1Msg);
}
}
});
Vue.component("yu2",{
template:"#temp2",
data(){
return {temp2Msg:"temp2Msg"};
},
methods:{
triggerMethod(value){
alert(value);
}
}
});
var vm = new Vue({
el: "#app",
})
</script>
</body>
</html>