PamanBeruang
PamanBeruang

Reputation: 1589

Import javascript file after component is mounted

i am building spa using vuejs as the frontend and laravel as the backend, and i purcased some admin bootstrap template named limitless (very cool admin template by the way).

But there is the problem with this template that in the main javascript file (app.js in admin directory) there is this line

// Calculate min height
    function containerHeight() {
        var availableHeight = $(window).height() - $('.page-container').offset().top - $('.navbar-fixed-bottom').outerHeight();

        $('.page-container').attr('style', 'min-height:' + availableHeight + 'px');
    }

    // Initialize
    containerHeight();

and because i am using spa vuejs so i only include all js file in my admin.blade.php file like this

<!DOCTYPE Html>
<Html lang="{{ config('app.locale') }}">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no' name='viewport'>
    <meta name="description" content="">
    <meta name="author" content="">
    <script>
        window.Laravel = <?php echo json_encode([
            'csrfToken' => csrf_token(),
        ]); ?>
    </script>
    <title>SIMO</title>
    <meta name="csrf-token" content="{{ csrf_token() }}" />
    <!-- icon-->
    <link rel="icon" href="{{asset('images/logo.png')}}" sizes="16x16">
    <link rel="icon" href="{{asset('images/logo.png')}}" sizes="32x32">
    <link rel="apple-touch-icon" href="{{asset('images/logo.png')}}"/>
    <link rel="apple-touch-icon" href="{{asset('images/logo.png')}}" sizes="76x76" />
    <link rel="apple-touch-icon" href="{{asset('images/logo.png')}}" sizes="120x120" />
    <link rel="apple-touch-icon" href="{{asset('images/logo.png')}}" sizes="152x152" />
    <link rel="apple-touch-icon" href="{{asset('images/logo.png')}}" sizes="180x180" />
    <!-- Bootstrap Core CSS -->
    <link href="https://fonts.googleapis.com/css?family=Roboto:400,300,100,500,700,900" rel="stylesheet" type="text/css">
    <link rel="stylesheet" type="text/css" href="{{asset('css/admin/icons/icomoon/styles.css')}}" >
    {{-- <link rel="stylesheet" type="text/css" href="{{asset('css/admin/icons/fontawesome/styles.min.css')}}" > --}}
    <link rel="stylesheet" type="text/css" href="{{asset('css/admin/bootstrap.css')}}" >
    <link rel="stylesheet" type="text/css" href="{{asset('css/admin/core.css')}}" >
    <link rel="stylesheet" type="text/css" href="{{asset('css/admin/components.css')}}" >
    <link rel="stylesheet" type="text/css" href="{{asset('css/admin/colors.css')}}" >
    @yield('css')

    <!-- Html5 Shim and Respond.js IE8 support of Html5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/libs/Html5shiv/3.7.0/Html5shiv.js"></script>
    <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->
</head>

<body>
<div id="app"></div>

<script type="text/javascript" src="{{ URL::asset('js/app.js') }}"></script>
<script type="text/javascript" src="{{ URL::asset('js/admin/plugins/loaders/pace.min.js') }}"></script>
<script type="text/javascript" src="{{ URL::asset('js/admin/libraries/jquery.min.js') }}"></script>
<script type="text/javascript" src="{{ URL::asset('js/admin/libraries/bootstrap.min.js') }}"></script>
<script type="text/javascript" src="{{ URL::asset('js/admin/plugins/loaders/blockui.min.js') }}"></script>
<script type="text/javascript" src="{{ URL::asset('js/admin/plugins/ui/nicescroll.min.js') }}"></script>
<script type="text/javascript" src="{{ URL::asset('js/admin/plugins/ui/drilldown.js') }}"></script>
<script type="text/javascript" src="{{ URL::asset('js/admin/plugins/buttons/hover_dropdown.min.js') }}"></script>
<script type="text/javascript" src="{{ URL::asset('js/admin/plugins/forms/selects/bootstrap_select.min.js') }}"></script>
<script type="text/javascript" src="{{ URL::asset('js/admin/plugins/ui/ripple.min.js') }}"></script>
<script type="text/javascript" src="{{ URL::asset('js/admin/app.js') }}"></script>

</body>
</Html>

and after inspecting the code i found out that it need div with class page-container and this div is located after header part so in my index.vue page i put it like this

<template>
<div>
   <div class="page-header">
     //here is header
   </div>
   <div class="page-container">
    //content
   </div>
</div>
</template>

so it will throw

Uncaught TypeError: Cannot read property 'top' of undefined

because when the page loaded it don't find any div with page-container class, since it not there yet.

And from what i read in vuejs documentation about lifecycle, this entire admin/app.js code should be run in mounted() or created() vuejs function. But from the example in documentation and around the internet it just used for run some javascript function but not include entire javascript file so it will be executed in there....

so my question is how to solve this? or for more simple way, how to add external css file and javascript file in component(this index.vue is called component right?) some people tell me to make it module and import it but i have no idea how to do that....

from what i know is i can download javascript plugin like moment from npm and it magically can be called within vue with import moment from moment but how about the local javascript files?

Upvotes: 1

Views: 9464

Answers (1)

Zany
Zany

Reputation: 79

when you use your local javascript files at your component ,you should import it. just like that:

// before you use your files in some components,you should package them
// your local files
export default {   //export your file
   your_function(){ // defined your function
   ...
   }
}

// now your can use it
// your component file

<script>
import local_file from 'your_file_relative_path'
//now you can use it in the hook function
created(){  //or other hook function
   local_file.your_function() //call your function
}

</script>

as for css file , your can also import it at style tag inside

//your component file
<style>
  @import 'your_css_file_path' 
  //or use requrie
  require('your_css_file_path')
<style>

Other way, write your js code outside of export,it maybe work

   //xxx.vue
   <script>
   var your_code='your_code'
   var your_function=function(){

   }
   export default{

   }
   </script>

update_1:

After a difficult battle,I use jQuery correctly in Vue.

First,you must make sure that you can use jQuery by introducing instead of using script tag which .This is very important!!!

the following is my way to introduce jQuery ,but my webpack is different from you,so do that in your way:

//package.json  //add the attributes and run npm install
"devDependencies": {
   "jquery" : "^2.2.3",
   ...
}

//webpack.base.conf.js
var webpack = require("webpack")
module.exports = {
   ...
    plugins: [ //use the plugin
        new webpack.optimize.CommonsChunkPlugin('common.js'),
        new webpack.ProvidePlugin({
            jQuery: "jquery",
            $: "jquery"
        })
    ]
}

//main.js,the file you instantiate Vue object just like your app.js
import $ from 'jquery'  //now you can use jQuery anywhere in the Vue files
...
const app = new Vue({
    router,
    render: h => h(Admin)
}).$mount('#app');

now you can use jQuery anywhere in the Vue files

//app.vue
<template>
    <div id="app">
        <router-view></router-view>
        <div class="page-container"></div>
    </div>
</template>

<script>
    //file name don't be like app.js in order to avoid conflict
    import yourApp from './yourApp.js'  
    export default {
        name: 'app',
        created() {
            yourApp.app_function()
           //now it can find .page-container class and not alert the error
        }
    }
</script>

Upvotes: 2

Related Questions