iview 中, switch 开关如何在 methods 中控制?

这是代码:

<i-switch size="small" :value="isEnable" @on-change="switch"/>
<script>
    new Vue({
        el: '#app',
        data: {
            isEnable: false
        },
        methods: {
            switchTokenLogin: function(status){
                this.isEnable = false;
            }
        }
    })
</script>

预想的是:当点击开关时(无论开或关),他总是处于关闭状态,但上面的代码却达不到,,设置了 isEnable 这个值页面不能正常重新渲染,,大佬们这个怎么解?

阅读 10k
6 个回答
新手上路,请多包涵

同样的需求,未找到直接操作switch的可实现的方法,选择其他方法实现了,方法如下:

<div class="switch-box">
    <div class="zhe" @click="handlestatus(index)"></div>
    <i-switch v-model="item.enable"></i-switch>
</div>

JS部分

handlestatus(index) {
    this.navList[index].enable = !this.navList[index].enable;
    let s = this.navList[index].enable;
    if (s) {
        if (this.showNavLeng >= 5) {
            this.navList[index].enable = false;
            this.$Message.warning('最多开启5个导航');
            return;
        }
        this.showNavLeng += 1;
    } else {
        this.showNavLeng -= 1;
    }
}

CSS部分

.switch-box {
    position: relative;
}
.switch-box > div.zhe {
    position: absolute;
    top: 0;
    left: 0;
    width: 44px;
    bottom: 0;
    z-index: 1;
}

iview没有相应的函数可以控制,不过可以使用disabled属性模拟

<i-switch v-model="switch1" @on-change="change" :disabled="!(disabled && switch1)"/>

data () {
    return {
        switch1: true,
        disabled: true
    }  
},
methods: {
    change (status) {
        this.disabled = false
    }
}

17:30补充

根据你发的链接看了下,刚开始以为是增加了before-change事件,但是查看文档,源码都没找到相应的内容,查了下三个版本的版本更新,也没有找到switch组件before-change的更新内容
switch点击和input事件

再次看了下链接上讲的,最后一个回复是

我认为Promise应该是开发者端配置的。而我们这样写的话:

    this.beforeChange().then((result)=>{
        // xxx
    })
本质上iView不用做任何处理,开发者使用时,他可以根据自己当前的情况来考虑要不要做Polyfill。

所以,他的意思是iview并没有增加相关事件,而是让我们用Promise自己实现,所以这就变成了需要我们自己等待状态改变后再去手动改变他的状态,那么使用Promise可以这么写

data () {
    return {
        switch1: true
    }  
},
methods: {
    beforeChange(val){
        return val ? new Promise((resolve) => {
        setTimeout(function () {
            resolve(true);
        }, 300);
        }) : false
    },
    change (status) {
        var r = this.beforeChange(status)
        r && r.then(()=>{
            this.switch1 = false
        })
    }
}

这种的就变成了状态由true改为false正常使用,但是由false变成true,会先改变为true,300ms(可自己定义时长)后状态再变成false

不知道你要的可是这种,我觉得你想要的应该是状态为false后不可点击。这个我觉得只能通过修改源码来实现了

当点击开关时(无论开或关),他总是处于关闭状态

你首先得把 value 缓存 v-model

我的代码示例:

<i-switch v-model="m1" :loading="loading">
            <span slot="open">开</span>
            <span slot="close">关</span>
        </i-switch>
        {{ m1 }}
        <div @click="m1 = false">toggle</div>
    
    data 里面:m1: true
   
新手上路,请多包涵

用v-model就可以解决

我也遇到了这个问题,最后直接基于iView源码重写了一个Switch组件,给Switch添加一个isControlled的属性,通过这个属性来在toggle方法中判断要不要修改currentValue的值。
iView里面只要你点击了Switch,就一定会触发这个handleToggle(除非设置了beforeChange),所以在这里做个拦截就行了。

clipboard.png

新手上路,请多包涵

大概解释下原因:除非表单提交以外,其它的数据绑定场景都应该是单向绑定原则,即以远端服务器数据为本,以此更新store/页面的state, 驱动UI更新。但是这里遇到的问题就是:switch改值之后保留了一个控件内部缓存了value的状态,而且这个状态不刷新整个页面不会从内存里清理,所导致了类似僵尸状态。
下面是解决方案:利用before-change来阻止on-change事件,保证switch不触发内部改值,具体做法参考官方示例:

 // 业务数据处理逻辑
    ......
 // 此处将阻止on-change发生
 return new Promise(resolve => {
                        return false
                      })

然后,