安装组件后导入javascript文件

Posted

技术标签:

【中文标题】安装组件后导入javascript文件【英文标题】:Import javascript file after component is mounted 【发布时间】:2018-01-24 15:20:26 【问题描述】:

我正在使用 vuejs 作为前端和 laravel 作为后端来构建 spa,并且我购买了一些名为 limitless 的管理引导模板(顺便说一下非常酷的管理模板)。

但是这个模板的问题是在主javascript文件(admin目录中的app.js)中有这一行

// 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();

因为我使用的是 spa vuejs,所以我只在我的 admin.blade.php 文件中包含所有 js 文件,像这样

<!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>

在检查代码后,我发现它需要带有 page-container 类的 div,而这个 div 位于标题部分之后,所以在我的 index.vue 页面中我这样写

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

所以它会抛出

Uncaught TypeError: Cannot read property 'top' of undefined

因为当页面加载时它没有找到任何带有page-container 类的 div,因为它还没有。

根据我在 vuejs 文档中读到的关于生命周期的内容,整个 admin/app.js 代码应该在 mount() 或 created() vuejs 函数中运行。但是从文档中的示例和互联网上的示例来看,它仅用于运行一些 javascript 函数,但不包括整个 javascript 文件,因此它将在那里执行....

所以我的问题是如何解决这个问题?或者更简单的方法,如何在组件中添加外部 css 文件和 javascript 文件(这个 index.vue 被称为组件对吗?)有些人告诉我让它成为模块并导入它,但我不知道该怎么做.. ..

据我所知,我可以从 npm 下载类似 moment 的 javascript 插件,并且可以在 vue 中使用 import moment from moment 神奇地调用它,但是本地 javascript 文件呢?

【问题讨论】:

【参考方案1】:

当您在组件中使用本地 javascript 文件时,您应该导入它。 就这样:

// 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>

css文件也可以在style标签里面导入

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

另外,在导出之外编写你的 js 代码,它可能会工作

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

   
   export default

   
   </script>

更新_1:

经过一场艰苦的战斗,我在Vue中正确使用了jQuery。

首先,你必须确保你可以通过引入而不是使用脚本标签来使用jQuery这很重要!!!

下面是我介绍jQuery的方式,但是我的webpack和你不一样,那就按照你的方式来吧:

//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');

现在您可以在 Vue 文件中的任何位置使用 jQuery

//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>

【讨论】:

抱歉,我的项目是 laravel 和 vuejs,所以我的资产文件夹与 vuejs 不同,所以如何获得正确的路径? 这个比较尴尬,建议你把js文件放到vue项目中。另外,我看到你在index.html中引入了很多js文件,可能不太好,因为它占用了很多流量。我想你可以在使用时介绍它们。 这就是重点,我只想引入与当前视图有关的 JS 文件,并且我已经尝试过,我将所有 js 文件放在那里并导入它......但仍然得到同样的错误......只是不要;不明白 这里我的项目在 github github.com/t0n1zz/bkcuvue 请注意这是 laravel 之一,所以如果你不熟悉 laravel,vue 文件位于 resources/assets/js 和我的 index.html 中(在这种情况下,我使用 admin.blade.php)位于资源/视图中并编译它只需在根目录中运行 npm run watch 我跑了 NPM run watch,然后我访问了 localhost://8020,什么也没发生。如何访问您的页面?

以上是关于安装组件后导入javascript文件的主要内容,如果未能解决你的问题,请参考以下文章

用 JavaScript 实现手势库 — 手势动画应用前端组件化

用 JavaScript 实现手势库 — 手势动画应用前端组件化

用 JavaScript 实现手势库 — 封装手势库前端组件化

用 JavaScript 实现手势库 — 封装手势库前端组件化

用 JavaScript 实现手势库 — 手势动画应用前端组件化

用 JavaScript 实现手势库 — 封装手势库前端组件化