【前端Vue】05|【前端Vue】05 - [插槽 ,前端模块化开发,webpack]

1. 插槽 1.1 插槽的基本使用 组件的插槽:

  1. 组件的插槽也是为了让我们封装的组件更加具有扩展性。
  2. 让使用者可以决定组件内部的一些内容到底展示什么。
定义插槽的步骤
  1. 在组件中使用一个特殊的元素可以为组件开启一个插槽。
  2. 该插槽插入什么内容取决于父组件如何使用。
【前端Vue】05|【前端Vue】05 - [插槽 ,前端模块化开发,webpack]
文章图片
插槽的基本使用
用户 更多 收藏

/* * 1. 插槽的基本使用 * 2. 插槽的默认值 * 3. 如果有多个值同时放入到插槽中进行替换的时候,一起作为替换元素。 * */ const app = new Vue({ el: '#app', data: {}, components: { 'cpn': { template: '#cpn' } } });

1.2 具名插槽
  1. 定义具名插槽,需要在slot标签中使用 name属性标识该插槽的名称,在使用时在具体的标签中使用 slot属性指定需要替换的插槽的名称。
【前端Vue】05|【前端Vue】05 - [插槽 ,前端模块化开发,webpack]
文章图片
具名插槽slot
我是标题 返回 返回 我是标题 用户

const app = new Vue({ el: '#app', data: {}, components: { 'cpn': { template: '#cpn' } } });

1.3 编译作用域 【前端Vue】05|【前端Vue】05 - [插槽 ,前端模块化开发,webpack]
文章图片
编译作用域

const app = new Vue({ el: '#app', data: { isShow: true }, components: { 'cpn': { template: '#cpn', data() { return { isShow: false } } } } });

1.4 作用域插槽
  1. 当子组件中的数据使用了默认的显示方式,但是父组件希望拿到子组件的数据在其基础上修改显示方式,就可以使用作用域插槽。
作用域插槽的使用步骤
  1. 在子组件中定义一个插槽,可以指定一种默认的显示方式。并在插槽上使用自定义属性绑定一个子组件的数据,传递给父组件。
【前端Vue】05|【前端Vue】05 - [插槽 ,前端模块化开发,webpack]
文章图片
通过自定义属性传递数据
  1. 父组件使用 template标签 和 slot-scope属性获取来自子组件的数据,在slot-scope中指定一个属性接收数据。
【前端Vue】05|【前端Vue】05 - [插槽 ,前端模块化开发,webpack]
文章图片
接收数据

/* 作用域插槽是父组件替换插槽的标签,但是内容由子组件提供 *//* 问题:如何在父组件中拿到子组件中的数据 */ const app = new Vue({ el: '#app', data: {}, components: { cpn: { template: '#cpn', data() { return { pLanguage: ['JavaScript', 'Java', 'C++', 'C#'] }; } } } });

2. 前端模块化开发 2.1 JavaScript原始功能 存在的问题
  1. 客户端需要完成的事情越来越多,代码量也是与日俱增。
  2. 为了应对代码量的剧增,我们通常会将代码组织在多个js文件中,进行维护。
  3. 但是这种维护方式,依然不能避免一些灾难性的问题。
如下面的代码
  1. index.html

  1. xiaoming.js
// 小明的文件 var name = '小明'; var age = 23; function sum(a, b) { return a + b; }var flag = true; if (flag) { console.log(sum(12, 36)); }

  1. xiaohong.js
// 小红的js文件 var name = '小红'; console.log(name); var flag = false;

  1. tiancai.js
if (flag) { console.log('我真是个天才'); }

  1. 上面代码由于调用顺序问题,和变量名重名问题,导致后面的代码修改了前面的变量,出现问题。
2.2 解决方案:匿名函数
  1. 我们可以使用匿名函数来解决方面的重名问题,在 xiaoming.js 文件中。
【前端Vue】05|【前端Vue】05 - [插槽 ,前端模块化开发,webpack]
文章图片
匿名函数的方式解决变量命名冲突问题 3. webpack 对打包的理解
  1. 理解了webpack可以帮助我们进行模块化,并且处理模块间的各种复杂关系后,打包的概念就非常好理解了。
  2. 就是将webpack中的各种资源模块进行打包合并成一个或多个包(Bundle)。
  3. 并且在打包的过程中,还可以对资源进行处理,比如压缩图片,将scss转成css,将ES6语法转成ES5语法,将TypeScript转成JavaScript等等操作。
