为了账号安全,请及时绑定邮箱和手机立即绑定

vue系列组件篇(二)

2018.10.18 18:23 1234浏览

概述

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

微信图片_20180907112102.png


整个工程可以在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:'携手打造更加紧密的中非命运共同体',content:'9月3日,2018年中非合作论...'},
            {title:'“小眼镜”牵动大情怀',content:'近日,习近平总书记就青少年视力健...'},
            {title:'倡议五周年之际',content:'2013年9月7日,国家主席习...'},
          ]
        }
    },
    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
      }
    },

微信截图_20180907141949.png

可以看到,子组件使用propos接收了父组件传过来的dataListclickFun2个变量。注意传递形式就是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>

微信截图_20180907143350.png

设置点击删除按钮,顺利删除了一行,可以看到,我们在父组件通过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}

微信截图_20180907144533.png

点击按钮,顺利改变了列表的背景颜色。这里,在引用组件的时候,我们通过ref给组件添加了一个命名:myList,父组件点击切换主题,执行this.$refs.myList.changeColor(),子组件changeColor方法被调用,最终实现了转换主题,这里组件能单独命名,意味着同一个页面可以引用同一个组件多次,通过不同的命名,来单独操作,互不影响。

组件插槽

组件插槽是为了组件能有更灵活的使用,能让主页面在适当的字符插入自定义的html片段,先看一张图


插槽

我们想给每一行添加一个序号并且加粗,如果是组件里面固定的html结构,和明显难以实现,这里我们需要用到slot插槽功能。

//文件componentSutdy.vue,关键代码<my-list :data-list="dataList" ref="myList" :click-fun="clickFunction" @deleteItem="removeItem">
          <template slot="title" slot-scope="{item,index}">
            <div>
              <span v-text="`${index + 1}.`" style="font-weight: bold"></span>
              <span v-text="item.title"></span>
            </div>
          </template>
        </my-list>//文件my-list.vue,关键代码<li class="list-group-item" :class="{'has-bg':isChange}" v-for="(item,index) in dataList" @click="clickFun(1)">
          <slot name="title" :item="item" :index="index">
            <div class="main-title" v-text="item.title"></div>
          </slot>
          <div class="content" v-text="item.content"></div>
          <i class="el-icon-delete" @click="$emit('deleteItem',index)"></i>
        </li>



作者:伊泽瑞尔灬
链接:https://www.jianshu.com/p/04742416c4a4


点击查看更多内容
7人点赞

若觉得本文不错,就分享一下吧!

评论

相关文章推荐

正在加载中
意见反馈 去赚学费 帮助中心 APP下载
官方微信

举报

0/150
提交
取消