文章目录
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的简单使用