从0到1 将静态网页项目进行工程化 - 引入Vue(第三章)

前言: 在上两节中,我们将一个原生项目通过webapck进行了工程化改造,通过导入打包js,css等文件、复用了部分html结构,最后还将打包文件进行了压缩等。 这一章节就将此基础上引入Vue,通过本章的学习,可以熟练的将原生项目快速转化为Vue项目SPA,MPA进行二次开发

无工程化项目地址

tsx 复制代码
https://github.com/NewCoder798/ZBestPC

webpack多配置文件改造 将当前项目的webpack.config.js配置文件单独放在一个文件中便于管理,同时需要在package.json中修改打包命令,注意! 需要修改webpack.config.js中的打包路径!

json 复制代码
"build": "webpack --config build/webpack.config.js"

添加Vue

初始化vue3

引入vue库,让vue先跑起来。

  • 下载依赖
tsx 复制代码
npm i -S vue          
npm i -D @vue/compiler-sfc
npm i -D vue-template-compiler
npm i -D vue-loader        
  • 初始化vue

在build目录下创建webpack.vue.config.js

tsx 复制代码
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
// 路径别名
const { ProvidePlugin } = require('webpack')
// 拷贝文件
const CopyWebpackPlugin = require('copy-webpack-plugin')
// 将 CSS 提取到单独的文件中,为每个包含 CSS 的 JS 文件创建一个 CSS 文件
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
// js压缩
const TerserPlugin = require('terser-webpack-plugin')
// css压缩
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')

// vue配置
const { VueLoaderPlugin } = require('vue-loader')

module.exports = {
  mode: 'development',
  // 入口
  entry: {
    index: path.resolve(__dirname, '../src/main.js'),
  },
  output: {
    filename: 'js/[name].js',
    path: path.resolve(__dirname, '../dist'),
  },
  devServer: {
    static: {
      directory: path.resolve(__dirname, 'dist'),
    },
    port: 3000,
    // 服务器压缩
    compress: true,
    // 自动打开浏览器
    open: true,
    // 开启热更新
    hot: true,
  },
  module: {
    rules: [
      // 解析vue文件
      {
        test: /\.vue$/,
        loader: 'vue-loader',
      },
      {
        test: /\.css$/,
        // use: ['style-loader', 'css-loader'],
        use: [MiniCssExtractPlugin.loader, 'css-loader'],
      },
      {
        // 打包文件
        test: /\.(png|svg|jpg|jpeg|gif)$/i,
        // webpack自带
        type: 'asset',
        // 如果图片小于8kb,就会被转换成base64
        parser: {
          dataUrlCondition: {
            maxSize: 8 * 1024,
          },
        },
        // 大于8kb的图片会被打包到images文件夹下
        generator: {
          filename: 'images/[name].[hash:6][ext]',
        },
      },
      // ejs 复用模版
      {
        test: /\.ejs$/,
        loader: 'ejs-loader',
        options: {
          esModule: false,
        },
      },
    ],
  },
  optimization: {
    // 是否开启代码压缩
    minimize: true,
    // 代码优化
    minimizer: [
      // js 代码压缩
      new TerserPlugin({ parallel: true }),
      // css代码压缩
      new CssMinimizerPlugin(),
    ],
    // 代码分割
    splitChunks: {
      // 代码最小的分割大小
      minSize: 300 * 1024,
      // async 异步代码分割 initial 同步代码分割 all 同步异步代码分割都开启
      chunks: 'all',
      // 名称
      name: 'common',
      // 这里可以继续打包第三方库
      cacheGroups: {
        lodash: {
          test: /lodash-es/,
          name: 'lodash-es',
          // 优先级
          // priority:10,
          chunks: 'all',
        },
        jquery: {
          test: /jquery/,
          name: 'jquery',
          // priority: 10,
          chunks: 'all',
        },
      },
    },
  },
  plugins: [
    new VueLoaderPlugin(),
    // 配置首页资源
    new HtmlWebpackPlugin({
      filename: 'index.html',
      template: path.resolve(__dirname, '../public/index.html'),
      chunks: ['index'],
    }),
    // 从.. 拷贝文件 至..
    new CopyWebpackPlugin({
      patterns: [
        {
          from: path.resolve(__dirname, '../src/img'),
          to: path.resolve(__dirname, '../dist/img'),
        },
      ],
    }),
    // css压缩
    new MiniCssExtractPlugin({
      filename: 'css/[name].css',
      chunkFilename: 'css/[name].chunk.css',
    }),
    new CleanWebpackPlugin(),
  ],
}
  • public/index
