Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vue.js 实用技巧 #37

Closed
yuxino opened this issue Jan 7, 2018 · 12 comments
Closed

Vue.js 实用技巧 #37

yuxino opened this issue Jan 7, 2018 · 12 comments
Labels

Comments

@yuxino
Copy link
Owner

yuxino commented Jan 7, 2018

这里有一个Input Group组件。最直接的写法是这样子(节选自我的项目里的破代码)。

<template>
  <div class="input-group">
    <label>{{ label }}</label>
    <input ref="input"
                @input="$emit('input',$event.target.value)"
                :value="value"
                :placeholder="placeholder"
                :maxlength="maxlength"
                :minlength="minlength"
                :name="name"
                :form="form"
                :value="value"
                :disabled="disabled"
                :readonly="readonly"
                :autofocus="autofocus">
  </div>
</template>

<script>
export default {
  name: 'InputGroup',
  props: ['label', 'type', 'placeholder', 'maxlength', 'minlength', 'name', 'form', 'value', 'disabled', 'readonly', 'autofocus']

}
</script>

如果我们还需要传原生组件上的属性,例如name,id以及各种校验属性和事件,那么重复代码就会非常多。其实没有必要弄得这么复杂。Vue有个$props。如果结合v-bind可以简写成下面这样。不需要每个属性都写上:arrt=...这样的格式。

<template>
  <div class="input-group">
    <label>{{ label }}</label>
    <input ref="input"
               @input="$emit('input',$event.target.value)"
               v-bind="$props">
  </div>
</template>

<script>
export default {
  name: 'InputGroup',
  props: ['label', 'type', 'placeholder', 'maxlength', 'minlength', 'name', 'form', 'value', 'disabled', 'readonly', 'autofocus']
}
</script>
@yuxino
Copy link
Owner Author

yuxino commented Jan 10, 2018

一个烂大街的技巧。假设现在有个组件它渲染出来的标签应该长这样子。

<ul>
  <li class="fuck"></ li>
  <li class="vvv"></ li>
  <li class="fuck"></ li>
  <li class="vvv"></ li>
  <li class="fuck"></ li>
  <li class="vvv"></ li>
<ul>

那么我们如果想弄出这个效果很简单只要用template包装一下。

<ul>
  <template v-for="...">
       <li class="fuck"></ li>
       <li class="vvv"></ li>
  </template>
<ul>

@yuxino
Copy link
Owner Author

yuxino commented Jan 10, 2018

一个烂大街的技巧。假设你想让一个组件更改值就强行重新渲染。触发过渡效果的话。Just do it

<transition>
  <span :key="text">{{ text }}</span>
</transition>

原因是因为key是一个变量text。每次不一样会不停的重新渲染。最后触发过度。

@yuxino
Copy link
Owner Author

yuxino commented Jan 10, 2018

现在你有一个场景。假设是一个聊天对话框。你需要在收发信息后自动把滚动条滚动到最下面去。但是你不可以直接这么做,因为Vue的渲染需要一点点时间。这时候你需要用到vm.$nextTrick或者Vue.nextTrick。不知道的话看这里。然后通常你也许会这样子写。

// <ul :messages="messages">...</ul>
new Vue({
  ...
  props: ['messages'],
  watch: {
    'messages': function(val, oldVal) {
      this.$nextTick(function() {
        this.$el.scrollTop = this.$el.scrollHeight;
      });
    }
  }
  ...
});

嗯哼其实没毛病。但是就是不够优雅。你完全可以这样。因为一般项目是通过vue-cli创建的,带了babel,所以可以放心的使用async function。这样做看起来会好很多(大概)。

// <ul :messages="messages">...</ul>
new Vue({
  ...
  props: ['messages'],
  watch: {
    'messages': async function(val, oldVal) {
     await this.$nextTick;
     this.$el.scrollTop = this.$el.scrollHeight;
    }
  }
  ...
});

@yuxino
Copy link
Owner Author

yuxino commented Jan 10, 2018

v-debounce的源码 非常简单 但是非常实用。

module.exports = function debounce (fn, delay) {
  var timeoutID = null
  return function () {
    clearTimeout(timeoutID)
    var args = arguments
    var that = this
    timeoutID = setTimeout(function () {
      fn.apply(that, args)
    }, delay)
  }
}

@yuxino yuxino removed the note label Feb 10, 2018
@yuxino
Copy link
Owner Author

yuxino commented Mar 14, 2018

security code

@yuxino yuxino added the WIP label Mar 14, 2018
@yuxino yuxino removed the JavaScript label Apr 18, 2018
@fimars
Copy link

fimars commented Apr 26, 2018

Vuex + Typescript的最佳实践: vuejs/vuex#564

@yuxino
Copy link
Owner Author

yuxino commented Apr 26, 2018

@fimars thank . 我刚刚发现了一个有趣的东东 可以拿来测试网站的交互流程。 比如说可以输我看到了按钮。如果页面没有 那就不正常 。 告诉CI测试失败。

@Hazlank
Copy link

Hazlank commented May 25, 2018

new Vue({
  ...
  props: ['messages'],
  watch: {
    'messages':  async function(val, oldVal) {
     await this.$nextTick();
     this.$el.scrollTop = this.$el.scrollHeight;
    }
  }
  ...
});

@yuxino
Copy link
Owner Author

yuxino commented May 25, 2018

@Hazlank 打扰了

@Hazlank
Copy link

Hazlank commented May 25, 2018

@Nbsaw 打扰了,其实我是说你上面的列子 async放错地方了,$nextTic没执行

@yuxino
Copy link
Owner Author

yuxino commented May 25, 2018

@Hazlank 打扰了!以改

@Hazlank
Copy link

Hazlank commented May 25, 2018

@Nbsaw 你这是改了?

@yuxino yuxino removed the WIP label Apr 2, 2020
@yuxino yuxino closed this as completed Oct 9, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants