Vue的组件以及数据传递

1-组件化开发:
我们可以很直观的将一个复杂的页面分割成若干个独立组件,每个组件包含自己的逻辑和样式,再将这些独立组件组合完成一个复杂的页面。这样既减少了逻辑复杂度,又实现了代码的重用。页面是组件的容器,组件自由组合形成完整的页面,当不需要某个组件时,或想要替换某个组件时,可以随时进行替换和删除,而不影响整个应用的运行。
2-组件化开发的好处
提高开发效率
方便重复使用
便于协同开发
更容易被管理和维护
3-VUE中组件的特点
vue中一个自定义标签(不是W3C规定的标准标签如div、p等),vue就会把他看成一个组件
不能光写一个自定义的标签而不赋予意义
4-组件分类
页面级组件:
1)一个页面是一个组件
2)将可复用的部分抽离出来 基础组件

全局组件:声明一次 可以在任何地方使用

局部组件:必须告诉这个组件属于谁
一般写插件的时候或者很多人都要用,使用全局组件的多一些。
//1.组件名不要带有大写,多个单词用-连接
//2.只要组件名和定义的名字相同时可以的(首字母可以大写,中间不要有大写)
//3.html采用短横线隔开命名法 JS中转驼峰也是可以的
定义全局组件

Vue.component('my-handsome',{ //一个对象可以看成一个组件
//在自己定义的模板中取自己data返回的数据
template:'<div>{{msg}}</div>',
//组件中数据必须是函数类型,返回一个实例作为组件的数据
data(){
return {msg:'我很英俊'}
}
})
let vm=new Vue({
el:'#app',
data:{
........
}
})

定义局部组件
局部组件使用的三部曲:
1.创建这个组件
2.注册这个组件
3.使用这个组件
组件是相互独立的,不能直接跨作用域(子组件不能直接使用父组件的data)
vm的实例也是一个组件,自定义组件中也拥有声明周期函数

//如果组件共用了数据,会导致同时刷新,但是组件应该是独立性的
//为什么会独立呢?
//因为data是一个函数,return 出去是一个新对象,新对象那就是一个独立的作用域。
// 所以组件中的data要是一个函数,函数是一个作用域,return 出去一个新对象,
// 这样就与其他组件的data不冲突是独立的了

//组件理论上是可以无限嵌套的,因为vm本身就是一个组件,他里面也自定义了组件,并且自定义的组件也是一个对象,
//并且和其父级一样拥有各种属性,所以其自己又可以作为“父组件”,他里面也可以放组件

let obj={
school:'zfpx'
};
//1.创建组件
let component1={
//这里的引号问题 把里面的单引号转义一下,或者使用ES6的模板字符串
template:'<div @click="school='home'">组件一 {{school}}</div>',
data(){
return obj;
}
};
let component2={
template:'<div @click="fn">组件二 {{school}}</div>',
data(){
return obj;
},
methods:{
fn(){
//这里的this不再指向其父级vm,而是指向自己的组件
console.log(this)
}
}
}
 
 
let vm=new Vue({
el:'#app',
//2.注册组件
components:{
component1:component1, //在ES6中名字一样可以只写一个,如component2那样
component2,
},
data:{
a:1
}
})

组件嵌套
1.如果要在一个组件中使用另一个组件,先要保证使用的组件得是真实存在的,
2.在需要引用这个组件的实例通过components注册这个组件
3.组件需要在父级的模板中通过标签的形式引入

//son中要用到grandson,所以得把grandson声明到son上面
let grandson={
template:'<div>grandson</div>'
};
 
//parent中要用到儿子,所以得先把son声明到parent上面
let son={
template:'<div>son <grandson></grandson></div>',
components:{
grandson
}
};
let parent={
template:'<div>parent <son></son></div>',
components:{
son,
}
};
 
 
let vm=new Vue({
el:'#app',
template:'<parent></parent>',
components:{
parent
},
data:{
a:1
}
})

父子组件数据传递(父传子)
组件的传递:
父亲 -> 儿子 -> 孙子 (属性传递)
孙子 -> 儿子 -> 父亲 (事件传递)
html结构

父亲:{{money}}

父传子流程: - 1.首先子组件嵌套在父组件内(结构) - 2.在html中给子组件的标签中 加上自定义属性 并赋值,这个值就是要在父组件中得到的数据,既然是数据,肯定要是变量,所以我们要给 这个属性前面加上:,叫做动态绑定 - 3.在JS中子组件里,props接收(获取)在上一步中子组件中定义的属性值 - 4.然后在子组件定义的模板中就可以用获取到的属性值了

//这个实例就是一个组件,parent
let vm=new Vue({
el:’#app’,
components:{
child:{
//会在当前子组件上声明一个m属性,值是父亲的。(儿子通过props获取到父亲的m属性值)相当于 this.m=100
//如果props是一个数组,他不能校验里面获取到的值是什么类型,把其变成一个对象,里面有几个方法如下:
//props:[‘m’,‘a’],
props:{
//校验时不能阻断代码的执行,只是警告而已
m:{ //校验属性的类型,如果不带:,得到的肯定是字符串类型,只有:m="1"才是数字类型1,:m="true"才是布尔类型
type:[String,Boolean,Function,Object,Array,Number],
//如果什么都不传,会调用default,要给一个默认值,否则就是false了
default:0,
//此属性是必须传递的意思,但不能与default同用
required:true,
//自定义校验器 第一个参数是当前传递的值,返回true表示通过,false表示不通过
validator(val){
return val>300
}
}
},

data(){
return {n:5} //有了上面的props中的m了,就不能再让自己data(包括methods等其他对象中)中有m了,会冲突
},

template:‘

儿子:{{m}} {{n}}
’,
//如果想在child中取的值名跟parent保持一致,我们可以用computed属性;但是这样很麻烦,直接在child上设置属性的时候
//设置成跟parent一样的名字就好了
// computed:{
// money(){return this.m}
// },
}
},
data:{
money:400
}
})
父子组件数据传递(子传父)
父亲绑定一些事件,儿子触发这个事件,将参数传递过去 、
单项数据流:(儿子不能改爸爸的数据,告诉爸爸让他改,父亲数据刷新后,儿子就刷新了)
html结构

父亲:{{money}}

子传父流程:

  • 1.首先在父可以传子的基础上,给child一个自定义事件,并且这个自定义事件是父亲的方法

2.在子组件的methods中定义一个儿子的方法,并且这个方法是要传递(发射)给上一步儿子的自定义方法的,第一个参数是
child上自定义的事件名,第二个参数是要传递的值
3.于是当子组件中的方法触发(点击、双击等等)时,父亲的方法就收到了儿子发射的方法中传递的值,然后更新自己的数据即可。
//这个实例就是一个组件,parent
let vm=new Vue({
el:’#app’,
data:{
money:400
},
methods:{
//相当于发布订阅的on
things(val){
this.money=val;
}
},
components:{
child:{
props:[‘m’],
template:‘

儿子:{{m}} <button @dblclick=“getMoney()”>多要钱
’,
methods:{
getMoney(){
//触发自己的自定义事件,让父亲的方法执行 相当于发布
this.$emit(‘child-msg’,800)
}
},

}
},

})

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值