tsx 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
    <style></style>
  </head>

  <body>
    <div id="app"></div>
  </body>
</html>
  • main.js
tsx 复制代码
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)
app.mount('#app')
  • App.vue
tsx 复制代码
<script setup>
import { ref } from 'vue'
const message = ref('工程化 - Vue')
</script>

<template>
    <div id="app">{{ message }}</div>
</template>

<style></style>
  • 增加启动命令
tsx 复制代码
"scripts": {
    "start": "webpack-dev-server",
    "start:vue": "webpack-dev-server --config build/webpack.vue.config.js",
    "build": "webpack --config build/webpack.config.js",
    "build:vue": "webpack --config build/webpack.vue.config.js"
},

首页和登录页面移植到Vue - SPA

首页移植

  • 将首页的html复制到Home.vue

注意 如何报找不到jquery 说明在webpack中没有设置路径别名。

vue 复制代码
<script setup>
  import './css/index.css'
  import './css/public.css'
  import 'jquery'
  import 'flexslider'
  import './js/public'
  import './js/nav'
</script>

<template>
  <div>
    <!------------------------------head------------------------------>
    <div class="head">
    <div class="wrapper clearfix">
    <div class="clearfix" id="top">
    <h1 class="fl"><a href="index.html"><img src="img/logo.png" /></a></h1>
    <div class="fr clearfix" id="top1">
    <p class="fl">
    <a href="#" id="login">登录</a>
    <a href="#" id="reg">注册</a>
  </p>
    <form action="#" method="get" class="fl">
    <input type="text" placeholder="热门搜索:干花花瓶" />
    <input type="button" />
  </form>
    <div class="btn fl clearfix">
    <a href="mygxin.html"><img src="img/grzx.png" /></a>
    <a href="#" class="er1"><img src="img/ewm.png" /></a>
    <a href="cart.html"><img src="img/gwc.png" /></a>
    <p><a href="#"><img src="img/smewm.png" /></a></p>
  </div>
  </div>
  </div>
    <ul class="clearfix" id="bott">
    <li><a href="index.html">首页</a></li>
    <li>
    <a href="#">所有商品</a>
    <div class="sList">
    <div class="wrapper  clearfix">
    <a href="paint.html">
    <dl>
    <dt><img src="img/nav1.jpg" /></dt>
    <dd>浓情欧式</dd>
  </dl>
  </a>
    <a href="paint.html">
    <dl>
    <dt><img src="img/nav2.jpg" /></dt>
    <dd>浪漫美式</dd>
  </dl>
  </a>
    <a href="paint.html">
    <dl>
    <dt><img src="img/nav3.jpg" /></dt>
    <dd>雅致中式</dd>
  </dl>
  </a>
    <a href="paint.html">
    <dl>
    <dt><img src="img/nav6.jpg" /></dt>
    <dd>简约现代</dd>
  </dl>
  </a>
    <a href="paint.html">
    <dl>
    <dt><img src="img/nav7.jpg" /></dt>
    <dd>创意装饰</dd>
                                    </dl>
                                </a>
                            </div>
                        </div>
                    </li>
                    <li>
                        <a href="flowerDer.html">装饰摆件</a>
                        <div class="sList2">
                            <div class="clearfix">
                                <a href="proList.html">干花花艺</a>
                                <a href="vase_proList.html">花瓶花器</a>
                            </div>
                        </div>
                    </li>
                    <li>
                        <a href="decoration.html">布艺软饰</a>
                        <div class="sList2">
                            <div class="clearfix">
                                <a href="zbproList.html">桌布罩件</a>
                                <a href="bzproList.html">抱枕靠垫</a>
                            </div>
                        </div>
                    </li>
                    <li><a href="paint.html">墙式壁挂</a></li>
                    <li><a href="perfume.html">蜡艺香薰</a></li>
                    <li><a href="idea.html">创意家居</a></li>
                </ul>
            </div>
        </div>
        <!-------------------------banner--------------------------->
        <div class="block_home_slider">
            <div id="home_slider" class="flexslider">
                <ul class="slides">
                    <li>
                        <div class="slide">
                            <img src="img/banner2.jpg" />
                        </div>
                    </li>
                    <li>
                        <div class="slide">
                            <img src="img/banner1.jpg" />
                        </div>
                    </li>
                </ul>
            </div>
        </div>

        <!------------------------------thImg------------------------------>
        <div class="thImg">
            <div class="clearfix">
                <a href="vase_proList.html"><img src="img/i1.jpg" /></a>
                <a href="proList.html"><img src="img/i2.jpg" /></a>
                <a href="#2"><img src="img/i3.jpg" /></a>
            </div>
        </div>

        <!------------------------------news------------------------------>
        <div class="news">
            <div class="wrapper">
                <h2><img src="img/ih1.jpg" /></h2>
                <div class="top clearfix">
                    <a href="proDetail.html"><img src="img/n1.jpg" />
                        <p></p>
                    </a>
                    <a href="proDetail.html"><img src="img/n2.jpg" />
                        <p></p>
                    </a>
                    <a href="proDetail.html"><img src="img/n3.jpg" />
                        <p></p>
                    </a>
                </div>
                <div class="bott clearfix">
                    <a href="proDetail.html"><img src="img/n4.jpg" />
                        <p></p>
                    </a>
                    <a href="proDetail.html"><img src="img/n5.jpg" />
                        <p></p>
                    </a>
                    <a href="proDetail.html"><img src="img/n6.jpg" />
                        <p></p>
                    </a>
                </div>
                <h2><img src="img/ih2.jpg" /></h2>
                <div class="flower clearfix tran">
                    <a href="proDetail.html" class="clearfix">
                        <dl>
                            <dt>
                                <span class="abl"></span>
                                <img src="img/flo1.jpg" />
                                <span class="abr"></span>
                            </dt>
                            <dd>【花艺】七头美丽玫瑰仿真花束</dd>
                            <dd><span>¥ 79.00</span></dd>
                        </dl>
                    </a>
                    <a href="proDetail.html">
                        <dl>
                            <dt>
                                <span class="abl"></span>
                                <img src="img/flo2.jpg" />
                                <span class="abr"></span>
                            </dt>
                            <dd>【花艺】七头美丽玫瑰仿真花束</dd>
                            <dd><span>¥ 79.00</span></dd>
                        </dl>
                    </a>
                    <a href="proDetail.html">
                        <dl>
                            <dt>
                                <span class="abl"></span>
                                <img src="img/flo3.jpg" />
                                <span class="abr"></span>
                            </dt>
                            <dd>【花艺】七头美丽玫瑰仿真花束</dd>
                            <dd><span>¥ 79.00</span></dd>
                        </dl>
                    </a>
                </div>
                <div class="flower clearfix tran">
                    <a href="proDetail.html">
                        <dl>
                            <dt>
                                <span class="abl"></span>
                                <img src="img/flo4.jpg" />
                                <span class="abr"></span>
                            </dt>
                            <dd>【花艺】七头美丽玫瑰仿真花束</dd>
                            <dd><span>¥ 79.00</span></dd>
                        </dl>
                    </a>
                    <a href="proDetail.html">
                        <dl>
                            <dt>
                                <span class="abl"></span>
                                <img src="img/flo5.jpg" />
                                <span class="abr"></span>
                            </dt>
                            <dd>【花艺】七头美丽玫瑰仿真花束</dd>
                            <dd><span>¥ 79.00</span></dd>
                        </dl>
                    </a>
                    <a href="proDetail.html">
                        <dl>
                            <dt>
                                <span class="abl"></span>
                                <img src="img/flo6.jpg" />
                                <span class="abr"></span>
                            </dt>
                            <dd>【花艺】七头美丽玫瑰仿真花束</dd>
                            <dd><span>¥ 79.00</span></dd>
                        </dl>
                    </a>
                </div>
            </div>
        </div>

        <!------------------------------ad------------------------------>
        <a href="#" class="ad"><img src="img/ib1.jpg" /></a>

        <!------------------------------people------------------------------>
        <div class="people">
            <div class="wrapper">
                <h2><img src="img/ih3.jpg" /></h2>
                <div class="pList clearfix tran">
                    <a href="proDetail.html">
                        <dl>
                            <dt>
                                <span class="abl"></span>
                                <img src="img/s7.jpg" />
                                <span class="abr"></span>
                            </dt>
                            <dd>【最家】不锈钢壁饰墙饰软装</dd>
                            <dd><span>¥688.00</span></dd>
                        </dl>
                    </a>
                    <a href="proDetail.html">
                        <dl>
                            <dt>
                                <span class="abl"></span>
                                <img src="img/s10.jpg" />
                                <span class="abr"></span>
                            </dt>
                            <dd>【最家】小城动物木板画壁挂北欧</dd>
                            <dd><span>¥188.00</span></dd>
                        </dl>
                    </a>
                    <a href="proDetail.html">
                        <dl>
                            <dt>
                                <span class="abl"></span>
                                <img src="img/s4.jpg" />
                                <span class="abr"></span>
                            </dt>
                            <dd>【最家】玄关假山水壁饰背景墙饰挂件创意</dd>
                            <dd><span>¥599.00</span></dd>
                        </dl>
                    </a>
                    <a href="proDetail.html">
                        <dl>
                            <dt>
                                <span class="abl"></span>
                                <img src="img/s9.jpg" />
                                <span class="abr"></span>
                            </dt>
                            <dd>【最家】金属树枝壁饰铜鸟装饰品</dd>
                            <dd><span>¥928.00</span></dd>
                        </dl>
                    </a>
                </div>
                <div class="pList clearfix tran">
                    <a href="proDetail.html">
                        <dl>
                            <dt>
                                <span class="abl"></span>
                                <img src="img/s6.jpg" />
                                <span class="abr"></span>
                            </dt>
                            <dd>【最家】金属壁饰创意背景墙面挂件创意</dd>
                            <dd><span>¥228.00</span></dd>
                        </dl>
                    </a>
                    <a href="proDetail.html">
                        <dl>
                            <dt>
                                <span class="abl"></span>
                                <img src="img/s8.jpg" />
                                <span class="abr"></span>
                            </dt>
                            <dd>【最家】小城动物木板画壁挂北欧</dd>
                            <dd><span>¥199.00</span></dd>
                        </dl>
                    </a>
                    <a href="proDetail.html">
                        <dl>
                            <dt>
                                <span class="abl"></span>
                                <img src="img/s12.jpg" />
                                <span class="abr"></span>
                            </dt>
                            <dd>【最家】欧式复古挂钟创意餐厅钟表家居挂件</dd>
                            <dd><span>¥666.00</span></dd>
                        </dl>
                    </a>
                    <a href="proDetail.html">
                        <dl>
                            <dt>
                                <span class="abl"></span>
                                <img src="img/s1.jpg" />
                                <span class="abr"></span>
                            </dt>
                            <dd>【最家】客厅地中海欧式现代相片墙创意</dd>
                            <dd><span>¥59.80</span></dd>
                        </dl>
                    </a>
                </div>
                <div class="pList clearfix tran">
                    <a href="proDetail.html">
                        <dl>
                            <dt>
                                <span class="abl"></span>
                                <img src="img/s5.jpg" />
                                <span class="abr"></span>
                            </dt>
                            <dd>【最家】铁艺荷叶壁挂软装背景墙上装饰品</dd>
                            <dd><span>¥800.00</span></dd>
                        </dl>
                    </a>
                    <a href="proDetail.html">
                        <dl>
                            <dt>
                                <span class="abl"></span>
                                <img src="img/s3.jpg" />
                                <span class="abr"></span>
                            </dt>
                            <dd>【最家】欧式照片墙 创意组合结婚礼物</dd>
                            <dd><span>¥189.00</span></dd>
                        </dl>
                    </a>
                    <a href="proDetail.html">
                        <dl>
                            <dt>
                                <span class="abl"></span>
                                <img src="img/s2.jpg" />
                                <span class="abr"></span>
                            </dt>
                            <dd>【最家】欧式钟表相框墙挂墙创意组合</dd>
                            <dd><span>¥148.00</span></dd>
                        </dl>
                    </a>
                    <a href="proDetail.html">
                        <dl>
                            <dt>
                                <span class="abl"></span>
                                <img src="img/s11.jpg" />
                                <span class="abr"></span>
                            </dt>
                            <dd>【最家】小城动物木板画壁挂北欧</dd>
                            <dd><span>¥188.00</span></dd>
                        </dl>
                    </a>
                </div>
            </div>
        </div>
        <!--返回顶部-->
        <div class="gotop">
            <a href="cart.html">
                <dl>
                    <dt><img src="img/gt1.png" /></dt>
                    <dd>去购