3.1 webpack 的介绍和安装
  1. webpack要正常运行必须依赖于nodenode为了可以正常执行很多代码,必须包含各种包。
  2. 查看自己的node版本:
node -v 或者 node --version

  1. 全局安装webpack(这里我先指定版本号3.6.0,因为vue cli2依赖该版本)。
npm install webpack@3.6.0 -g

  1. 局部安装webpack(后续才需要)。
cd对应目录npm install webpack@3.6.0 --save-dev

为什么全局安装后,还需要局部安装呢?
  1. 在终端直接执行webpack命令,使用的全局安装的webpack
  2. 当在package.json中定义了scripts时,其中包含了webpack命令,那么使用的是局部webpack
3.2 webpack 的基本使用
  1. 在项目文件夹下创建 distsrc文件夹。dist文件夹用于存放的是打包完成的文件。src存放的是打包之前的文件。
  2. 场景 : 创建 main.jsmathUtils.jsinfo.js三个文件。在项目下创建 index.html文件。下面分别使用 CommonJs 模块化 和 ES6模块化。最终使用 webpack 打包
  3. main.js 分别导入 info.jsmathUtils.js 的模块。
/* CommonJS的方式 */ const {add, mul} = require('./mathUtils.js'); console.log(add(20, 30)); console.log(mul(100, 10)); /* 使用ES6的方式 */ import {age, height, name} from './info.js'; console.log(name); console.log(age); console.log(height); /* webpack 打包命令 : 1. 切换到当前目录 ; 2. 使用 webpack ./src/main.js ./dist/bundle.js 进行打包; */

  1. info.js 使用ES6模块化方式。
export const name = '张三'; export const age = 23; export const height = 1.88;

  1. mathUtils.js使用CommonJs 模块化方式。
function add(a, b) { return a + b; }function mul(a, b) { return a * b; }/* CommonJs的方式 */ module.exports = { add, mul };

  1. 使用命令进行打包操作:webpack ./src/main.js ./dist/bundle.js
3.3 webpack.config.js配置和package.json配置 webpack.config.js 文件
  1. 在项目下创建一个 webpack.config.js 的文件,定义打包的对象。
【前端Vue】05|【前端Vue】05 - [插槽 ,前端模块化开发,webpack]
文章图片
webpack.config.js文件
  1. 上面文件定义完成之后便可以在项目路径下使用 webpack 命令直接打包了。
  2. 初始化 package.json 文件配置命令映射。使用 npm init 命令初始化package.json文件。
【前端Vue】05|【前端Vue】05 - [插槽 ,前端模块化开发,webpack]
文章图片
webpack命令映射
  1. 如上配置之后可以使用 npm run build打包项目。
  2. 但是此时使用打包的webpack是全局安装的webpack但是在之后可能全局webpack版本和项目使用的webpack版本不一致的情况,此时就需要在项目的目录下自己安装一个本地(局部)webpack。使用命令npm install webpack@3.6.0 --save-devcnpm install webpack@3.6.0 --save-dev 但是不建议使用 cnpm ,我试过可能因为下载太快,我使用 webstorm加载过程中非常卡 。
【前端Vue】05|【前端Vue】05 - [插槽 ,前端模块化开发,webpack]
文章图片
局部的webpack安装完成之后 3.4 什么是loader?
  1. 【【前端Vue】05|【前端Vue】05 - [插槽 ,前端模块化开发,webpack]】webpack 可以使用 loader 来预处理文件。这允许你打包除 JavaScript之外的任何静态资源。loader 可以将所有类型的文件转换为 webpack 能够处理的有效模块,然后你就可以利用 webpack 的打包能力,对它们进行处理。本质上,webpack loader 将所有类型的文件,转换为应用程序的依赖图(和最终的 bundle)可以直接引用的模块。
  2. 在我们之前的实例中,我们主要是用webpack来处理我们写的js代码,并且webpack会自动处理js之间相关的依赖,但是,在开发中我们不仅仅有基本的js代码处理,我们也需要加载css、图片,也包括一些高级的将ES6转成ES5代码,将TypeScript转成ES5代码,将scssless转成css,将.jsx.vue文件转成js文件等等。对于webpack本身的能力来说,对于这些转化是不支持的。那怎么办呢?给webpack扩展对应的loader就可以啦。
