• vue系列组件篇(二)


    概述

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


    目录结构

    整个工程可以在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
          }
        },


    这里写图片描述

    可以看到,子组件使用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>
    


    这里写图片描述

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


    这里写图片描述

    点击按钮,顺利改变了列表的背景颜色。这里,在引用组件的时候,我们通过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>

    可以看到,我们在子页面,添加了name="title"slot插槽,并且通过绑定数据的方式传递了2个参数,item,index,父组件,<template slot="title" slot-scope="{item,index}">通过sole与字段就name匹配,来将html代码插入到对应的位置。这样主页面就轻松定制了新闻列表标题栏的html结构,当主页面不引入插槽是,将使用默认的html解析。这里接收参数的方式是采用es205的解构语法。

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


    公众号

  • 相关阅读:
    oracle中常用的函数
    请求转发和URL重定向的原理和区别
    servlet的生命周期和servlet的继承关系
    Jdbc来操作事物 完成模拟银行的转账业务
    Map的嵌套 练习
    正则表达式练习
    学习 day4 html 盒子模型
    学习day03
    学习day02
    学习day01
  • 原文地址:https://www.cnblogs.com/zhujieblog/p/12816874.html
Copyright © 2020-2023  润新知