物车</dd>
                </dl>
            </a>
            <a href="#" class="dh">
                <dl>
                    <dt><img src="img/gt2.png" /></dt>
                    <dd>联系
客服</dd>
                </dl>
            </a>
            <a href="mygxin.html">
                <dl>
                    <dt><img src="img/gt3.png" /></dt>
                    <dd>个人
中心</dd>
                </dl>
            </a>
            <a href="#" class="toptop" style="display: none">
                <dl>
                    <dt><img src="img/gt4.png" /></dt>
                    <dd>返回
顶部</dd>
                </dl>
            </a>
            <p>400-800-8200</p>
        </div>

        <!-------------------login-------------------------->
        <!--footer-->
        <div class="footer">
            <div class="top">
                <div class="wrapper">
                    <div class="clearfix">
                        <a href="#2" class="fl"><img src="img/foot1.png" /></a>
                        <span class="fl">7天无理由退货</span>
                    </div>
                    <div class="clearfix">
                        <a href="#2" class="fl"><img src="img/foot2.png" /></a>
                        <span class="fl">15天免费换货</span>
                    </div>
                    <div class="clearfix">
                        <a href="#2" class="fl"><img src="img/foot3.png" /></a>
                        <span class="fl">满599包邮</span>
                    </div>
                    <div class="clearfix">
                        <a href="#2" class="fl"><img src="img/foot4.png" /></a>
                        <span class="fl">手机特色服务</span>
                    </div>
                </div>
            </div>
            <p class="dibu">最家家居&copy;2013-2017公司版权所有 京ICP备080100-44备0000111000号

                违法和不良信息举报电话:400-800-8200,本网站所列数据,除特殊说明,所有数据均出自我司实验室测试</p>
        </div>
    </div>
