VUE进阶笔记(5) - ( better-scroll ) + ( 父组件调用子组件的方法函数 ) + ( click.stop阻止冒泡,click.prevent阻止默认事件 ) + ( 1px像素边框 ) + ( 过渡,动画 ) + ( 显示省略号。。。) + ( 背景模糊 filter ) + ( display:table多行垂直居中布局 ) +(阴影box-shadow,filter: drop-shadow )

(1) better-scroll插件

官网:https://ustbhuangyi.github.io/better-scroll/#/examples
详细:https://zhuanlan.zhihu.com/p/27407024

  • 安装:
cnpm install better-scroll --save
  • 使用
js部分


<script type="text/ecmascript-6">
  import BScroll from 'better-scroll';                   // 引入better-scroll
    created() {                              // 生命周期钩子函数,用在实例被创建之后
      this.$http.get('/api/goods')       // 异步请求数据
        .then((response) => {
          response = response.body;
          if (response.errno === ERR_OK) {
            this.goods = response.data;
            this.$nextTick(() => {       // this.$nextTick保证在更新dom之后,再执行initscroll()函数
              this.initScroll();
            });
          }
        });
    },
    methods: {
        initScroll() {                                // 定义一个(初始化scroll)的函数
            this.menuScroll = new BScroll(this.$refs.menuWrapper, { click: true });   
                 // 拿到dom,实例化BScroll,click:true则是允许点击事件
            this.contentScroll = new BScroll(this.$refs.goodsWrapper, { click: true});  
        }
    }
  };
</script>
----------------------------------------------------------------------------
vue的DOM部分


<template>

  <div class="goods">

    <div class="menu-wrapper" ref="menuWrapper">               // ref属性:绑定dom
      <ul>
        <li v-for=" item in goods " class="li">
        </li>
      </ul>
    </div>

    <div class="goods-wrapper" ref="goodsWrapper">             // ref属性:绑定dom
      <ul>
        <li v-for=" item in goods" class="foods-Wrapper">
          <h1 class="foods-section"> {{ item.name }} </h1>
          <ul>
            <li v-for=" foods in item.foods " class=" foods-content ">
            </li>
          </ul>
        </li>
      </ul>
    </div>

  </div>
</template>


  • 使用进阶
    当better-scroll处在时刻变化的场景中的时候( 比如:在显示隐藏一个modal的时候,每次状态的变化都需要new BScroll? 不需要,better-scroll中有 refresh() 接口 )
//初始化函数


initBetterScroll() {      
            if (!this.modalScroll) {
              this.modalScroll = new BScroll(this.$refs.modalDom, { click: true });
            } else {
                this.modalScroll.refresh();      // 不存在就new,已经存在就refresh()
            }
        }

---------------------------------------------------------------

//调用


  showDetail() {
            if (!this.selectTotalCount) {    // 当数量为0的时候,不显示
                return;
            } else {
              this.showModal = !this.showModal;      // 切换显示状态
            } if (this.showModal) {      // 显示的时候,调用better-scroll
              this.$nextTick(() => {     //dom更新后,执行
                this.initBetterScroll();
              });
          }
        }

(2) 父组件调用子组件的方法

  • (1) ref属性
    ref 绑定在一般元素上,ref指 ( DOM元素 )
    ref 绑定在组件上,ref指 ( 组件实例 )

  • (2) 例子说明

子组件的函数


methods: {
        show() {
            this.foodsDetail = !this.foodsDetail;
        }
    }

------------------------------------------------------------------

父组件调用子组件的函数

dom

<li v-for=" foods in item.foods " class=" foods-content " v-on:click="selectFoodsFunction(foods)">

 // 点击,执行 selectFoodsFunction函数,并把当前的 foods 作为参数传入



<Foods v-bind:foods="selectedFoodsObject" ref="foodsChildrenComponent"></Foods>

 // ref绑定子组件实例调用子组件方法 , 将selectedFoodsObject对象 传给子组件



 selectFoodsFunction(foods) {
        this.selectedFoodsObject = foods;   // 将foods对象保存在data的selectedFoodsObject 中
        this.$refs.foodsChildrenComponent.show();    //调用子组件的show()函数
      }

(3) click.stop阻止冒泡,click.prevent阻止默认事件



<div class="cart-add icon-add_circle" v-on:click.stop.prevent="addCart($event)"></div>

(4) @media 媒体查询

<meta 
name="viewport" 
content="width=device-width, 
initial-scale=1.0, 
maximum-scale=1.0, 
minimum-scale=1.0, 
user-scalable= no"
/>


@media screen and (max-width: 300px) {
    body {
        background-color:lightblue;
    }
}

// 如果文档宽度小于 300 像素则修改背景颜色(background-color):
// ( min-width: 300px) 浏览器宽度大于300px时

(5) 1px像素边框

html


  <div class="suo">
      定义伪类,缩放class
    </div>

---------------------------------------------------------------------------------------------

stylus


.suo
      position: relative
      &:after
        display: block
        position: absolute
        left: 0
        bottom: 0
        width: 100%
        border-bottom: 1px solid red
        content: ' '
@media (-webkit-min-device-pixel-ratio: 1.5),(min-device-pixel-ratio: 1.5)
      .suo:after
          -webkit-transform: scaleY(0.7)
          transform: scaleY(0.7)
@media (-webkit-min-device-pixel-ratio: 2),(min-device-pixel-ratio: 2)
      .suo:after
          -webkit-transform: scaleY(0.5)       // ratio: 比例
          transform: scaleY(0.5)

(6) 省略号。。。

