vue系列组件篇(二)

概述

vue组件是vue常用的功能,vue也因为强大的组件功能得到很多开发者的青睐。一个好的组件,可以提供给开发者很多方便,特别是复用代码,代码一致性等。
本文通过实现一个列表my-list组件,来讲解组件的用法和特性。
下面先看一下工程目录:

![目录结构](https://img-blog.youkuaiyun.com/20180907112150513?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMwODExNzIx/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70) > 整个工程可以在git上下载:[点击下载](https://github.com/jackzhujie/vue-study.git),其中蓝色线条标记的,分别是我们这次用到的页面和组件。
组件引入

组件引入分全局引入和局部引入,顾名思义,全局引入可以在任何一个路由页面使用该组件,而局部引入是在引入页面才能使用。

import myList from '../components/my-list'
  //全局引入
  Vue.component('my-list',myList)
  export default {
    name: "componentStudy",
    data: function () {
        return {}
    },
    //局部引入,写法很灵活
    components:{myList},
    methods: {},
    mounted: function () {
    },

    computed: {},
    created: function () {
    }
  }

上面的代码的2中写法分别是全局引入和局部引入,整体来说,像分页组件,下拉框组件,表格组件等大多数页面都用得上的可以全局引入,像tab页面,特殊按钮等用的比较的少的页面可以采用局部引用。

组件传值

我们的列表组件,各个页面的数据不一样,这些数据往往是通过引入改组件的页面决定的,那么意味着,这些数据应该是从父组件传到子组件的,下面我们给我们的列表组件传一个dataList(数据)和一个clickFunction(点击每一项的触发函数)。vue通过prop子组件传值,这里传值可以是js所有类型。

//文件componentSutdy.vue
<my-list :data-list="dataList" :click-fun="clickFunction"></my-list>
data: function () {
        return {
          dataList:[
            {title:'标题1',content:'内容一'},
            {title:'标题2',content:'内容二'},
            {title:'标题3',content:'内容三'},
          ]
        }
    },
    methods: {
      clickFunction(item){
        console.log(item)
      }
    },
//文件my-list.vue
<template>
    <div class="my-list">
      <ul>
        <li class="list-group-item" v-for="(item,index) in dataList" @click="clickFun(1)">
          <div class="main-title" v-text="item.title"></div>
          <div class="content" v-text="item.content"></div>
        </li>
      </ul>
    </div>
</template>
//子组件接收父组件传过来的值
    props:{
      dataList:{
        type:[Array,Object],   // 类型校验,多个可能的类型
        require:true,         //是否必传
        default:function () { //默认值, 对象或数组默认值必须从一个工厂函数获取
          return []
        },
        // //自定义校验
        // validator: function (value) {
        //   // 这个值必须匹配下列字符串中的一个
        //   return ['success', 'warning', 'danger'].indexOf(value) !== -1
        // }
      },
      clickFun:{
        type: Function,
        require: false
      }
    },
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200522171717805.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMwODExNzIx,size_16,color_FFFFFF,t_70#pic_center) > 可以看到,子组件使用`propos`接收了父组件传过来的`dataList`和`clickFun`2个变量。注意传递形式就是vue常见语法v-bind来传递。试着点击列表,可以看到父组件的方法cliFun被调用了,并且接收到了子组件传过来的变量。 > 上面的例子,完成了父组件向子组件传递参数,子组件调用父组件方法。
子组件调用父组件方法

和其他框架一下,vue在子组件无法直接通过this.的方式调到父组件的方法,这里vue提供的是$emit的方式来调用父组件的方法。我们修改上面的例子,让子组件点击按钮来删除一个列表,这里值得注意的是,vue组件直接传递参数是单向的,意思是,父组件传递过去的变量,只能在父组件被改变子组件是不能改变父组件传过来的这个变量的。不过可以通过赋值、计算属性等方式来重新定义一个变量。
修改部分的代码:

//文件componentSutdy.vue
//添加了@deleteItem的绑定
<my-list :data-list="dataList" :click-fun="clickFunction" @deleteItem="removeItem"></my-list>
//方法里面添加执行函数
removeItem(index){
        this.dataList.splice(index,1)
      }
//文件my-list.vue
//添加了$emit('deleteItem',index)"执行函数
<li class="list-group-item" v-for="(item,index) in dataList" @click="clickFun(1)">
          <div class="main-title" v-text="item.title"></div>
          <div class="content" v-text="item.content"></div>
          <i class="el-icon-delete" @click="$emit('deleteItem',index)"></i>
        </li>
      

在这里插入图片描述

设置点击删除按钮,顺利删除了一行,可以看到,我们在父组件通过deleteItem传递了removeItem函数给子组件,子组件通过$emit('deleteItem',index)顺利调到了父组件的函数,并且传递了一个参数,父组件通过这个参数删除了用户点击的数据,这个过程完成了字段就调用父组件的方法,也说明了,子组件不要直接改变父组件传递过来的参数,因为这里是单向绑定的。
值得注意的是,字段就调用父组件的函数,有2种方式,稳重第一种是通过prop传递,第二种是通过@绑定来传递的,实际使用过程中,建议使用第二种方式。

父组件调用子组件方法

很多时候,我们需要字段就来执行某种操作,来达到页面效果,比如说,我们需要在用户点击之后,改变列表颜色,来切换主题。

//文件componentSutdy.vue,关键代码
<my-list :data-list="dataList" ref="myList" :click-fun="clickFunction" @deleteItem="removeItem"</my-list>
<el-button @click="changeTheme" style="margin-top: 20px;">切换主题</el-button>
changeTheme(){
        this.$refs.myList.changeColor()
      },
//文件my-list.vue,关键代码
<li class="list-group-item" :class="{'has-bg':isChange}" v-for="(item,index) in dataList" @click="clickFun(1)">
          <div class="main-title" v-text="item.title"></div>
          <div class="content" v-text="item.content"></div>
          <i class="el-icon-delete" @click="$emit('deleteItem',index)"></i>
        </li>
changeColor(){
 this.isChange = true
}

![在这里插入图片描述](https://img-blog.csdnimg.cn/20200522171232537.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMwODExNzIx,size_16,color_FFFFFF,t_70#pic_center) > 点击按钮,顺利改变了列表的背景颜色。这里,在引用组件的时候,我们通过`ref`给组件添加了一个命名:`myList`,父组件点击切换主题,执行`this.$refs.myList.changeColor()`,子组件`changeColor`方法被调用,最终实现了转换主题,这里组件能单独命名,意味着同一个页面可以引用同一个组件多次,通过不同的命名,来单独操作,互不影响。 #### 组件插槽 组件插槽是为了组件能有更灵活的使用,能让主页面在适当的字符插入自定义的html片段,先看一张图 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200522171452417.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMwODExNzIx,size_16,color_FFFFFF,t_70#pic_center) 我们想给每一行添加一个序号并且加粗,如果是组件里面固定的html结构,和明显难以实现,这里我们需要用到slot插槽功能。 ```code //文件componentSutdy.vue,关键代码

总结:关于vue组件就将到这里,相信上面的类容能涵盖到大多数用法,还有部分动态组件和异步组件不作讲解,实际使用中,用到很少,整个代码的源码可以在git:https://github.com/jackzhujie/vue-study.git上下载到。
最后想查看更多文章,可以关注我的个人公众号:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值