Vue旅程之使用directive告别onkeyup

在MVVM模式之前,做一个限制只能输入数字的 input 框应该会是这样的:

<input type="text" onkeyup="this.value = this.value.replace(/[^0-9]/g,'')">

但这种写法有时会因为浏览器间的差异或输入法的问题,导致了其输入内容不是我们想要的纯数字,而需要使用 oninput 这样一个非大众兼容的事件来归避输入法带来的影响。

使用Vuejs后,接触 vue 提供的 Vue.directive() ,用来监听其数据变化,来处理 value 。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script type="text/javascript" src="http://libs.cdnjs.net/vue/2.0.1/vue.min.js"></script>
</head>
<body>
    <div class="container" id="app">
        <input type="text" v-model="show" v-input-init />
        {{show}}
    </div>

</body>
</html>
<script type="text/javascript">
        // 定义 一个 directive 
        // 使用 v-input-init 调用
    Vue.directive('input-init',{
        update: function (el,binding) {
            el.value = el.value.replace(/[^0-9]+/gi,'');
        }
    });

    var vm = new Vue({
        el: "#app",
        data:{
            show: ''
        },
        methods:{
                        
        }
    });
</script>

以上做法,同样可以用来限制 Input 框的输入内容,而是通过监听数据的改变来及时发生变化,避免了键盘事件,复制,粘贴等问题的干扰。

但是这个写法也还有一个问题就是,没法改变data.show的值,故此还需稍微修改一下。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script type="text/javascript" src="http://libs.cdnjs.net/vue/2.0.1/vue.min.js"></script>
</head>
<body>
    <div class="container" id="app">
        <input type="text" v-model="show" v-input-init="{func: setShow}" />
        {{show}}
    </div>

</body>
</html>
<script type="text/javascript">
        // 定义 一个 directive 
        // 使用 v-input-init 调用
    Vue.directive('input-init',{
        update: function (el,binding) {
            var func = binding.value.func;
            
            var newVal = el.value.replace(/[^0-9]+/gi,'');
            func(newVal);
        }
    });

    var vm = new Vue({
        el: "#app",
        data:{
            show: ''
        },
        methods:{
            // 用于设置show的值
            setShow: function(nVal){
                this.show = nVal;
            }
        }
    });
</script>

Vue监听的是 data 对象下的属性值,故在第一步中,el.value的改变并不会触发data.show的变化。

使用 Object.defineProperty 来监听object.property的改变。

var data = {
    show: ''
};
Object.defineProperty(data,'show',{
    set: function(newVal){
        console.log('show is change:' + newVal);
        show = newVal;
    }
})
// show is change:change show
setTimeout(function(){
    data.show = 'change show'; // 
},1000)

 

posted @ 2017-07-06 21:52  marunzhou  阅读(410)  评论(0)    收藏  举报