zoukankan      html  css  js  c++  java
  • vue-eleme 学习笔记

     # watch 用法

    (1)、普通的watch

    <div style="margin-top: 60px;">
         {{common}}
          <button @click="common='123456'">change</button>
    </div>
    data () {
         return {
              common: 'hello world'
         }
    },
    watch: {
         common (newVal, oldVal) {
             console.log(`newVal--->${newVal}`)
          }
     },

    运行:

    (2)、对象的属性watch (需要借助 computed 计算属性)

    <div style="margin-top: 60px;">
        {{common.name}}
       <button @click="common.name='KobeByrant'">change</button>
     </div>
    computed: {
         name () {
            return this.common.name
         }
    },
    watch: {
         name (newVal, oldVal) {
             console.log(`newVal--->${newVal}`)
          }
    },

     # 移动端 1px:

    HTML部分:加一个 “border-1px” 类

    <div class="container border-1px"></div>

    CSS部分:两部分,一部分是通过伪类给定1px 的宽度,另一部分是在不同DPI下缩小一定的倍数

    .border-1px{
        position: relative;
        &:after{
            position: absolute;
            bottom: 0;
            left: 0;
            display: block;
            width: 100%;        
            content: '';
            border-top: 1px solid $color;
        }
    }
    
    @media (-webkit-min-device-pixel-ratio: 1.5) {
        .border-1px{
            &::after{
                -webkit-transform: scaleY(0.7);
                -moz-transform: scaleY(0.7);
                transform: scaleY(0.7);
            }
        }
    }
    
    @media (-webkit-min-device-pixel-ratio: 1.0) {
        .border-1px{
            &::after{
                -webkit-transform: scaleY(0.5);
                -moz-transform: scaleY(0.5);
                transform: scaleY(0.5);
            }
        }
    }

    # Element.getBoundingClientRect()

    Element.getBoundingClientRect() 方法返回元素的大小及其相对于视口的位置

    返回值是一个 DOMRect 对象,该对象包含了一组用于描述边框的只读属性,left、right、top 和 bottom,单位为像素。除了width 和 height 以外的属性都是相对于视口的左上角

    当滚动位置发生改变时,top 和 left 属性值会立即随之发生变化,因为它们的值是相对于视口的,不是绝对的。

    <div class="bounding bounding-hook" style=" 100px; height: 100px; margin-left: 15px; background-color: rgb(0,160,220)"></div>
    
    let rect = document.getElementsByClassName('bounding-hook')[0].getBoundingClientRect()
    
    console.log(rect)

    控制台打印结果:

    # ref 属性:

    属性值是一个 String,这里要注意一点,属性值必须是一个单词或者驼峰命名法(这点可以自行试验),如果模板中用短横杠命名法,js中用驼峰的话会报错;如果二者都用短横杠,也会报错

    如果用在普通的DOM元素上,引用指向的就是DOM元素;如果用在子组件上,引用就指向组件实例

    (1)、用在普通的DOM元素上

    <template>
      <div>
        <p ref="profile"> hello world!</p>
        <button @click="hello">button</button>
        <h1 style="font-size: 16px; color: red;">{{str}}</h1>
      </div>
    </template>
    <script type="text/ecmascript-6">
      export default {
        data () {
          return {
            str: ''
          }
        },
        methods: {
          hello () {
            this.str = this.$refs.profile.innerHTML
          }
        }
      }
    
    </script>

    运行效果:

    可以看到,点击按钮时,通过 " this.$refs.profile" 获取到的是整个 DOM元素 ( <p data-v-04987154> hello world!</p> )

    (2)、用在子组件上

    父组件:

    <template>
      <div>
        <child ref="childWrapper"></child>
        <button @click="get">父组件按钮</button>
        <h1>{{str}}</h1>
      </div>
    </template>
    <script type="text/ecmascript-6">
      import child from './child'
      export default {
        components: {
          child
        },
        data () {
          return {
            str: ''
          }
        },
        methods: {
          get () {
            this.$refs.childWrapper.addNum()
            this.str = this.$refs.childWrapper.str
          }
        }
      }
    
    </script>

    子组件:

    <template>
      <div class="child-wrapper" style="margin:30px 15px; padding: 15px; border: 3px double #ddd;">
          <button @click="addNum()">子组件按钮</button>
          <div v-show="isShow" style=" 100px; height: 100px; background-color: red;"></div>
      </div>
    </template>
    
    <script>
    export default {
        data () {
            return {
                isShow: false,
                str: '我是子组件的数据,你能拿到我吗?'
            }
        },
        methods: {
            addNum () {
                this.isShow = !this.isShow
            }
        }
    }
    </script>

    运行效果:

    可以看到,child组件可以通过点击按钮实现红色DIV的显示与隐藏,父组件一样可以通过 " this.$ref.childWrapper" 拿到子组件,并调用获取子组件的数据和方法,对子组件加以控制

    关于 ref 注册时间的重要说明:因为 ref 本身是作为渲染结果被创建的,在初始渲染的时候你不能访问它们 - 它们还不存在!$refs 也不是响应式的,因此你不应该试图用它在模板中做数据绑定。

    上面的两个例子,都是通过点击事件来实现示例效果,如果我们直接在数据更新的时候通过 ref来访问的话是找不到的,报错未定义,如下图:

    为了解决这个问题,我们可以借助$nextTick方法延迟调用,在下次DOM更新之后执行
    <script type="text/ecmascript-6">
      import child from './child'
      export default {
        components: {
          child
        },
        data () {
          return {
            str: ''
          }
        },
        created () {
          // this.get2()
          this.$nextTick(() => {
            this.get2()  // 我是子组件的数据,你能拿到我吗?
          })
        },
        methods: {
          get2 () {
            console.log(this.$refs.childWrapper.str)
          }
        }
      }
    
    </script>

    # 为动画DOM元素添加 transform: translate3d(0,0,0) 开启GPC硬件加速模式,从而让浏览器在渲染动画时,从CPU转向GPU。具体有两篇较好的文章可查阅

    http://blog.bingo929.com/transform-translate3d-translatez-transition-gpu-hardware-acceleration.html

    http://www.w3cplus.com/animation/animation-performance.html

    .cart-decrease{
            display: inline-block;
            padding: 6px;
            opacity: 1;
            transform: translate3d(0,0,0); // 开启GPU硬件加速,解决Chrome动画卡顿
            .inner{
                display: inline-block;
                line-height: 24px;
                font-size: 24px;
                color: rgb(0, 160, 220);
                transition: all 0.4s linear;
                transform: rotate(0);
            }
            &.move-enter-active, &.move-leave-active{
                transition: all 0.4s linear
            }
            &.move-enter, &.move-leave-to{
                opacity: 0;
                transform: translate3d(24px, 0, 0);
                .inner{
                    transform: rotate(180deg);
                }
            }
        
        }

    # navtive 修饰符

    浏览器默认会把 <router-link>渲染成 a 标签,如果需要为 router-link 添加事件,不能像一般 html 元素那样直接写 " @click="someMethod",必须加 .navtive 修饰符

    Demo 1:按一般的写法添加事件

     <router-link to="/rank" @click="test">aaa</router-link>
    test () {
          alert(1)
    }

    Demo2:用.native 修饰符来添加事件

    <router-link to="/rank" @click.native="test">aaa</router-link>

    同样,给组件绑定原生事件也必须用 .native 修饰符

    <select v-model="optSelected">
              <option value="aa">AA</option>
                <option value="bb">BB</option>
    </select>
    <component :is="optSelected" @click="test"></component>

    不加的情况下,没法弹出1,并且控制台会有警告消息

    现在加上修饰符

    <select v-model="optSelected">
              <option value="aa">AA</option>
                <option value="bb">BB</option>
    </select>
     <component :is="optSelected" @click.native="test"></component>

    # slot 插槽

    (1)、单个插槽

    组件的可复用性在开发中带来非常大的方便,但某些特殊情况下依旧不太灵活,比如自定义一个模态框弹出各种消息,“添加成功!”,“删除成功!”之类,实现的时候往往需要通过props属性来传递一些提示消息或者传递bool值来显示自定义模态框组件中的某些消息。

    通过 slot 就可以很好的解决这个问题,顾名思义,slot就是一个插槽(可以理解成一个占位符),在子组件中添加slot占据一块位置,这块位置放什么内容暂时不用考虑。被调用时,其父组件可根据实际情况把自己的内容传入到slot插槽占好的位置中。

    子组件:

    <div class="child">
          <slot></slot>
     </div>

     父组件:

    <div class="log-out content">
        <my-component>
             <ul>
                 <li v-for="item in 10">{{item}}</li>
              </ul>
        </my-component>
     </div>

    渲染结果:

    上图可看到,在本来为空的子组件中插入了一个ul列表

    官网提到了两个问题:

    一、除非子组件模板包含至少一个 <slot> 插口,否则父组件的内容将会被丢弃

    也就是说,如果子组件没有 slot 插槽,那么上例中的ul列表就不会在DOM中显示出来

    子组件:

    <div class="child">
          <!-- <slot></slot> -->
     </div>

    什么都渲染不出来,父组件的内容被丢弃了

     二、最初在 <slot> 标签中的任何内容都被视为备用内容。备用内容在子组件的作用域内编译,并且只有在宿主元素为空,且没有要插入的内容时才显示备用内容

    也就是说,slot 插槽中的内容只有在父组件没有内容的情况下才会显示,针对上例,改下my-component组件slot插槽中的内容

    子组件:

    <div class="child">
          <slot>如果父组件中什么内容都没有就显示这段文字</slot>
    </div>

    渲染结果,父组件有一个列表循环,所以不会显示slot插槽中的备用内容

    现在稍作修改,移除父组件中的内容

    父组件:

    <div class="log-out content" v-show="otherFlag">
         <my-component>
             <!-- <ul>
                 <li v-for="item in 10">{{item}}</li>
              </ul> -->
          </my-component>
     </div>

    渲染结果:

    (2)、具名插槽

    一、子组件通过给 solt 插槽添加 name 属性来配置如何分发内容

    二、子组件的多个 slot 插槽有多个不同的名字

    三、父组件中与子组件对应的slot插槽对应的元素 需要添加 slot 属性

    四、渲染出的DOM顺序以子组件中slot出现的顺序为准

    五、父组件中没有 slot 属性的元素会被插入到子组件中没有name 属性的slot插槽中

    子组件:

    <div class="child">
          <div class="header">
              <slot name="header"></slot>
          </div>
          <div class="body">
              <slot></slot>
          </div>
          <div class="footer">
            <slot name="footer"></slot>
          </div>
     </div>

    父组件:

    <div class="log-out content" v-show="otherFlag">
         <my-component>
               <div>我还在顶部吗?</div>
                <ul slot="footer">
                   <li>单个插槽</li>
                   <li>具名插槽</li>
                </ul>
                <span>我的插槽在哪里呢?</span>
                <h1 slot="header">头部信息</h1>
            </my-component>
     </div>

    渲染结果:

  • 相关阅读:
    MSSQL查询表占用空间
    JS字典
    匹配是否指定主域名
    站点文件删除不了提示权限不足
    事件委托发布-订阅
    微信中打开第三方应用
    以Spring Bean配置文件为例解释 xmlns,xmlns:xsi,xsi:schemaLocation
    Hdfs的读出机制
    Hdfs的写入机制
    spring常用注解的作用
  • 原文地址:https://www.cnblogs.com/rogerwu/p/7777382.html
Copyright © 2011-2022 走看看