vue组件

vue组件使用

分3步

  1. 引入组件 import Home from ‘./components/Home’
  2. 挂载组件 components:{‘v-home’:Home’}
  3. 在模板中使用:<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属性,该组件第一次显示(挂载)会存入内存,需要再次显示时可以直接到内存里找,而不需要经过销毁,创建的过程。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kitt15

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值