栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > Web开发 > Vue.js

Vue.js新手教学|如何写一个Checklist组件(下)

Vue.js 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Vue.js新手教学|如何写一个Checklist组件(下)


作者:Dunizb,原文地址

第四步:组件显示隐藏 4.1 显示组件

这一步我们要做一下的组件的显示与隐藏,点击输入框从页面底部显示组件,点击取消或者蒙层从上到下隐藏组件,并且添加过渡动画。这其实使用定位和CSS3的transform属性即可实现。

.cl-checklist{
    overflow: hidden;
    position: fixed;
    bottom: 0;
    left: 0;
    width: 100%;
    -webkit-transition: all .5s;
    transition: all .5s;
    -webkit-transform: translateY(100%);
    transform: translateY(100%);
}
.cl-checklist.show{
    -webkit-transform: translateY(0%);
    transform: translateY(0%);
}

我们还得为组件弄一个是否显示和隐藏的属性isOpen,默认为false不显示,用它来控制给组件动态添加显示和隐藏的.cl-checklist.show类。

那在demo.vue中如何调用这个属性呢?这时候我们就不得不考虑对外提供方法了,我们可以定义一个显示和隐藏的方法来供使用者调用。

methods: {
   show () {
      this.isOpen = true
   },
   hide () {
      this.isOpen = false
   }
}

在demo.vue中,为输入框添加事件,然后调用组件的 show 方法


现在的效果如下:

4.2 隐藏组件

做好了显示那隐藏就很简单了,点击取消隐藏组件,动画会原路返回,只需要为取消设置一下isOpen = false或者调用hide方法即可。

   取消
   选择考场
   完成

现在效果如下

4.3 添加蒙层

为了使蒙层能够覆盖整个页面,还不得不为DOM结构做一下调整

    
 ... ...
    
    
    

.checklist-overlay的CSS如下

.checklist-overlay{
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 1000;
  background: rgba(0, 0, 0, .5);
  transition: all .5s;
}

对应的,DOM结构调整后,最外层的样式也要改一下

.cl-checklist{
    overflow: hidden;
}
.checklist{
    position: fixed;
    bottom: 0;
    left: 0;
    z-index: 2000;
    width: 100%;
    background-color: #fff;
    -webkit-transition: all .5s;
    transition: all .5s;
    -webkit-transform: translateY(100%);
    transform: translateY(100%);
}

特别注意,为.checklist增加了白色背景和z-index:2000,现在的效果如下


当然了,你也可以让点击蒙层的时候也可以隐藏组件,直接给蒙层绑定一个单击事件@click = "hide"即可。

4.4 移动端input输入框阻止弹起手机虚拟键盘

在移动端,input会默认触发手机的虚拟键盘,如何阻止手机虚拟键盘弹起呢?目前我试过有两个方案,一个是给input添加readonly属性,另一个就是在input事件处理方法前面添加一句document.activeElement.blur()。关于这个问题的详细可以阅读我的另一篇博客《小技巧|H5禁止手机虚拟键盘弹出》

methods: {
   show () {
      document.activeElement.blur()
      this.isOpen = true
   }
}
第五步:数据渲染和向父组件传递事件

此文中子组件就是 checklist.vue ,父组件就是 demo.vue

5.1 数据渲染

前面我们的数据都是写死的,现在我们来动态渲染数据,也就是循环数据了。从父组件传递数据,在子组件中接收,还得使用 Props,前面我们定义了一个 max 属性,用来控制最多选择几项,我们再添加一个 Props 属性,取名为 dataList,这是一个数组类型,并且是必须的

props: {
  max: {
      type: Number,
default: 0
   },
  dataList: {
      type: Array,
      require: true
  }
}

在组件中传递这个 Props ,需要注意的就是,由于 HTML 特性不区分大小写,当使用 DOM 模板时,驼峰命名的 props 名称要转为短横线分隔符命名。不能dataList在组件中必须使用中划线,变成data-list 形式。

定义 data 数据,这里的数据应该是从后端接口中来的,这里我就模拟一下数据了