</template>

<style></style>

引入vue-router

因为还需要引入Login页面,所有需要路由,来进行SPA单页面的应用

vue 复制代码
import { createRouter, createWebHashHistory } from 'vue-router'
const publicRoutes = [
  {
    path: '/',
    redirect: '/home',
  },
  {
    path: '/home',
    name: 'home',
    component: () => import('../Home.vue'),
  },
  {
    path: '/login',
    name: 'login',
    component: () => import('../login.vue'),
  },
]

const router = createRouter({
  history: createWebHashHistory(),
  routes: publicRoutes,
})
  
export default router

登录页移植

只要将html复制过来,并且将css导入即可

vue 复制代码
<script setup>
import '../css/public.css'
import '../css/login.css'
</script>

<template>
    <div class="login">
        <form action="#" method="post">
            <h1><a href="index.html"><img src="img/temp/logo.png"></a></h1>
            <p></p>
            <div class="msg-warn hide"><b></b>公共场所不建议自动登录,以防账号丢失</div>
            <p><input type="text" name="" value="" placeholder="昵称/邮箱/手机号"></p>
            <p><input type="text" name="" value="" placeholder="密码"></p>
            <p><input type="submit" name="" value="登  录"></p>
            <p class="txt"><a class="" href="reg.html">免费注册</a><a href="forget.html">忘记密码?</a></p>
        </form>
    </div>