(1) white-space:nowrap ( 规定段落中的文本不进行换行 )
(2) overflow: hidden ( 内容会被修剪,并且其余内容是不可见的 )
(3) text-overflow: ellipsis ( 显示省略符号来代表被修剪的文本 )


 .right
    white-space: nowrap
    overflow: hidden
    text-overflow: ellipsis    //ellipsis是省略的意思

(7) filter: blur(10px) 模糊效果

(filter详解)http://www.cnblogs.com/moqiutao/p/4843437.html

 filter: blur(10px);
 overflow: hidden;      //一般会让超出的模糊部分隐藏

(8) filter: drop-shadow() 阴影效果


filter: drop-shadow(x偏移, y偏移, 模糊大小, 色值);

(9) box-shadow: 盒阴影效果


box-shadow: x偏移, y偏移, 模糊大小, 色值

两者区别:http://www.zhangxinxu.com/wordpress/2016/05/css3-filter-drop-shadow-vs-box-shadow/

(10) VUE中 css3 过渡 和 动画

动画:

vue部分

 <transition name="aa">
      <div class="modal" v-show="showModal">
        <div v-on:click="show()" class="close">关闭</div>
      </div>
 </transition>

-----------------------------------

css部分

  .aa-enter-active {
    animation: bounce-in .4s;
  }
  .aa-leave-active {
    animation: bounce-in .4s reverse;    // reverse反转的意思
  }
  @keyframes bounce-in {
    0% {
      transform: translateX(-100px);
    }
    100% {
      transform: translateX(0);
    }
  }

(11) flex固定宽度

flex: 0 0 80px;
width: 80px;

(12) display:table 多行垂直居中布局

.li
        display: table
        background:red
        border-bottom: 1px solid red
        line-height:14px;
        height:54px;
        width:56px;
        padding: 0 12px
        .table-cell
          display: table-cell
          background:yellow
          vertical-align: middle

(13) 用数组控制不同的class的显示


template

 <li v-for=" item in goods " class="li">
      <div v-bind:class="classMap[ item.type ]" class="ii"></div>
      <span class="table-cell">{{ item.name }}</span>
 </li>
------------------------------------------------------------------------------------------
script

    created() {
      this.classMap = ['jian', 'jia', 'cheng', 'chu', 'mo'];

     //这里也可以在data(){}中直接初始化classMap
     //data() {
     // return {
     //  goods: [],
     //  classMap: ['jian', 'jia', 'cheng', 'chu', 'mo']
     //   };
     //    }

      this.$http.get('/api/goods')
        .then((response) => {
          response = response.body;
          if (response.errno === ERR_OK) {
            this.goods = response.data;
          }
        });
    }
--------------------------------------------------------------------------------------------
css

        .jian
          background:blue
        .jia
          background:blueviolet
        .cheng
          background:black

(14) 在vue中如果props是一个 (数组Array)或者一个(对象Object),那么default就是一个函数

cart组件中js部分



export default {
      props: {
        sellerCart: {          // <Cart v-bind:sellerCart="seller"></Cart> 父组件传过来的对象
            type: Object,
            default() {       // props是对象,所以default是一个函数
                return {};
            }
        },
        selectFoods: {
            type: Array,    
            default() {    // props是数组,所以default是一个函数
                return [
                  {
                      price: 10,     // 在selectFoods传过来的不存在时,返回defaut中值
                      count: 20
                  }
                ];
            }
        }
      },
      computed: {                               // 计算属性
          selectTotalPrice() {
              let total = 0;
              this.selectFoods.forEach((foods) => {     // 遍历selectFoods
                total += foods.price * foods.count;
              });
              return total;
          },
          selectTotalCount() {
              let count = 0;
              this.selectFoods.forEach((foods) => {
                  count += foods.count;
              });
              return count;
          },
           stateRight() {            //结算的三种状态
              if (this.selectTotalPrice === 0) {
                  return `${this.sellerCart.minPrice}元起送`;     // `${...}` es6带变量的字符串写法
              } else if (this.selectTotalPrice < this.sellerCart.minPrice) {
                  let diff = this.sellerCart.minPrice - this.selectTotalPrice;
                  return `还差 ${diff}元起送`;
              } else {
                  return '去结算';
              }
          }
      }

  };
-----------------------------------------------------------------------------------

cart的vue的dom部分



<template>
  <div class="Cart">
    <div class="Cart-container">

      <div class="left">

        <div class="circle">
          <div class="circle-in" v-bind:class="{ 'selectTotalCount': selectTotalCount>0}">
            <i class="fa fa-credit-card" aria-hidden="true"></i>
            <div class="foodsCountNum">
              {{ selectTotalCount }}
            </div>
          </div>
        </div>
        <div class="price" v-bind:class="{ 'priceHighlight': selectTotalPrice>0 }">
          {{ selectTotalPrice }}
        </div>

        <div class="otherPrice">
          另需配送费{{ sellerCart.deliveryPrice }}元
        </div>

      </div>

      <div class="right" v-bind:class="{ 'go': (selectTotalPrice - sellerCart.minPrice ) > 0 }" >

            //上面要注意,在template(或者html)中表达式都不能带this,如(this.selectTotalPrice )

            <div class="right-text">{{ stateRight }}</div>

      </div>

    </div>
  </div>
</template>

(15) 手机,浏览器下点击触发两次解决方案:

js部分

 methods: {
          add(event) {
              if (!event._constructed) {
                 return;
              }
              console.log('add');
           }
         }
--------------------------------------------------------

html部分

 <div class="same" v-on:click.stop.prevent="add($event)">+</div>
 
//这里要加上add($event)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268

推荐阅读更多精彩内容