javascript - 在 Vue 组件实例上更新 Prop 的正确方法是什么

标签 javascript vue.js

我正在尝试找出更新在组件实例上创建的 propsData 的最佳方法。基本上我有一个签名包装页面,并收到一堆使用 v-html 呈现的 html。然后我在呈现的 html 中创建可变数量的签名板组件。因为我不知道 html 是什么,所以我被迫(我能说的最好)在安装后即时创建组件。

所以我在父 mounted() 上运行以下命令:

    initializeSignaturePads() {

        const signatureAreas = document.querySelectorAll('.signature_area');

        // dynamically create a new vue instance for each signature pad and mount onto the respective .signature_area element
        // since the html is loaded via ajax, we don't know where to render this template on load, so a new Vue must be created
        signatureAreas.forEach(element => {
            const id = element.id;
            const signatureType = element.classList.contains('initials') ? 'initials' : 'signature';

            if (this.needsCustomerSignature(id)) {
                let length = this.signatures.push({
                    fieldName: id,
                    valid: false,
                    data: null,
                    type: signatureType
                });

                const SignaturePadClass = Vue.extend(SignaturePad);
                const SignaturePadInstance = new SignaturePadClass({
                    parent: this,
                    propsData: {
                        fieldName: id,
                        editable: true,
                        signatureType: signatureType,
                        signatureIndex: length - 1,
                        signatureData: null
                    }
                });

                // add handler for signed emit
                SignaturePadInstance.$on('signed', signature => {
                    this.padSigned(signature);
                });

                // watch this for an accepted signature, then pass to each child
                this.$watch('createdSignature.accepted', function (val) {
                    let signatureData = null;

                    if (val) {
                        signatureData = signatureType == 'signature' ? this.createdSignature.signatureData : this.createdSignature.initialsData;
                    }

                    // These two lines are the problem
                    SignaturePadInstance._props.signatureData = signatureData;
                    SignaturePadInstance._props.editable = !val;
                });

                SignaturePadInstance.$mount(element);
            }
        });
    },

据我所知,propsData 现在是在组件上静态设置的。但是对于 signatureDataeditable Prop ,我需要能够在子组件更新时将其传递给它们。观察者工作正常, Prop 正在更新,但我收到了 Avoid mutating a prop directly 警告。这是可以理解的,因为我直接改变了 child 的 Prop 。有没有好的方法来处理这个问题?

最佳答案

在我找到这个 stackoverflow answer 之后,我就明白了这一点.在 propsData 上设置 Prop 时,我使用的是所有原始类型,因此它们没有内置的响应式(Reactive) getter 和 setter。现在我意识到,我所做的相当于将字符串作为 prop 传递给组件元素。在我这样做之后, Prop 是响应式(Reactive)的,我不必费心手动创建观察者。

无论如何,这是解决方案:

const SignaturePadInstance = new SignaturePadClass({
    parent: this,
    propsData: {
        fieldName: id, // << primitive
        editable: true, // << primitive
        signatureType: signatureType, // << primitive
        signatureIndex: length - 1,  // << primitive
        createdSignature: this.createdSignature  // << reactive object, updates to the child when changed
    }
});

关于javascript - 在 Vue 组件实例上更新 Prop 的正确方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51072796/

相关文章:

javascript - 更改已安装组件的数据的正确方法是什么?

javascript - 在浏览器调整大小时更改超链接位置

javascript - JQPlot:如何在不同位置重新绘制

javascript - 具有相同名称javascript的函数声明中的函数声明

javascript - 将 Kendo 网格数据发布到 MVC 中的 Controller

javascript - 在jquery中初始化一个函数一次

javascript - Vue.js 在列表中显示 v-show

javascript - 为什么代理在浏览器中不起作用(NuxtJS+Axios)?

vue.js - 如何从网址中删除主题标签?

javascript - 如何使用 Vuelidate minValue maxValue