</template>

<style scoped></style>

首页和登录页面移植到Vue - MPA

mpa会根据页面产生多个html文件,有利于seo, 通过webpack也可以将项目改造成mpa

  • 修改入口文件 一个页面 就有一个Vue实例也就是单独一个入口文件
vue 复制代码
import { createApp } from 'vue'
import App from '../views/Home.vue'
const app = createApp(App)
app.mount('#app')
vue 复制代码
import { createApp } from 'vue'
import App from '../views/Login.vue'
const app = createApp(App)
app.mount('#app')
  • 修改webpack

分别修改打包入口 以及HtmlWebpackPlugin

vue 复制代码
  // 配置文件入口
  entry: {
    home: path.resolve(__dirname, '../src/mpa/Home.js'),
    login: path.resolve(__dirname, '../src/mpa/Login.js'),
  },


引入资源分别打包
new HtmlWebpackPlugin({
  filename: 'home.html',
  template: path.resolve(__dirname, '../public/index.html'),
  chunks: ['home'],
}),
new HtmlWebpackPlugin({
  filename: 'login.html',
  template: path.resolve(__dirname, '../public/index.html'),
  chunks: ['login'],
}),

像Vue一样在控制台百分比显示编译进度

vue 复制代码
const { ProgressPlugin } = require('webpack') 使用这个插件即可!
相关推荐
崔庆才丨静觅7 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60617 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了7 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅8 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅8 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅8 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment8 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅9 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊9 小时前
jwt介绍
前端
爱敲代码的小鱼9 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax