简体   繁体   中英

Vue JS router component - Cannot re-use JS file that uses webpack imports after navigating between routes

Alright, so this issue I'm having is a bit complicated but I'll try to be as clear as possible with what's happening here. First of all, I am using the latest Vue and Vue-Router in my application with webpack.

This is a single-file component named

CP.vue

<template>
...
</template>

<script>
    export default {
        data() {
            return {
            }
        },
        created() {
            Load();
            const JS = () => import('cp.js');
            JS();
            console.log("created");

        },
        mounted() {
            Show();
        },
        destroyed() {
            console.log("destroyed");
        },
        methods: { }

    }
</script>

And this is how cp.js begins

cp.js

console.log("cp created");

// Bootstrap Datepicker
import '../../../node_modules/bootstrap-datepicker/dist/css/bootstrap-datepicker.css';
// Switchery
import '../../../node_modules/mohithg-switchery/switchery.css';
// TreeView CSS 
import '../../../node_modules/patternfly-bootstrap-treeview/dist/bootstrap-treeview.css';
// Datatables CSS 
import '../../../node_modules/datatables.net-bs4/css/dataTables.bootstrap4.css';
// Datatables - Button CSS 
import '../../../node_modules/datatables-buttons/css/buttons.dataTables.scss';
/////////////////////////// Toastr - for warnings
import '../../../node_modules/toastr/build/toastr.min.css';
////////////////////////// ScrollBar 
import '../../../node_modules/perfect-scrollbar/src/css/main.scss';
// CSS
import '../../scss/pages/cp.scss';

.....
.... more JS code which never works the second time
.....

/*----------  DatePicker  ----------*/

const datePicker = $('#date-range').datepicker({
    toggleActive: true,
    format: 'dd/mm/yyyy',
    autoclose: true,
    daysOfWeekHighlighted: "0,6",
    weekStart: 1,
    endDate: 'today',
    maxDate: 'today',
    startDate: '01/01/2014'
});
/*----------  ScrollBar  ----------*/

$('#tree-container').perfectScrollbar();
// there's more, but it's a long file so I cut it short

^ The modules here are loaded with lazy-load. When I first navigate to the path of CP.vue, the template shows and the JS file loads fine. You can see "cp created" in the console. However, when I move to a path of another component in the vue router and then return to /cp, all the functionalities from cp.js no longer work (date picker, etc), while the style it imported on the first time is still intact, and console.log("cp created") doesn't even run, which means it only loads cp.js once, and when you re-navigate to /cp the functions of the script are gone. So you have to refresh the page for it to work again which is exactly what I don't want to do hence the reason I'm using VueRouter. I tried searching for people who had the issue all over the internet, tried plugins like "vue-plugin-load-script" to try and unload the script and load it again whenever the component is created and destroyed, but nothing works. Only the approach with using this code

const JS = () => import('cp.js');
JS();

To even load the js file works because plugins like "vue-plugin-load-script" don't recognize esx syntax.

Does anyone know a way I can reuse cp.js eveytime the component is created again when I navigate between components in vue router? Or maybe a different approach that will work for loading that JS file... Thank you.

As I said you should redesign your code. The script is evaluated only once, you could do nothing about it, and it's the right way it should work.

cp.js :

export function initComponents()  {
  const datePicker = $('#date-range').datepicker({
    toggleActive: true,
    format: 'dd/mm/yyyy',
    autoclose: true,
    daysOfWeekHighlighted: "0,6",
    weekStart: 1,
    endDate: 'today',
    maxDate: 'today',
    startDate: '01/01/2014'
  });
  /*----------  ScrollBar  ----------*/

  $('#tree-container').perfectScrollbar();
}

and from your component:

import( /* webpackChunkName: "cp.js" */ 'cp.js').then(exports => {
  exports.initComponents();
});

EDIT : Also it's bad practice defining component ids in your custom file. I would recommend to use vue-datepickers. There're a lot of them Well, if you still wanna use custom datepicker, you could pass htmlNode as parameter to your initComponent function. But I guess the best choice would be creating component named datePicker and put all js code into create method there. Also you could pack your css files into scoped css section instead of having global css.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM