维.这段代码去哪里了? [英] Vue. Where does this code go?

查看:23
本文介绍了维.这段代码去哪里了?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们开始使用 Vue,并且非常喜欢 store 的想法,将页面状态与展示分开.我们编写了一个 zippy 警报组件,用于显示 store.pageError 中的任何警报字符串.

We jumped into Vue, and totally loved the idea of a store, separating page state from presentation. We wrote a zippy alert component, that displayed whatever alert string was in store.pageError.

然后我们想添加confirm(),所以我们给了我们的组件一个ref和一个返回promise的popConfirm()方法,每当我们想确认某事时,我们就调用...

Then we wanted to add confirm(), so we gave our component a ref, and a popConfirm() method that returned a promise, and whenever we wanted to confirm something, we called...

vm.$refs.alertConfirm.confirm("Are you sure?")
.then(function(conf){if(conf) /* do it */ })

...并且该组件负责管理自己的可见性,而商店中没有发生任何事情.

...and the component became responsible for managing its own visibility, without anything happening in the store.

这非常有效,很快许多组件开始产生 refs,因此它们可以作为方法直接调用.在最新的版本中,我们实现了一个六步隧道,api 调用和用户操作与 Promise.all() 并行调用,效果很好,但是 store 倒退了一大步,越来越多的 state直接在 Vue 组件中管理.这些组件不再是存储状态的愚蠢表示,而是越来越少的内部管理状态的功能序列.

This worked so well that soon lots of components started sprouting refs, so they could be called directly as methods. In the latest incarnation, we implemented a tunnel with six steps, with api calls and user actions called in parallel with Promise.all(), and it works great, but the store has taken a big step back, and more and more state is being managed directly in Vue components. These components are no longer dumb representations of store state, but increasingly little functional sequences with state managed internally.

我们如何重申 store 的想法,同时保持将这些简短的函数序列称为方法的便利性?

How do we reassert the idea of a store, while keeping the convenience of calling these short functional sequences as methods?

这是我们的隧道代码.这目前存在于 Vue 组件的 methods 中,其中标记、状态和顺序逻辑愉快地混合在一起.这不会好吗?

Here is our tunnel code. This currently lives in the methods of a Vue component, where markup, state, and sequential logic are joyously mixed. This can't be good?

startTunnel(idNote) {
    var rslt = {
        idNote: idNote,
        photoJustif: null,
        date: null,
        currency: "",
        montant: null
    }
    //---------------Step 1: photo et count notes in parallel
    Promise.all([
      me.$refs.camera.click(),
      getUrlAsJson("api/note/getNotes"),
    ])
    //---------------Step 2: Choose note if > 1
    .then(function (results) {
        rslt.photoJustif = results[0];
        me.$refs.loader.hide();
        // if we already know the note, go straight to Step 3.
        if (rslt.idNote)
            return true;

        // if no idNote supplied, and only one returned from server, assign it.
        if (results[1].notes.length === 1 && !rslt.idNote) {
            rslt.idNote = results[1].notes[0].idNote;
            return true;
        }
        else {
            return me.$refs.chooseNote.choose(results[1].notes)
            // combine photoJustif from Step 1 with idNote chosen just above.
            .then(function (idNoteChosen) { rslt.idNote = idNoteChosen; return true })
        }
    })
    //--------------Step 3: OCR
    .then(() => me.doOcr(rslt))
    //--------------Step 4: Choose nature and retrieve card statement from server in parallel
    .then(function (ocrResult) {
        me.$refs.loader.hide()
        if (ocrResult != null) { //Si ocr n'a pas échoué
            rslt.date = ocrResult.date;
            rslt.montant = ocrResult.montant;
            rslt.currency = ocrResult.currency;
            return Promise.all([
              me.$refs.chooseNature.init(rslt.idNote, ocrResult.grpNatures),
              getUrlAsJson("api/expense/relevecarte/filterpers", { IdPerson: 1, montant: ocrResult.montant })
            ]);
        }
        else return null;
    })

    //--------------Step 5: Choose card transaction
    .then(function (natureAndFraisCartes) { 
        if (natureAndFraisCartes != null) {
            rslt.idNature = natureAndFraisCartes[0].id;
            if (rslt.montant != null && natureAndFraisCartes[1].length > 1)
                return me.$refs.choixFraisCarte.init(rslt, natureAndFraisCartes[1]);
            else
                return null;
        }
        else return null;
    })
    //------------- Step 6: End tunnel
    .then(function (fraisCarte) {
        me.$refs.loader.popInstant();
        me.$refs.form.idNote.value = rslt.idNote;
        var jsonObject;

        if (fraisCarte != null) {
            me.$refs.form.action.value = 15;
            jsonObject = {
                "DateFrais": rslt.date,
                "IdNature": rslt.idNature,
                "MontantTicket": rslt.montant,
                "Justificatif": rslt.photoJustif,
                "idCarte": fraisCarte.id
            };
        }
        else {
            me.$refs.form.action.value = 14;
            jsonObject = {
                "DateFrais": rslt.date,
                "IdNature": rslt.idNature,
                "MontantTicket": rslt.montant,
                "Justificatif": rslt.photoJustif,
                "idCarte": 0
            };
        }

        me.$refs.form.obj.value = JSON.stringify(jsonObject);
        me.$refs.form.submit();
    })
    .catch(function (error) {
        me.$refs.loader.hide();
        me.active = false;
        me.rslt = {
            idNote: idNote,
            photoJustif: null,
            date: null,
            montant: null
        };
        console.log(error);
        vueStore.pageError = me.allStrings.tunnelPhoto.erreurTunnel;
    })
}

推荐答案

看起来问题在于你从声明式思考转向命令式思考.当你想确认某事时,你应该设置一个 confirmPrompt 数据项,并且组件应该以与观察警报字符串大致相同的方式观察它.

It looks like the problem is that you got away from thinking declaratively and went to thinking imperatively. When you want to confirm something, you should set a confirmPrompt data item, and the component should be watching it in much the same way it watches the alert string.

确认响应应该有一个数据项来指示您是在等待响应,还是已确认或已取消.都是程序状态.

There should be a data item for the confirmation response to indicate whether you're waiting for a response, or it was confirmed or it was canceled. It's all program state.

使用 $refs 是一种代码异味.这并不总是错的,但您应该始终考虑为什么要这样做.诸如 me.$refs.loader.hide(); 之类的东西建议程序状态更改应该通过设置 loaderIsVisible 数据项来控制,例如.

Using $refs is a code smell. It's not always wrong, but you should always think about why you're doing it. Things like me.$refs.loader.hide(); suggest program state changes that should be controlled by setting a loaderIsVisible data item, for example.

这篇关于维.这段代码去哪里了?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