vue组件使用
分3步
- 引入组件 import Home from ‘./components/Home’
- 挂载组件 components:{‘v-home’:Home’}
- 在模板中使用:
<v-home></v-home>
新建一个components文件夹存放组件
src/components/Home.vue
<template>
<div>
<h2>我是一个Home组件</h2>
</div>
</template>
src/App.vue
<template>
<div>
<v-home></v-home> <!--3、在模板中使用-->
</div>
</template>
<script>
import Home from './components/Home';//1、引入组件
export default{
data(){},
components:{
'v-home':Home, //2、挂载组件
}
}
</script>
组件嵌套:
如图:将News放在Home组件里,Home组件放在App里边。
src/components/News.vue
<template>
<div>
<h2 class="box">我是一个News组件</h2>
</div>
</template>
<style>
.box{padding:20px;border:1px solid #333;}
</style>
src/components/Home.vue
<template>
<div class="box">
我是一个Home组件
<v-news></v-news>
</div>
</template>
<script>
import News from './News.vue';
export default{
components:{
'v-news':News,
}
}
</script>
src/App.vue
<template>
<div class="box">
我是一个App组件
<v-home></v-home> <!--3、在模板中使用-->
</div>
</template>
<script>
import Home from './components/Home';//1、引入组件
export default{
components:{
'v-home':Home, //2、挂载组件
}
}
</script>
以上是组件的简单使用方法。
组件之间传值
父组件给子组件传值:
1、父组件调用子组件的时候绑定动态属性
2、子组件里通过props(props可以接收一个数组或对象,接收对象时可对数据进行校验如:{title:String},可以校验组件传过来的是否为String)接收父组件传过来的数据
父组件src/App.vue
<template>
<div>
<h1>这是App</h1>
<v-home :title="title" :run="run" :home="this"></v-home>
</div>
</template>
<script>
import Home from './components/Home.vue';
export default{
data(){
return {
title:'父组件的title'
}
},
components:{
'v-home':Home
},
methods:{
run(){
console.log('我是父组件的run方法')
}
}
}
</script>
子组件src/components/Home.vue
<template>
<div>
<h1>home----------{{title}}</h1>
<button @click="run()">父组件的run方法</button>
<button @click="getParent()">获取父组件的数据和方法</button>
</div>
</template>
<script>
export default{
props:['title','run','home'],
methods:{
getParent(){
//console.log(this.title);//这种其实不对,因为调用的是自身的
console.log(this.home.title);//这个正确
}
}
}
</script>
父组件主动获取子组件的数据和方法
1、在父组件调用子组件的时候定义一个ref
<v-home ref="header"></v-home>
2、在父组件里通过
this.$refs.header.属性
获取属性
this.$refs.header.方法
获取方法
<template>
<div>
<h1>这是app</h1>
<v-home ref="headers"></v-home>
<button @click="getChild()">获取子组件的方法</button>
</div>
</template>
<script>
import Home from './components/Home.vue';
export default{
components:{
'v-home':Home
},
methods:{
run(){
console.log('我是父组件的run方法')
},
getChild(){
console.log(this.$refs.headers.msg);
this.$refs.headers.run()
}
}
}
</script>
子组件自动获取父组件的数据和方法(使用 this.$parent)
<template>
<div>
<button @click="getParentData()">获取父组件的方法</button>
{{msg}}
</div>
</template>
<script>
export default{
data(){
return {
msg:this.$parent.msg
}
},
methods:{
run(){
console.log('这是子组件的方法');
},
getParentData(){
console.log(this.$parent.msg);
this.$parent.run()
}
}
}
</script>
非父子组件,使用事件广播的方法bus
接下来实现一个效果,通过点击按钮我们将Home组件的msg传给它的兄弟组件News,将News组件的msg传给它的兄弟组件Home
效果如下:
流程如下
1、新建一个js文件 然后引入vue 实例化vue 最后暴露出来
src/models/VueEvent.js
import Vue from 'vue';
var VueEvent = new Vue();
export default VueEvent;
2、在要广播的地方引入刚才定义的实例
import VueEvent from ‘…/model/VueEvent.js’;
3、通过VueEmit.$emit(‘名称’,‘数据’)
4、在接收数据的地方用
VueEmit.$on(‘名称’,function(data){})
src/components/Home.vue
<template>
<div>
<h1>这是home</h1>
<button @click="emitNews()">给news组件广播数据</button>
</div>
</template>
<script>
import VueEvent from '../model/VueEvent.js';
export default{
data(){
return {
msg:'点击了home组件按钮,to-news'
}
},
methods:{
emitNews(){=
VueEvent.$emit('to-news',this.msg);//推送消息
}
},
mounted(){//生命钩子函数,表示模板渲染完毕后执行的方法
VueEvent.$on('to-home',function(data){ //接收数据
console.log(data);
})
}
}
</script>
src/components/News.vue
<template>
<div>
<h1>这是news</h1>
<button @click="emitNews()">给home组件广播数据</button>
</div>
</template>
<script>
import VueEvent from '../model/VueEvent.js';
export default{
data(){
return {
msg:'点击了news组件按钮,to-home'
}
},
methods:{
emitNews(){
VueEvent.$emit('to-home',this.msg)
}
},
mounted(){//生命钩子函数,表示模板渲染完毕后执行的方法
VueEvent.$on('to-news',function(data){
console.log(data);
})
}
}
</script>
src/App.vue引入两个组件
<template>
<div>
<h1>这是App</h1>
<v-home :title="title" :run="run" :home="this"></v-home>
<v-news></v-news>
</div>
</template>
<script>
import Home from './components/Home.vue';
import News from './components/News.vue';
export default{
data(){
return {
title:'父组件的title'
}
},
components:{
'v-home':Home,
'v-news':News
},
methods:{
run(){
console.log('我是父组件的run方法')
}
}
}
</script>
递归组件
有时候我们需要组件调用自身以减少代码冗余。
使用递归组件,我们必须在组件里定义一个name属性,然后在模板 中使用标签,接下来我们实现一个类似目录的组件,效果如下:
代码如下:
App.vue,通过该组件,将数据传给子组件
<template>
<div>
<detail-list :list="list"></detail-list>
</div>
</template>
<script>
import DetailList from './components/List'
export default {
name:"App",//递归组件
data(){
return {
list:[{
"title": "标题1",
"children": [{
"title": "标题1.1",
"children": [{
"title": "标题1.1.1"
}]
},{
"title": "标题1.2"
}]
}, {
"title": "标题2"
}, {
"title": "标题3",
"children": [{
"title": "标题3.1",
"children": [{
"title": "标题3.1.1"
}]
},{
"title": "标题3.2"
}]
}, {
"title": "标题4"
}]
}
},
components:{
DetailList
}
}
</script>
components/List.vue,接收数据,如果数据中有children属性,那么递归该组件(这里vue将name为DetailList自动转化为detail-list组件)
<template>
<div>
<div class="item" v-for="(item,index) of list" :key="index">
<div class="item-title" >
{{item.title}}
</div>
<div v-if="item.children" class="item-children">
<detail-list :list="item.children"></detail-list><!--递归组件-->
</div>
</div>
</div>
</template>
<script>
export default {
name:"DetailList",//用于递归组件
props:{list:Array}
}
</script>
<style>
.item-title{
line-height:18px;
font-size:18px;
padding-top:20px;
}
.item-children{
padding-left:20px;
}
</style>
动态组件与v-once
使用<component is="component-name"></component>
来动态绑定显示的组件
使用v-once缓存需要显示的组件,即切换组件时不需要经过销毁组件,新建组件等过程,直接到内存里找。
<template>
<div>
<component :is="type"></component>
<!--<child-one v-if="type === 'child-one'"></child-one>
<child-two v-if="type === 'child-two'"></child-two>-->
<button @click="handlecomponent()">change</button>
</div>
</template>
<script>
export default{
data(){
return {
type:'child-one'
}
},
methods:{
handlecomponent(){
this.type=this.type==='child-one'?'child-two':'child-one'
}
},
components:{
"child-one":{
template:`<div v-once>child-one</div>`
},
"child-two":{
template:`<div v-once>child-two</div>`
},
"chiltt":{
template:`<div v-once>child-two</div>`
}
}
}
</script>
总结:
1、vue组件使用分3步
引入组件 import Home from ‘./components/Home’
挂载组件 components:{‘v-home’:Home’}
在模板中使用:<v-home></v-home>
2、可以嵌套组件
3、组件事件可以互相传值
- 父组件传值给子组件(父组件绑定数据如
:list="list"
,子组件通过props获取) - 父组件主动获取子组件的数据和方法(使用this.$refs.header.属性,父组件调用子组件时带上
rel
) - 子组件主动获取父组件的数据和方法 (使用this.$parent.xxx)
- 非父子组件之间的传值(使用事件广播,称为bus,实例化一个vue实例VueEvent,然后使用
VueEvent.$emit('名称',数据)
发送,使用VueEvent.$on('名称',function(data){}
接收)
4、组件可以递归(组件内定义一个name,然后组件内调用这个name组件,注意数据必须从外部组件传入,不然会报错)
5、组件之间通讯可以使用vuex,或者localStorage等存储数据的api(这些日后在讨论)
6、动态组件:使用<component is="component-name"></component>
可以动态地显示组件,component-name为组件的名字。
7、v-once属性,子组件内使用v-once属性,该组件第一次显示(挂载)会存入内存,需要再次显示时可以直接到内存里找,而不需要经过销毁,创建的过程。