2

I'm building a javascript module (npm package) that serves as a validator for vue projects inspired from vee-validate. In the validator I have a few variables that I would need to reference in a vue component by destructuring and I need them to be reactive, therefore in the javascript module I import ref from the composition api and apply it on my variable.

Validator.js

import {ref} from '@vue/composition-api'

class Validator {
….

register({fieldName, rules, type}) {
    if (!fieldName || rules === null || rules === undefined) {
      console.error('Please pass in fieldName and rules');
      return false;
    }
    let errorMessages = ref([]); // Ref is used on this variable which gets populated with error messages (if any)
    const callback = ({id, messages}) => {
      if (fieldId === id) {
        errorMessages.value = Object.assign([], messages);
        console.log(errorMessages.value); // this contains the value of error messages. As you can see I still need to reference it using .value as one would on refs.
      }
    };
    return {
      errorMessages,
    };
  }
……

In my vue project I install the validator via NPM, and its core functionality works as it should. However, my issue is when I try to display the error messages on the template. Despite the errorMessages array getting the data it should, the variable is not reactive and therefore it does not update on the template. It feels like the reactivity is breaking somewhere, or it could be a scoping issue with I'm not too savvy with.

InputField.vue

<template>
  <div :style="{'width': fieldWidth}" class="form-group">
    <label :for="fieldName">
      <input
        ref="inputField"
        :type="type"
        :id="fieldName"
        :name="fieldName"
        :class="[{'field-error': apiError || errorMessages.length > 0}
        @input="handleInput"
        v-model="input"
        class="form-input"/>
    </label>
    <div>
      <p class="text-error">{{errorMessages}}</p> // Error messages not displaying
    </div>
  </div>
</template>

<script>
  import {ref, watch} from '@vue/composition-api';
  import Validator from "validator";

  export default {
    props: {
      fieldTitle: {
        required: true
      },
      fieldName: {
        required: true
      },
      type: {
        required: true
      },
      rules: {
        default: 'required'
      }
    },
    setup(props) {
      // The error messages are returned in the component but they are not reactive. Therefore they only appear after its re-rendered.
      const {errorMessages, handleInput, setFieldData} = Validator.register(props);

      return {
        errorMessages,
        handleInput,
      }
    }
  }
</script>

To build this package I'm not using a bundler as I simply need to export the classes/functions in order to publish to npm and install it in another project. Can someone kindly suggest what the issue could be here?

4
  • "To build this package I'm not using a bundler or package.json " - what does this mean? You need package.json any way. What does it look like? The obvious reason for reactivity to not work on import is that there are dupe vue packages. The lib shouldn't have its own vue dep. @vue/composition-api is Vue 2 lib, it's incorrect to use it if you want it to work with Vue 3. Commented Nov 18, 2021 at 8:35
  • @EstusFlask I am using package.json but I'm not using a bundler, apologies for the mistake. Through some research I've seen that bundlers like webpack are not required to create javascript packages as we simply need to use module.exports. I'm using the composition api from vue 2, which is why I import it like that.
    – thelandog
    Commented Nov 18, 2021 at 8:44
  • Please, provide package.json, both the project and the module. As I said, the first thing to look are dupe vue packages. The module should have peerDependencies with loose version constraints. For your case vue-demi is usually used, but if it's private package that is hard-coded to use Vue 2 then there's no difference Commented Nov 18, 2021 at 9:55
  • stackoverflow.com/questions/68879535/… Commented Dec 16, 2021 at 8:38

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.