组件
原因:使用组件可以提升代码的复用性,非常的方便,节省了很多时间成本。
由于组件设计的知识点较多,所以就分为两个部分写,这里先写上半部分。
主要包括以下几点:
1、组件的使用方法
2、组件使用时的一些奇技淫巧
3、父子组件传递数据
4、单向数据流
5、数据验证及命名规则
6、组件通信
1、组件的使用方法
组件的使用方法分为两点:全局注册和局部注册
1.1、全局注册
用法:Vue.component(‘tag’,{template:’…’})
<div id="app">
<tag></tag>
</div>
Vue.component('tag',{
template:'<div>这里是全局注册的组件</div>'
})
var app = new Vue({})
//这里页面上就会把template的值渲染出来
注意的地方:template的内容一定需要dom元素包括起来,就算没有内容也要写
template:'<div></div>' 不写的话会报错
优点:由于是全局变量,所有的vue实例都可以使用
缺点:权限太大,容易出错,所以尽量使用局部注册的组件
1.2、局部注册
用法:在vue实例中使用,在与data同级的components中写
<div id="app">
<tag></tag>
</div>
var app = new Vue({
el:"#app",
data:{},
components:{
'tag':{
template:'<div>这里是局部注册的组件</div>'
}
}
})
//页面上会显示 这里是局部注册的组件
1.3、html标签限制
也有部分html标签无法直接挂载组件,比如table中只有tr td tbody等元素,无法直接挂载组件。
这时候使用 is 属性来挂载组件就可以了
<table>
<tbody is="appTag"></tbody>
</table>
components: {
'appTag': {
template: '<div>我这里是局部注册</div>'
}
}
2、组件使用时的一些奇技淫巧
1、组件的命名使用时需按照小写字母加横杠的形式才更加规范,如:app-tag
2、template中的内容必须被一个dom元素包括起来,不能是单纯的字符串
3、在组件中也可以使用 data,computed,methods ,但data在使用时必须是一个方法
需求:两个按钮上各有数字,每点击一次数字增加1
<btn-comp></btn-comp>
<btn-comp></btn-comp>
data{},
components:{
'btn-comp':{
template:'<button v-on:click="count++">{{count}}</button>',
data:function(){
return {
count: 0
}
}
}
}
3、父子组件之间的数据传递
子组件:局部注册的组件都叫做子组件
父组件:vue绑定的那个id="app"的div元素(根元素)就是父组件
1、在子组件中使用props从父组件接受参数,并且props中接收到的属性,都可以在子组件中直接使用
2、props属性中的数据来自父组件,而子组件中data的返回值 return 就是子组件自己的数据,与父组件无关
作用域:props和data的作用域一样,都只能在子组件本身使用,也可以在子组件内的methods,computed,template中使用
<!--在这里传进去的数据,都是父组件的数据-->
<chlid-comp msg="我是来自父组件的内容"></child-comp>
data{},
components:{
'child-comp':{
props:['msg'],
template:'<div>{{msg}}</div>'
}
}
//网页上会显示出 我是来自父组件的内容
3、也可以使用v-bind进行数据的动态绑定
需求:把input中的msg传递到子组件中
<input type="text" v-model="msg">
<bind-comp v-bind:childMsg="msg"></bind-comp>
data:{
msg:'我是v-model绑定的数据'
},
components:{
'bind-comp':{
props:['childMsg'],
template:'<div>{{childMsg}}</div>'
}
}
//你在input框中输入什么,下面就会显示什么
4、单向数据流
概念:通过props传递数据的操作是单向传递,只能通过父组件传递到子组件中,无法通过子组件传递到父组件
目的:这样设定的目的是为了避免子组件无意中修改了父组件中的数据
应用场景:经常会遇到两种需要改变 props 的情况
4.1 父组件传递数据到子组件,子组件将该数据作为初始值保存,在自己的作用域下进行修改和使用
这时候可以现在子组件data内声明一个数据,引用父组件的props
步骤1:注册组件
步骤2:将父组件的数据传递进来,并在子组件中用props引用
步骤3:将传递的数据通过初始值保存起来,后面只要维护这个初始值就好了
<app-tag msg="我是父组件传入的数据"></app-tag>
data:{},
components:{
'app-tag':{
props:['msg],
template:'<div>{{words}}</div>'
data:function(){
return {
words: this.msg
}
}
}
}
//需要注意的是这里的retun内是 words : this.msg 而不是 =
4.2、props作为需要被转变的原始值传入,这种情况用计算属性就可以了
步骤1:注册组件
步骤2:将父组件的数据传递进来,并用props接收
步骤3:将传递的数据通过计算属性重新进行计算
需求:随着input输入框的值改变红色方块的长度
<input type="text" v-model="widthMethods">
<!--这里的num可以理解为专门用来接收父组件数据的一个变量-->
<width-tag v-bind:num="widthMethods"></width-tag>
data:{
widthMethods:100
},
components:{
'width-tag':{
props:['num'],
template:'<div v-bind:style="styleMethods"></div>',
computed:{
styleMethods:function(){
return {
width: this.num + 'px',
background: darkred,
height: '50px'
}
}
}
}
}
5、数据验证及命名规则
命名规则:
1、在html中, myMessage 和 mymessage 是一致的,因此在组件中的html中使用必须使用kebabcase(短横线)命名方式。在html中不允许使用驼峰!
2、在组件中, 父组件给子组件传递数据必须用短横线。在template中,必须使用驼峰命名方式,若为短横线的命名方式。则会直接保错。
3、在组件的data中,用this.XXX引用时,只能是驼峰命名方式。若为短横线的命名方式,则会报错。
总结:
1、html里面要用短横线<br>
<my-component></my-component>
2、父组件给子组件传递的数据必须用短横线<br>
<input type="text" msg-component="我是父组件的内容">
3、组件里面的data用驼峰<br><br>
data:function(){
return {
this.msgText
}
}
数据验证
验证的 type 类型可以是,emmmm,这个没啥好讲的
• String
• Number
• Boolean
• Object
• Array
• Function
组件通信
组件关系:vue中有父子组件通信、兄弟组件通信、跨级组件通信这三种
用法:
1、使用v-on,v-on除了监听DOM事件外,还可用于组件之间的自定义时间
2、子组件用 emit 来触发事件,父组件用on来监听事件
步骤1:先自定义一个时间
步骤2:在子组件中用emit触发事件,第一个参数是事件名,后面的参数是要传递的数据
步骤3:在自定义事件中用一个参数来接收这个数据
需求:通过加号按钮和减号按钮来给父组件传递数据
银行卡余额:{{total}}
<!--这里的change就是自定义事件-->
<btn-comp v-on:change="handleTotal"></btn-comp>
data:{
total: 1000
},
methods:{
//这里的参数 value 就是 this.$emit() 传递过来的数据
handleTotal:function(value){
//直接赋值就可以
this.total = value
}
},
components{
'btn-comp':{
template:'<div>\
<button v-on:click="increase">+1000</button>\
<button v-on:click="reduce">-1000</button>\
</div>\ ',
data:function(){
return {
//在子组件内定义一个count,对count进行操作,然后把count赋值给total
count: 1000
}
},
methods:{
increase:function(){
this.count = this.count + 1000
//写好触发事件$emit(),第一个参数是事件名,第二个是参数,可以有多个
this.$emit('change',this.count)
},
reduce:function(){
this.count = this.count - 1000
this.$emit('change',this.count)
}
}
}
}