data () {
   return {
 data: [{
     label: '科目二第07考点马路',
     value: '101',
     address: '上海市宝山区宝安公路2009号'
   },{
     label: '科目二第08考点沪松公路',
     value: '102',
     address: '上海市闵行区沪松公路565弄128号'
   },{
     label: '科目二第09考点七宝',
     value: '103',
     address: '上海市闵行区沪松公路200号'
   },{
     label: '科目二第09考点世纪公园世纪公园',
     value: '104',
     address: ''
   },{
     label: '科目二第09考点世纪公园',
     value: '105',
     address: '上海市浦东新区世纪大道200号'
   },{
     label: '科目二第09考点哈哈哈哈',
     value: '107'
   },{
     label: '科目二第09考点合川路地铁站',
     value: '106',
     address: '上海市合川路地铁站2号出口'
   }]
     }
}

最后就是渲染了,回到 checklist.vue 中,把 v-for 补上就行了

    


    

需要注意的就是第 3 行和第 10 行,for的值和id的值必须一致,这里最好是使用v-for的index,当然了,也可以用item.label或item.value,但不推荐这样做。

5.2 组件通信与自定义事件

最后的最后,就是该处理点击“完成”后把选中的值传递给父页面了。我们已经知道从父组件向子组件通信,通过 props 传递数据就可以了,当子组件需要向父组件传递数据时,就需要用到自定义事件。v-on 指令除了可以监听 DOM 事件外,还可以用于组件之间额自定义事件

在 Vue.js 中子组件使用 $emit() 来触发事件,父组件使用 $on() 来监听子组件的事件。父组件也可以直接在子组件的自定义标签上使用 v-on 来监听子组件触发的自定义事件。

我们给确定使用@click按钮绑定一个方法,叫on/confirm/i

    取消
    选择考场
    完成

我们需要传递什么给父组件?选中的值,这个值应该包含一个考场 value 值(也就是考场的id),选中的考场名称,或许还需要考场的地址,我们可以把这几个值使用|符号连接这几个值一起放到单选框的 value 里面

    
 
 
    

注意:第 2 行的 data-val 要跟 单选框的 value 值保持一致,因为接下来的 JS 逻辑需要用到它来和单选框的 value 比较,我们来实现 on/confirm/i() 方法

on/confirm/i () {
    this.isOpen = false
    const checkboxValue = this.checkboxValue
    const res = []
    for (let i = 0; i < checkboxValue.length; i++) {
 const resObj = {}
 const item = checkboxValue[i].split('|')
 resObj.label = item[0]
 resObj.value = item[1]
 res.push(resObj)
    }
    this.$emit('on-change', res)
}

在方法中,首选取得checkboxValue的值,然后分别取出其中的value、label 和 address 三个部分放到一个对象resObj 中,再放到 res 数组中,最后把这个数组对象作为 on-change 事件的返回值参数。

在父组件的子组件标签上我们用 @on-change 来接收

在父组件的 data 选项中定义一个kaochangVal属性来接收,然后把选中的考场名称打印出来

{{item.label}}

changeKaochangValue 方法

changeKaochangValue (val) {
    this.kaochangVal = val
}

现在的效果如下:


至此,这个 Checklist 组件算是完成了。

第六步:扩展和完善 设置选框在左边

考虑通用性,假如需求需要 CheckBox 框在左边呢?这个问题其实很好解决,因为我们使用 Flexbox 布局,天然支持,只需要多加一句样式即可。这个特性应该是可以用户设置的,也就是得弄一个 props 属性来支持。

props : {
  checkboxLeft: {
    type: Booolean,
    default: false
  }
}

定义一个 checkboxLeft 属性,默认为 false 也就是 默认 checkbox 在右边,只有用户显示传递改值为 true 时 checkbox 才在左边。

前面说只需要加一个样式就可以让 checkbox 在左边了,为 .line 元素设置一个样式 class ,然后通过 checkboxLeft 这个 props 来动态绑定 class

.list .line.checkbox-left{
    flex-direction: row-reverse;
}
...

熟悉 Flexbox 的同学应该知道,flex-direction是控制布局的方向,row-reverse就是倒序的意思,原来是 12 排列,row-reverse 后就变成 21 排列了。

在组件上(demo.vue)设置

显示设置 props 的checkboxLeft 为 true 即可


还可以做点什么呢?
大家可以扩展一下…

完整源码

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/241663.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号