vue无需webpack打包直接在浏览器端运行的几种方法

vue无webpack直接在浏览器端运行的几种方法

vue无需webpack打包直接在浏览器端运行的几种方法

现在开发vue的应用,都是在nodejs下通过vue cli创建项目,然后编写代码,执行webpack devserver调试运行,最后通过webpack打包输出,那么vue可以实现无需webpack就能直接在浏览器上按需加载不同的vue和组件吗?当然可以,而且方案不止一种,下面我们来一个一个介绍一下:

一、Vue3原生支持

vue本来就可以在浏览器中开发,看看这个项目目录,我们先看main.js文件。

vue无需webpack打包直接在浏览器端运行的几种方法

main.js

///main.js

import App from './App.js';

import Home from './pages/Home.js';
import Center from './pages/Center.js';

// 2. 定义路由
// 每个路由应该映射一个组件

const routes = [
{
    path: '/',
    component:Home
},
{
    path: '/center',
    component:Center
}]

// 3. 创建 router 实例,然后传 `routes` 配置
// 你还可以传别的配置参数, 不过先这么简单着吧。
const router = VueRouter.createRouter({
  // 4. 通过 createWebHashHistory() 创建 hash 模式。
  history: VueRouter.createWebHashHistory(),
  routes, // (缩写) 相当于 routes: routes
})

const app = Vue.createApp({
    render: () => Vue.h(App),
});
app.use(router)
   app.use(ElementPlus) // 加载ElementPlus
app.mount('#app');

main.js写法跟vue cli的方式有点差异

不过组件的写法除了后缀必须为js外其他大致一样,我们看Home.js

import BaseButton from "../component/BaseButton.js"
export default {
  name: 'App',
  components: {
   BaseButton
  },
  data() {
    return {
      count: 0,
      visible:false
    };
  },
  template: `
    <div>
     <el-button @click="visible = true">Button</el-button>
       
      Count: {{ count }}
      <BaseButton @click="count += 1">
        +1
      </BaseButton>
      <h1>
       页面一
      </h1>
    </div>
  `,
};

完整的项目源码地址在bfwstudio上,可直接克隆并直接开发运行,项目webide地址:https://studio.bfw.wiki/Studio/Open.html?projectid=16291885208748360042

二、Vue3-sfc-loader插件支持

vue无需webpack打包直接在浏览器端运行的几种方法

我们还可以通过Vue3-sfc-loader这款插件来实现自定义vue文件的加载与处理,他需要重写import载入vue文件的方式,我们看index.js。

