ccforward / cc

Code & Blog
1.59k stars 193 forks source link

62.Vue.js Little Tips #67

Open ccforward opened 7 years ago

ccforward commented 7 years ago

Vue.js Little Tips

v-model

在输入框中双向绑定一个数据虽然可以这样写

<input :value="data" @input="data = $event.target.value">

但更应该这样写

<input v-model="data">

这一点没什么可说的,但由此我们应该知道是,在使用一个属性前,一定要提前定义,例子如下

https://ccforward.github.io/demos/vue-tips/v-model.html

没有提前定义 name 属性,所以 input 标签中改变 person.name 属性不会响应到 js 对象上

Name: <input v-model="person.name">
Phone: <input v-model="person.phone">
<pre>{{person}}</pre>
new Vue({
  el: '#app',
  data: {
    person: {
      phone: '110'
    }
  }
})

不能提前定义属性,就只能用 $set 和 $delete 来动态处理属性了

删除数组索引

在数组中删除一项的标准做法是用 Array.splice(index, 1)

del (index) {
  this.arr.splice(index ,1);
}

在 Vue.js 2.2.0+ 的版本里可以直接用 Vue.delete

del (index) {
  this.$delete(this.arr, index);
}

demo:

https://ccforward.github.io/demos/vue-tips/delete.html

选中 input 框中文字

这个比较简单,调用 select 方法即可

<input @focus="$event.target.select()">

组件中调用就需要加上 native 属性了

<component @focus.native="$event.target.select()"></component>

demo:

https://ccforward.github.io/demos/vue-tips/select.html

私有属性

如下代码

data: {
  name: 'name',
  _name: 'name'
},
mounted() {
  console.log(this.name, this._name);
}

结果输出为 "name" undefined

这是因为 以 _ 或者 $ 开头的属性只能 Vue 自身使用

demo

用 debounce 延迟计算 watch 属性

debounce 去抖 尤其适合在输入这种高频的操作中实时计算属性值

data: {
  text: '',
  inputing: false 
},
watch: {
  text: _.debounce(function () {
    this.inputing = false
  }, 1000)
}

顺手写个简单的 v-debounce 指令, 如下:

const debounce = (fn, delay) {
  let timer = null
  return function () {
    clearTimeout(timer)
    timer = setTimeout(_ => {
      fn.apply(this, arguments)
    }, delay)
  }
}

directive.debounce = debounce

function directive (el, binding) {
  if (binding.value !== binding.oldValue) { // change debounce only if interval has changed
    el.oninput = directive.debounce(_ => {
      el.dispatchEvent(new Event('change'))
    }, parseInt(binding.value) || 500)
  }
}
module.exports = directive

Vue.js 中使用 v-debounce:

<input v-debounce="delay" v-model="text" />
<p> {{text}} </p>
import debounce from './debounce.js'
export default {
  data () {
    return {
      text: 'some words',
      delay: 500
    }
  },
  directives: {debounce}
}

绑定 console.log

在 html 标签中无法使用 console.log 调试,但是只需要在 Vue 的原型链上增加 $log 函数即可

Vue.prototype.$log = console.log.bind(console);
new Vue({el: '#app'})

html 中就可以直接 console

  <input @keydown="$log" @keyup="$log" placeholder="input something">

在demo中打开控制台查看 demo

简写v-bind

data: {
  placeholder: 'this is text',
  required: true,
  value: '123',
  input: {
    placeholder: 'this is text',
    required: true,
    value: '123'
  }
}
<input :placeholder="placeholder" :required="required" :value="value">

如果 input 标签属性的属性很多,则可以直接绑定整个对象,如下:

<input v-bind="input">

demo

慎用 eval

偶尔用下 eval 体验体验 evil

用 eval 来做简单的数学计算

data: {
  input: '2**10 + 10*(1+1)'
},
computed: {
 exp () {
   var type = /[^\d*\/+\(\)-]/g
   var pow = /(\d+)\*\*(\d+)/g
   return this.input.replace(type, ' ').replace(pow, 'Math.pow($1, $2)')
 },

 result () {
   try {
     return eval(this.exp)
   } catch (e) {
     return e.message
   }
 }
}
<div id="app">
  <input v-model="input">
  <p>{{exp}} = {{result}}</p>
</div>

eval-demo

lbca commented 7 years ago

awesome!

JasonYadi commented 7 years ago

现在不知道从那个方向开始下手vue

ccforward commented 7 years ago

@JasonYadi

两步走:

  1. https://cn.vuejs.org/v2/guide/ 教程看一遍,官方文档写得很细了,代码也跟着实现一遍
  2. 把这个代码 https://cn.vuejs.org/v2/examples/index.html 抄一遍,边抄边理解
JasonYadi commented 7 years ago

@ccforward 谢谢 有什么不懂得可以问你不?

ccforward commented 7 years ago

@JasonYadi 没问题

madneal commented 7 years ago

@ccforward 你好,能不能推荐一个好用的vue轮播组件,我试了下vue-swiper和vue-swipe,但是都有点问题,官方的文档都太简陋了,不知道又没有在单独vue文件中使用这个的例子,或者你有什么好的组件推荐。谢谢