组件:拆分vue实例代码量,不同的组件来划分不同的功能模块,需要什么功能调用什么组件
组件化与模块化的不同:
1.模块化是从代码逻辑的角度进行划分,方便代码分层开发,保证每个功能模块职能单一。
2.组件化是从ui界面的角度划分
全局组件
语法格式
第一种
Vue.component('组件名称',{
template:"<div></div>"//组件html结构
})
第二种
//app操作区域外定义组件html
<template id="cmp1">
<div></div>
</template>
Vue.component('组件名称',{
template:"#cmp1"
})
使用组件
直接在页面上将组件名以html标签展示即可,需要注意的是驼峰命名使要转换为-
型 ,如组件名称为parentCmp
那么页面展示就是<parent-cmp></parent-cmp>
示例定义一个全局组件
<div id="app">
<login></login>
</div>
<script type="text/javascript">
Vue.component('login',{
template:"<div>登录组件</div>"
})
var vm = new Vue({
el:"#app",
data:{},
methods:{}
})
</script>
私有组件
全局组件在任何vm对象中都能使用,有时候我们希望组件只在当前vm对象生效
示例定义一个私有组件
<div id='app'>
<h1>app</h1>
<logins></logins>
<login></login>
<register></register>
</div>
<div id="app2">
<h1>app2</h1>
<logins></logins>
<login></login>
<register></register>
</div>
Vue.component('logins',{
template:"<div>登录全局组件</div>"
})
var vm = new Vue({
el:"#app",
data:{},
methods:{},
components:{
login:{
template:"<div>登录组件</div>"
},
register:{
template:"<div>注册组件</div>"
}
}
})
var vm2 = new Vue({
el:"#app2"
})
同样组件也可以有data,methods等属性不过需要注意的是组件的data必须是一个函数,这个函数在返回一个对象
组件切换
有时候我们会用到组件切换,如点击登录时弹出登录组件,点击注册弹出注册组件 简单的组件切换我们可以通过v-if
实现,如注册登录
<div id='app'>
<a href="#" @click.prevent="flag=true">登录</a>
<a href="#" @click.prevent="flag=false">注册</a>
<login v-if="flag"></login>
<register v-else="flag"></register>
</div>
var vm = new Vue({
el:"#app",
data:{
flag:true
},
methods:{},
components:{
login:{
template:"<div>登录组件</div>"
},
register:{
template:"<div>注册组件</div>"
}
}
})
如果切换的组件较多,用这种方式就不能满足需求,我们可以通过vue提供的<component :is="组件变量">
来实现组件切换 我们还可以用<transition>
将<component>
包裹起来为组件切换添加动画效果 示例
<div id="app">
<a href="#" @click.prevent="cmpName='one'">one</a>
<a href="#" @click.prevent="cmpName='two'">two</a>
<a href="#" @click.prevent="cmpName='three'">three</a>
<component :is="cmpName"></component>
</div>
var vm = new Vue({
el:"#app",
data:{
cmpName:"one"
},
components:{
one:{
template:"<div>one</div>"
},
two:{
template:"<div>two</div>"
},
three:{
template:"<div>three</div>"
},
}
})
组件传参
1.通过v-bind
与props
<div id="app">
<child v-bind:parent="msg"></child>
</div>
<script type="text/javascript">
var vm = new Vue({
el:"#app",
data:{
msg:"父组件内容"
},
methods:{},
components:{
child:{
props:['parent'],
template:"<div>这是子组件----{{parent}}</div>"
}
}
})
</script>
通过v-bind绑定变量,在子组件中使用props
接收变量即可
父子组件互调方法
子组件调用父组件方法 通过$emit
<div id="app">
<child @fn="hi"></child>
</div>
var vm = new Vue({
el:"#app",
data:{},
methods:{
hi(){
alert('Hi')
}
},
components:{
child:{
template:"<div><button type='button' @click='childHi()'>调用父组件方法</button></div>",
methods:{
childHi(){
this.$emit('fn')
}
}
},
}
})
父组件调用子组件的方法 通过$refs
<div id="app">
<button type="button" @click="childHi()">调用子组件方法</button>
<child ref="child"></child>
</div>
var vm = new Vue({
el:"#app",
data:{},
methods:{
childHi(){
this.$refs.child.Hi();
}
},
components:{
child:{
template:"<div></div>",
methods:{
Hi(){
alert('调用子组件的方法')
}
}
},
}
})
关于$refs
的说明,在Vue中是不提倡DOM操作的,可有时候我们就是要查找一下元素,如获取某个元素的innerText这个时候,我们肯定不能用原生document.get......
对于此Vue中提供了$refs
通过他即可实现查找元素,我们只需给要查找的元素添加ref
属性并赋予相应的名称即可,使用时直接
this.$refs.元素名称
即可 同时$refs
还可以用在组件上如上面案例通过$refs
实现父组件调用子组件方法。