0

I have an app with plain JS and Vue in one file. I need to pass a variable value from JS to Vue. 0. All code in one file:

<script>
plain js
var plainJS = 100;
</script>
<script>
 var app = new Vue({
        el: '#vue-app',
....
</script>
  1. main functionality of the app is on plain js. Vue does a small part with UI.

  2. with js I can catch if one of my elements changed position (a dot on the screen)

  3. I need fire popup(some alert) if checkBox is selected but the Dot wasn't moved.

  4. checkBox is a Vue element

  5. I can pass data from Django to Vue

     this.vueVar = {{ djangoVar|safe }}
    

So how to pass

*var plainJS = 100;*

to vue app from plain JS part of the code?

Can you give me a simple way to set vueVar = plainJS?

UPDATE:

function from plain JS

    function isDotMoved(length){
  if(length != 0){ 
    console.log(length)
    return true;
  } 
  return false;
};

so this function works when I grab and move my dot on the screen.

As well, I have a function in Vue part:

isDotsMoved(){
        this.dotMoved = isDotMoved(length); // function from plain JS
        console.log('moved', this.dotMoved)
        if(!this.dotMoved){
          toastr.info('Dot Moved');
        }             
      },

I call this function onClick. It should fire Alert if dots were moved.

I use another function the same way:

    function videoPause() {
       inputVideo.pause();   
   };

And called it inside of my Vue part:

        videoPauseVue() {
          videoPause(); //function from plain JS
        };

How can I do the same for isDotsMoved()?

4
  • are you trying to send it to vue during creation or run-time? Commented Jul 8, 2022 at 16:33
  • var plainJS can change any time, so I suppose it should be "run-time". Commented Jul 8, 2022 at 16:50
  • I'm also guessing that this is "progressive app", so you're implementing run time (not compiling the vue app) Commented Jul 8, 2022 at 19:29
  • I think the easiest might be to expose a method through the global window object from the app that will update the internal variable Commented Jul 8, 2022 at 19:31

3 Answers 3

1

First, i add isDotMoved function in the index.html script tag and declare it on window variable that can access anywhere in your code because it is global scope.

   <script>
      window.plainFunc = (function () {
        return {
          isDotMoved: function (length) {
            if (length != 0) {
              console.log(length);
              return true;
            }
            return false;
          }
        };
      })();
    </script>
Then in vue I access it throught window variable

<template>
  <div id="app">
    <h1>Use Function from plainJS</h1>
    <button @click="handleClick">Click here to invoke function isDotMove from script</script></button>
  </div>
</template>

<script>
function isDotsMoved() {
  let length = 10;
  let dotMoved = window.plainFunc.isDotMoved(length); // function from plain JS
  console.log("moved", dotMoved);
  if (!dotMoved) {
    alert("Dot Moved");
  }
}
export default {
  name: "App",
  methods: {
    handleClick: function () {
      isDotsMoved();
    },
  },
};
</script>

<style>
</style>

Check my example on codebox: https://codesandbox.io/embed/vue-js-font-awesome-1--getting-started-forked-d8xist?fontsize=14&hidenavigation=1&theme=dark

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks for the answer. I have only ONE file where plain js and vue are set together in separate <script> tags.
@AzamatUzbekov If you just pass data not listen to change then just set that data in window object like this window.plainJS = 100 than when you want to access it just use like window.plainJS it will return 100. Storge in window object is accessible over all js files that loaded to the browser. If not the method I show you above will still work even if your code is in a separate <script> tags
I added a window to var and function but no luck.
@AzamatUzbekov Hi check my edited code to see it fix your problem
thank you. I used window.plainJS from your previous comment. it worked.
0

You can access a ref on the root component if you store a variable of what createApp returns. Then each time you would update your plainJS var, also reassign a matching property (ref) on the "app" object. For the initial value you may use a "root prop" which is the 2nd param of the createApp function.

main.js

import { createApp } from "vue";
import App from "./App.vue";

var plainJS = 100;

const myApp = createApp(App, { plainJS: plainJS }).mount("#app"); 

setInterval(() => {
  //interval used here to simulate a value that changes at arbitrary times
  plainJS++;
  myApp.varFromOutsideVue = plainJS; // 👀 this updates the ref
}, 500);

App.vue

<template>
  <h1>{{ varFromOutsideVue }}</h1>
</template>

<script>
import { onMounted, onUnmounted, ref } from "vue";

export default {
  name: "App",
  props: {
    plainJS: { type: Number },
  },
  setup(props) {
    const varFromOutsideVue = ref(props.plainJS);

    return {
      varFromOutsideVue,
    };
  },
};
</script>

https://codesandbox.io/s/eager-rubin-6fv7p7?file=/src/main.js

3 Comments

hi. can you check the updates I added to the question?
Sorry, your edit is a little vague to me. Could you describe exactly what you are trying to do with isDotMoved (vanila) and isDotMoved (vue) and what error if any you are currently getting? FIrst impressions is you might need to place window. before isDotMoved(length); within your vue app.
thank you for your answer. yes, a simple window. helped me. never used it before.
0

Another option (see my other answer for a more direct solution) is to use the browser's native event system to "subscribe" to changes to the variable from within your vue app. Each time the value changes you emit a custom event and there is an event listener within your vue app set up to listen to those changes and update a reactive ref.

main.js

import { createApp } from "vue";
import App from "./App.vue";

var plainJS = 100;

function fireVarChangeEvent() {
  const newEvent = new CustomEvent("varchanged", {
    detail: plainJS
  });
  window.dispatchEvent(newEvent);
}

setInterval(() => {
  //interval used here to simulate a value that changes at arbitrary times
  plainJS++;
  fireVarChangeEvent(); // call this function after each time plainJs var is updated
}, 500);

createApp(App, { plainJS: plainJS }).mount("#app"); //pass in the first value of plainJS as a prop, this will not stay reactive, hence the custom event

App.vue

<template>
     <h1>{{ varFromOutsideVue }}</h1>
</template>

<script>
import { onMounted, onUnmounted, ref } from "vue";

export default {
  name: "App",
  props: {
    plainJS: { type: Number },
  },
  setup(props) {
    const varFromOutsideVue = ref(props.plainJS);

    function updateVar(e) {
      varFromOutsideVue.value = e.detail;
    }

    onMounted(() => {
      window.addEventListener("varchanged", updateVar);
    });

    onUnmounted(() => {
      window.removeEventListener("varchanged", updateVar);
    });

    return {
      varFromOutsideVue,
    };
  },
};
</script>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.