Vue 单文件组件与webpack的组合使用

1. 传统组件的问题和解决方案

1.1 问题

  • 全局定义的组件必须保证组件的名称不重复
  • 字符串模板缺乏语法高亮,在 HTML 有多行的时候,需要用到丑陋的 \
  • 不支持 CSS 意味着当 HTML 和 JavaScript 组件化时,CSS 明显被遗漏
  • 没有构建步骤限制,只能使用 HTML 和 ES5 JavaScript, 而不能使用预处理器(如:Babel)

1.2 解决方案

针对传统组件的问题,Vue 提供了一个解决方案 —— 使用 Vue 单文件组件。

2. Vue 单文件组件的基本用法

单文件组件的组成结构

  • template 组件的模板区域
  • script 业务逻辑区域
  • style 样式区域
<!-- App.vue -->
<template>

    组件代码区域

</template>

<script>

    js代码区域

</script>

<style scoped>
/* scoped 是代表私有的意思,避免与全局发生冲突*/
    样式代码区域

</style>

补充:安装Vetur插件可以使得.vue文件中的代码高亮

3. webpack 中配置 vue 组件的加载器

A. 安装vue组件的加载器

npm install vue-loader vue-template-compiler -D

B. 配置规则:更改webpack.config.js的module中的rules数组

   const VueLoaderPlugin = require("vue-loader/lib/plugin");
   //创建插件实例
    const vuePlugin = new VueLoaderPlugin();
    module.exports = {
        plugins:[  vuePlugin  ],
        module : {
            rules:[
                { 
                    test:/\.vue$/,
                    loader:"vue-loader",
                }
            ]
        }
    }

4. 在 webpack 项目中使用 vue

我们安装处理了vue单文件组件的加载器,想要让vue单文件组件能够使用,我们必须要安装vue,并使用vue来引用vue单文件组件。

A. 安装Vue

npm install vue -S

B. 在index.js中引入vue:

// 1. 导入 Vue 构造函数
import Vue from 'vue'
// 2. 导入 App 根组件
import App from './components/App.vue'

C. 创建Vue实例对象并指定el,最后使用render函数渲染单文件组件

//index.js
 const vm = new Vue({
 // first 是在index.html里指定div的id名 是root组件,其他组件将渲染到它里面
 //指定 vm 实例要控制的页面区域
        el:"#first",
 //通过 render 函数,把指定的组件渲染到 el 区域中      
 //这里的变量名与里导入时写的变量名一致
        render:h=>h(App)
    })

5. webpack 打包发布

上线之前需要通过webpack将应用进行整体打包,可以通过 package.json 文件配置打包命令:

A. 配置package.json

"scripts":{
     // 用于开发调试的命令
    "dev": "webpack-dev-server --open --host 127.0.0.1 --port 8080",
    // 用于打包的命令
    "build":"webpack -p"
}

B. 在项目打包之前,可以将dist目录删除,生成全新的dist目录

这样dist 文件夹里的就是我们发给后端,用来上线的文件了

案例及主要文档

  • 文档结构
    在这里插入图片描述
  • dist 文件中的index.html 文件与自己写在src/index.html(这是配置的入口文件)几乎一致,就是dist里的自动编译了script标签在页面底部
<!DOCTYPE html>
<html lang="en">

<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>
    <!-- <script src="./index.js"></script> -->
    <!-- <script src="../dist/main.js"></script> -->
    <!-- <script src="../dist/bundle.js"></script> -->
    <!-- 实时更新时在内存中的虚拟路径里 是我们看不见的 可以不写-->
    <!-- <script src="/bundle.js"></script> -->
</head>

<body>
    <input type="text" placeholder="ceshi" />
    <ul>
        <li>这是第1个li</li>
        <li>这是第2个li</li>
        <li>这是第3个li</li>
        <li>这是第4个li</li>
        <li>这是第5个li</li>
        <li>这是第6个li</li>
        <li>这是第7个li</li>
        <li>这是第8个li</li>
        <li>这是第9个li</li>
    </ul>

    <div id="box"></div>


    <hr />

    <!-- 将来要被 vue 控制的区域 -->
    <div id="app"></div>
<script type="text/javascript" src="bundle.js"></script></body>
//这是原index.html文件所没有的,编译时自动添加的
</html>
  • dist/bundle.js (这是在webpack.config.js中配置的出口文件)
    里面全是压缩过的js依赖以及编译文件的其他依赖
    在这里插入图片描述
  • App.vue
<template>
  <h1>
    hello.world
  </h1>
</template>

<script>
export default {};
</script>

<style scoped>
h1 {
  color: red;
}
</style>

  • index.js
import $ from "jquery";
import "../css/1.css";
import "../css/1.less";
// import "../css/1.scss";
$(function() {
  $("li:even").css("background", "navy");
  $("li:odd").css("background", "pink");
});

import Vue from "vue";
// 导入单文件组件
import App from "../components/App.vue";

const vm = new Vue({
  el: "#app",
  render: h => h(App)
});

  • 1.css
li {
  list-style: none;
}

/* 设置默认值的颜色 */
::placeholder {
  color: red;
}

#box {
  width: 580px;
  height: 340px;
  background-color: pink;
  background: url("../images/1.jpg");
}

  • webpack.config.js
const path = require("path");
// 导入可以生成一个预览页面的插件
const HtmlWebpackPlugin = require("html-webpack-plugin");
// 生成实例对象
const htmlPlguin = new HtmlWebpackPlugin({
  // 模板位置 自己目录可以找到
  template: "./src/index.html",
  // 生成的虚拟文件名  在内存里  我们看不到  index.html 会自动显示  默认规则  其他命名的不行
  filename: "index.html"
});
// 导入vue 文件插件
const VueLoaderPlugin = require("vue-loader/lib/plugin");

// 这里的模块化规范使用的是 Node 中的CommonJS
module.exports = {
  // 编译模式
  mode: "development", // development——开发时使用  production——上线时使用
  // 配置的打包入口
  entry: path.join(__dirname, "./src/js/index.js"),
  // 配置的打包出口
  output: {
    path: path.join(__dirname, "./dist"), // 输出文件的存放路径
    filename: "bundle.js" // 输出文件的名称
  },
  //
  // plugins: [htmlPlguin],
  // 创建vue插件实例
  plugins: [htmlPlguin, new VueLoaderPlugin()],
  module: {
    rules: [
      //style-loader 要写在 css-loader 之前 ;  解析是从后面向前解析 即先postcss -> css -> style  后面的依赖前面的
      { test: /\.css$/, use: ["style-loader", "css-loader"] },
      { test: /\.less$/, use: ["style-loader", "css-loader", "less-loader"] },
      //  这个的后缀名为scss不是sass
       { test: /\.scss$/, use: ["style-loader", "css-loader", "sass-loader"] }
      {
        test: /\.jpg|png|gif|bmp|ttf|eot|svg|woff|woff2$/,
        // limit  限制大小  小于这个值的才可以以base64的字符串格式显示在URL中   大于等于都是以图片路径显示
        use: "url-loader?limit=16941"
      },
      //   js高级语法解析                                   不转换node包里
      { test: /\.js$/, use: "babel-loader", exclude: /node_modules/ },
      //vue加载器
      { test: /\.vue$/, use: "vue-loader" }
    ]
  }
};

  • babel.config.js
module.exports = {
  presets: ["@babel/preset-env"],
  plugins: [
    "@babel/plugin-transform-runtime",
    "@babel/plugin-proposal-class-properties"
  ]
};

  • 效果图
    在这里插入图片描述

搭配文章参考地址:打包工具——webpack的简单使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值