; (async () => {
    const randvar = Math.random();
    const options = {
        moduleCache: {
            vue: Vue
        },

        getFile(url) {
            return fetch(url+"?rand="+randvar).then(res => {
                if (!res.ok) throw Object.assign(new Error(url + ' ' + res.statusText), {
                    res
                });
                // ----------------------
                return res.text().then(content => {

                    if (/.*?\.mjs$/.test(url)) {

                        return {
                            content: content,
                            type: ".mjs"
                        }
                    }
                    return content;
                });
            })
        },
        addStyle(textContent) {
            document.head.insertBefore(
                Object.assign(document.createElement('style'),
                    {
                        textContent
                    }),
                document.head.getElementsByTagName('style')[0] || null);
        },
    };
    const {
        loadModule
    } = window['vue3-sfc-loader'];
    const loadVue = (vuePath) => loadModule(vuePath, options);
    const loadVueFile = (vuePath) => () => loadVue(vuePath);
    let routes = [
        /*首页*/
        {
            path: '/', name: "keepAliveTest1",
            meta: {
                keepAlive: true //设置页面是否需要使用缓存
            }, component: loadVueFile('./pages/Listdata.vue')},

        {
            path: '/login', name: "loginpage",
            meta: {
                keepAlive: true //设置页面是否需要使用缓存
            }, component: loadVueFile('./pages/Login.vue')},
        {
            path: '/center', name: "keepAliveTest2",
            meta: {
                keepAlive: true //设置页面是否需要使用缓存
            }, component: loadVueFile('./pages/Listdata.vue')},
        {
            path: '/date', name: "keepAliveTest3",
            meta: {
                keepAlive: true //设置页面是否需要使用缓存
            }, component: loadVueFile('./pages/datetime.vue')},
    ]
    const args = {
        name: 'app', components: {
            'layout': await loadVue('./layout.vue')}};

    const app = Vue.createApp(args)
    // app.config.errorHandler = function(err, vm, info) {
    //     console.log(`Error: ${err.toString()}\nInfo: ${info}`);
    // }
    // app.config.warnHandler = function(msg, vm, trace) {
    //     console.log(`Warn: ${msg}\nTrace: ${trace}`);
    // }
    const vueroutes = VueRouter.createRouter({
        history: VueRouter.createWebHashHistory(),
        routes: routes
    });
    window.globle = {
        "islogined": false
    };
  
    const store = new Vuex.Store({
        state: {
            islogined:  localStorage.getItem('islogined')
        },

        mutations: {
            updatelogin(state,
                payload) {
                    console.log(payload);
                var islogined = localStorage.setItem('islogined',true)
                
                state.islogined = payload.message;
            }
        }
    });
    app.config.globalProperties.$axios = axios;
    app.use(store)
    app.use(vueroutes)
    app.use(ElementPlus)
    app.mount("#app")

})().catch(ex => console.error(ex));

这里的实现方式有点类似于webpack,通过解析vue文件来自定义操作,完整代码在bfwstudio中,此项目的webide的项目地址为:https://studio.bfw.wiki/Studio/Open.html?projectid=16292046046205750018

三、http-vue-loader

通过http-vue-loader也可以实现,不过http-vue-loader只支持vue2,而Vue3-sfc-loader不仅支持vue3还支持vue2,我们先看看目录结构:

vue无需webpack打包直接在浏览器端运行的几种方法

核心在index.html中

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>Vue</title>
    <style>
        body {
            margin: 0;
            padding: 0;
        }
    </style>

    <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/vue@2.6.1.js"></script>
    <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/http-vue-loader.js"></script>
    <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/vue-router-3.01.js"></script>

</head>

<body>

    <div id="app">
        <router-link to="/"> 首页</router-link><br>
        <router-link to="/center"> 中心</router-link>
        <keep-alive>
            <router-view></router-view>
        </keep-alive>




    </div>
    <script>
        const routes = [{
            path: '/',
            component: httpVueLoader('component/Home.vue')
        },
            {
                path: '/center',
                component: httpVueLoader('component/Center.vue')
            }]

        // 3. 创建 router 实例,然后传 `routes` 配置
        // 你还可以传别的配置参数, 不过先这么简单着吧。
        const router = new VueRouter({
            // mode: 'history',
            routes // (缩写) 相当于 routes: routes
        })

        // 4. 创建和挂载根实例。
        // 记得要通过 router 配置参数注入路由,
        // 从而让整个应用都有路由功能
        const app = new Vue({
            router
        }).$mount('#app')
    </script>
</body>

</html>

http-vue-loader还可自定义插件处理css文件比如scss处理vue中的scss样式,还支持stylus等,非常强大。

本项目webide地址为https://studio.bfw.wiki/Studio/Open.html?projectid=16291942820236260041

四、总结

vue不依赖webpack和nodejs进行开发的方式是有的,只是体验上可能没有webpack devserver的流畅,例如错误提示,编译错误等只能通过console来查看,而且还不支持代码的混淆和压缩,但是我相信浏览器对es6 module的支持会让更多的vue应用摆脱webpack和nodejs的运行环境束缚,直接可以在浏览器中进行运行甚至打包混淆js源码的操作。

{{collectdata}}

网友评论0