3.5 loader使用过程:
  1. 步骤一:通过npm安装需要使用的loader
  2. 步骤二:在webpack.config.js中的modules关键字下进行配置。
  3. 大部分loader我们都可以在webpack的中文网中找到。
3.6 使用 css-loader 和 style-loader 的场景
  1. 编写一个样式文件 noemal.css文件,在 main.js(入口文件)中进行使用 require() 引入。
require('./css/normal.css');

  1. 此时如果使用 nom run build 打包的话将会出现下面一个问题。
【前端Vue】05|【前端Vue】05 - [插槽 ,前端模块化开发,webpack]
文章图片
需要一个合适的loader
  1. 查看官方文档,使用命令安装 css-loader 此时未指定版本默认是最新版本。
npm install --save-dev css-loader

  1. 安装完成之后在webpack.config.js中进行配置:
【前端Vue】05|【前端Vue】05 - [插槽 ,前端模块化开发,webpack]
文章图片
数组默认从右往左读
  1. 配置完成之后,发现尚未可??? 原来是还缺少了一个loader style-loaderstyle-loader 将模块的导出作为样式添加到 DOM 中。安装 style-loader
npm install style-loader --save-dev

  1. 安装配置完成还有个问题 ??? ,,, (node:58300) UnhandledPromiseRejectionWarning: TypeError: this.getResolve is not a function。 百度一下发现,是我的版本太高了,我按照提示将 package.json下的依赖版本进行修改,重新使用 npm install 对依赖进行安装之后。终于可以了。
【前端Vue】05|【前端Vue】05 - [插槽 ,前端模块化开发,webpack]
文章图片
修改style-loader 和 css-loader 的版本 3.7 webpack 对 less 文件的处理
  1. 在开发过程中我们大多数时候会使用到less语法,所以 webpack需要提供对 less的支持。
  2. 安装less-loader ,但是 less-loader 需要 less支持。同时需要安装 less
npm install --save-dev less-loader less // 这样安装的是最新版的,后面会出问题 可以后面修改版本或者现在修改版本npm install --save-dev less-loader@4.1.0 less@4.1.0

  1. 安装完成之后在webpack.config.js中配置less-loader :
{ test: /\.less$/, use: [{ loader: "style-loader" // creates style nodes from JS strings }, { loader: "css-loader" // translates CSS into CommonJS }, { loader: "less-loader" // compiles Less to CSS }] }

【前端Vue】05|【前端Vue】05 - [插槽 ,前端模块化开发,webpack]
文章图片
在webpack.config.js中配置less-loader 3.8 webpack对图片文件的处理案例
  1. 准备两张图片,大小分别一大一小。之后可以设置文件大小一个分界线。
  2. 在样式中设置背景图片:该样式文件已经在main.js中引入,到时候打包将会将样式文件打包为一个模块。
body { /*background-color: #f00; */ background: url(../images/green-logo.png) no-repeat; background-size: cover; }

body { /*background-color: #f00; */ background: url(../images/green-logo-mini.png) no-repeat; background-size: cover; }

  1. 使用 npm run build 进行打包,发现需要安装适当的 loader
【前端Vue】05|【前端Vue】05 - [插槽 ,前端模块化开发,webpack]
文章图片
You may need an appropriate loader to handle this file type.
npm install --save-dev url-loader

  1. 安装完成之后在 webpack.config.js文件中进行配置:options: {} 中配置的是打包的一些属性。limit 相当于文件大小的分界线,如果超出该分界线是需要file-loader的支持的。
{ test: /\.(png|jpg|gif|jpeg)$/, use: [ { loader: 'url-loader', options: { /* 当图片小于指定的尺寸的时候回将其转换为base64位的图片 */ limit: 10240 } } ] }

【前端Vue】05|【前端Vue】05 - [插槽 ,前端模块化开发,webpack]
文章图片
配置url-loader
【前端Vue】05|【前端Vue】05 - [插槽 ,前端模块化开发,webpack]
文章图片
需要file-loader的支持
  1. 安装 file-loader ,npm install --save-dev file-loader
url-loader中options对象的属性 name
  1. name属性:name: 'img/[name].[hash:8].[ext]'
img:文件要打包到的文件夹;
name:获取图片原来的名字,放在该位置;
hash:8:为了防止图片名称冲突,依然使用hash,但是我们只保留8位;
ext:使用图片原来的扩展名。
3.9 babel 对 ES6 语法的处理 babel-loader
未使用babel-loader转换打包,还存在const关键字声明变量。
【前端Vue】05|【前端Vue】05 - [插槽 ,前端模块化开发,webpack]
文章图片
未使用babel-loader转换打包
  1. 使用babelES6转为 ES5
  1. 安装 babel-loadernpm install --save-dev babel-loader@7 babel-core babel-preset-es2015
  2. web.config.js中配置 babel-loaderexclude 属性用于排除某些文件夹,不对其进行转换。
{ test: /\.js$/, /* exclude 是排除的意思 */ /* include 是包含的意思 */ exclude: /(node_modules|bower_components)/, use: { loader: 'babel-loader', options: { presets: ['es2015'] } } }

【前端Vue】05|【前端Vue】05 - [插槽 ,前端模块化开发,webpack]
文章图片
使用babel-loader转换之后 3.10 webpack配置Vue的过程
  1. 使用命令npm install --save vue安装Vue,在main.js中导入Vue
// 1. 导入 vue import Vue from 'vue';

  1. 使用Vue输出一段文字。
const app = new Vue({ el: '#app', data: { message: 'Hello webpack!' } });

  1. 启动运行时发现出现下面的问题,是因为在Vue打包中有很多的版本其中有两个是 runtime-onlyruntime-compiler
【前端Vue】05|【前端Vue】05 - [插槽 ,前端模块化开发,webpack]
文章图片
使用runtime-only导致的问题
  1. 解决:在webpack.config.js文件中module同层级下配置如下代码
resolve:{ alias:{ 'vue$':'vue/dist/vue.esm.js' } }

【前端Vue】05|【前端Vue】05 - [插槽 ,前端模块化开发,webpack]
文章图片
webpack.config.js下进行配置 Vue打包的两个版本
  1. runtime-only: 代码中,不可以有任何的 template
  2. runtime-compiler: 代码中可以有 template,因为compiler可以用于编译 template
3.11 使用创建Vuetemplateel的关系 【前端Vue】05|【前端Vue】05 - [插槽 ,前端模块化开发,webpack]
文章图片
template和el的关系
  1. 在前面的Vue实例中,我们定义了el属性,用于和index.html中的#app进行绑定,让Vue实例之后可以管理它其中的内容。
  2. 上面我们将页面中 包裹的代码删除,在main.js中使用template编写相应的模板进行替换。
3.12 Vue的终极使用方案 使用 JS方式文件分离组件 【前端Vue】05|【前端Vue】05 - [插槽 ,前端模块化开发,webpack]
文章图片
使用JS文件分离模板的方式
  1. 但是使用这种方式还是未将 templatejs代码相分离开。
创建 Vue文件的方式分离组件
  1. 需要提前安装一个loader vue-loadervue-template-compiler
npm install vue-loader vue-template-compiler --save-dev

  1. webpack.config.js中配置vue-loader
{ test: /\.vue$/, use: { loader: 'vue-loader' } }

【前端Vue】05|【前端Vue】05 - [插槽 ,前端模块化开发,webpack]
文章图片
在`webpack.config.js`中配置`vue-loader`
  1. 创建一个 Vue component :
/* 样式相关 */ h2 { color: #00f !important; }

  1. 注意 vue-loader的版本问题。改为 13.0.0
【前端Vue】05|【前端Vue】05 - [插槽 ,前端模块化开发,webpack]
文章图片
出现这个错误需要将vue-loader的版本改为 13.0.0 【前端Vue】05|【前端Vue】05 - [插槽 ,前端模块化开发,webpack]
文章图片
app.js和app.vue的对比 3.13 认识 plugin 为我们的代码添加一个版权声明插件 BannerPlugin
  1. webpack.config.js中配置。
【前端Vue】05|【前端Vue】05 - [插槽 ,前端模块化开发,webpack]
文章图片
配置webpack.config.js 【前端Vue】05|【前端Vue】05 - [插槽 ,前端模块化开发,webpack]
文章图片
最终效果 打包html的plugin html-webpack-plugin【前端Vue】05|【前端Vue】05 - [插槽 ,前端模块化开发,webpack]
文章图片
这个html文件 【前端Vue】05|【前端Vue】05 - [插槽 ,前端模块化开发,webpack]
文章图片
安装完成并配置打包
  1. 安装 html-webpack-plugin插件:
npm install html-webpack-plugin --save-dev

  1. 配置插件并指定打包模板:
【前端Vue】05|【前端Vue】05 - [插槽 ,前端模块化开发,webpack]
文章图片
配置插件并指定打包模板
  1. 可能会出现版本问题 :在package.json中修改版本信息
【前端Vue】05|【前端Vue】05 - [插槽 ,前端模块化开发,webpack]
文章图片
这就是因为版本太高,需要调整版本
"html-webpack-plugin": "^3.0.0"npm install

压缩JS代码 UglifyjsWebpackPlugin
  1. UglifyjsWebpackPlugin , 丑化代码,压缩代码插件。
  1. 安装插件,为开发时插件。
npm install uglifyjs-webpack-plugin@1.1.1 --save-dev

  1. plugins中配置插件 :
【前端Vue】05|【前端Vue】05 - [插槽 ,前端模块化开发,webpack]
文章图片
配置插件 3.14 使用webpack搭建本地服务器
  1. 安装 webpack-dev-server
npm install --save-dev webpack-dev-server@2.9.3

  1. 配置 devServer
【前端Vue】05|【前端Vue】05 - [插槽 ,前端模块化开发,webpack]
文章图片
配置完成
  1. 启动有两种方式: 第一种使用在 package.json中的命令的方式,第二种方式使用node_modules中的命令的方式。
【前端Vue】05|【前端Vue】05 - [插槽 ,前端模块化开发,webpack]
文章图片
在package.json中配置启动webpack-dev-server
// 第一种方式 由于在 package.json中配置了script命令所以可以直接使用如下命令启动 npm run dev

3.15 webpack 中配置文件的抽离
  1. 创建一个build文件夹,在里面创建 base.config.jsprod.config.jsdev.config.js
  2. 将公共的配置都抽取到 base.config.js中。将开发环境的配置配置到 dev.config.js中 ,将生产环境的配置配置到peod.config.js中。
const path = require('path'); const webpack = require('webpack'); const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: './src/main.js', output: { path: path.resolve(__dirname, '../dist'), filename: 'bundle.js', /* 有关url的都会加上dist路径 */ // publicPath: 'dist/' }, module: { rules: [ { test: /\.css$/, /* css-loader 只负责将css文件进行加载 */ /* style-loader 负责将样式添加到DOM中 */ /* loader 从右向左读*/ use: ['style-loader', 'css-loader'] }, { test: /\.less$/, use: [{ loader: "style-loader" // creates style nodes from JS strings }, { loader: "css-loader" // translates CSS into CommonJS }, { loader: "less-loader" // compiles Less to CSS }] }, { test: /\.(png|jpg|gif|jpeg)$/, use: [ { loader: 'url-loader', options: { /* 当图片小于指定的尺寸的时候回将其转换为base64位的图片 */ limit: 10240, name: 'img/[name].[hash:8].[ext]' } } ] }, { test: /\.js$/, /* exclude 是排除的意思 */ /* include 是包含的意思 */ exclude: /(node_modules|bower_components)/, use: { loader: 'babel-loader', options: { presets: ['es2015'] } } }, { test: /\.vue$/, use: { loader: 'vue-loader' } } ] }, resolve: { alias: { 'vue$': 'vue/dist/vue.esm.js' } }, plugins: [ new webpack.BannerPlugin('最终版权归我所有!'), new HtmlWebpackPlugin({ template: 'index.html' }) ] };

  1. 安装合并插件,将他们分别进行合并。
npm install webpack-merge@3.0.0 --save-dev

  1. base.config.jsprod.config.js合并:
const UglifyJsWebpackPlugin = require('uglifyjs-webpack-plugin'); const webpackMerge = require('webpack-merge'); const baseConfig = require('./base.config')/* 合并 基本的配置 + 生产时依赖 */ module.exports = webpackMerge(baseConfig, { plugins: [ new UglifyJsWebpackPlugin() ] });

  1. base.config.jsdev.config.js合并:
const webpackMerge = require('webpack-merge'); const baseConfig = require('./base.config')module.exports = webpackMerge(baseConfig, { devServer: { contentBase: './dist', /* 是否实时进行监听 */ inline: true } })

  1. 合并完成删除webpack.config.js,此时再使用 npm run dev 或者 npm run build 就会出现找不到命令的问题。
  2. 解决合并文件只有删除webpack.config.js再使用 npm run dev 或者 npm run build 脚本命令出现的问题。修改 package.json
【前端Vue】05|【前端Vue】05 - [插槽 ,前端模块化开发,webpack]
文章图片
修改package.json文件

    推荐阅读