Vue学习 第八篇 vue cli

一、vue cli

  
  我们使用vue开发项目,我们要书写webpack配置,创建项目,创建文件等需要时间,为了做性能优化,需要大量的配置等等,在开发项目前,要准备大量的工作内容

  vue为了简化这一开发方式,提供了vue-cli脚手架。

安装
    通过npm安装vue-cli: npm install -g @vue/cli

  此时提供了vue指令,输入vue -v可以查看版本号

创建项目

    执行‘vue create 项目名称’指令就可以创建项目

    创建过程中,可以输入一些选项。

二、目录部署

  node_modules 依赖的模块

  public 静态资源

     index.html 入口文件
     manifest.json 离线缓存配置
     favicon.ico 网页logo
     robots.txt 爬虫配置
     img 图片资源目录

  src 开发目录

    assets 静态资源
    components 页面间共享的组件
    views 页面组件
    App.vue 应用程序组件
    router.js 路由文件
    store.js vuex文件
    main.js 入口文件
    registerServiceWorker.js web workers文件

  test 单元测试目录

    .browserslistrc 浏览器配置
    .eslintrc es语法校验
    .gitnore 提交配置

  babel.config.js babel配置

  jest.config.js 单元测试配置

  package.json npm包配置

  postcss.config.js css配置

  readme.rd 项目介绍文件

  yarn.lock yarn锁文件

三、指令

ts开发
  我们创建项目的时候,可以选择ts语法或者es6语法,

  选择ES6会使用.js文件

  选择ts会使用.ts文件

指令
  serve 启动项目,默认端口号是8080

  build 发布项目,默认向dist目录下发布

  test:unit 启动单元测试

我们既可以使用yarn指令运行,也可以使用npm run指令运行。

四、配置

  插件webpack配置,用inspect指令:vue inspect > 文件路径

我们可在vue.config.js中。自定义配置

  在配置文件中,有两个环境,

    一个是开发环境,执行yarn serve时候的环境

    一个是发布环境,执行yarn build时候的环境

  我们通过process.env.NODE_ENV来识别环境:

    development表示开发环境

    production表示发布环境

在vue.config.js文件中。我们要分别为开发环境和发布环境定义配置

我们可以定义两类配置

  一类是webpack语法配置

      在configureWebpack中配置

  一类是vue cli自身的语法配置

      outputDir 静态资源发布位置

      indexPath 模板发布位置

      publicPath 模板中引入的静态资源相对位置

五、PWA

是一个渐进式的web应用,介于web应用与源生应用之间的一类应用、

  可以像web应用一样开发。

  可以具有源生应用的一些功能,

其中以下文件就是为了实现这些功能的。

  manifest.json 离线缓存配置

  registerServiceWorker.js web workers文件

六、单元测试

  测试就是描述一段话,判断是否正确(断言)。基于文件或者模块(组件)的测试,我们称之为单元测试。

6.1 单元测试

在vue cli中,我们使用的是jest框架。测试结果有两种

  一种是测试成功,所有的单元测试都成功。

  一种是测试失败,有一个测试是失败的。

  启动测试:yarn test:unit npm run test:unit

测试文件:在单元测试中,有三类文件可以被测试

  1 放在test目录中的文件

  2 文件的名添加.test.后缀的文件

  3 文件的名添加.spec.后缀的文件

命名规范:通常与被测试的文件同名

6.2 测试方法

describe 测试整体描述

  第一个参数表示描述

  第二个参数是函数,表示测试内容

it 一次测试的描述

  第一个参数表示描述

  第二个参数是函数,表示本次测试的内容

expect 断言方法

  参数就是描述

  我们要对返回值做判断(断言)

6.3 断言方法

常见的断言方法有:
  toBe 表示===
  toEqual 字面量形式是否相等
  toMatch 是否正则匹配
  toContain 是否包含
  toBeTruthy 是否为真
  toBefalsy 是否为假
   …

6.4 周期方法

  beforeEach 每一个it语句执行前
  afterEach 每一个it语句执行后
  beforeAll 所有的it语句执行前
  afterAll 所有的it语句执行后

只对当前文件的it语句生效,其它文件无效。

6.5 测试 store

  由于store中有包含修改数据的逻辑(mutations以及action中),因此要对它们进行测试。

  此时store的这些组成部分要单独定义出来,这样才能测试。

6.6 测试组件

  我们在vue文件中,定义的组件只是Vue.extend方法的参数对象。因此我们不能直接使用,要转成实例化对象再使用,有两种方式

  第一种:new Vue(obj)返回的是vue实例化对象
  第二种: 通过组件类的方式

      第一步 let Comp = Vue.extend(obj);

      第二步 实例化 new Comp()

  不论是哪一种方式,都可以得到组件,但是组件没有上树,无法获取$el容器元素。

  为了获取$el容器元素,我们要使用 $mount 方法。

$nextTick

  会检测视图的更新,更新完毕,执行回调函数。

  该方法实现了Promise规范。

  所以我们可以通过then方法监听结果。

shallowMount

  vue cli为了方便我们测试组件,提供了一个 shallowMount 方法。

  该方法可以将组件实例化,并且执行$mount方法上树。

  我们通过该方法,我们就可以得到一个组件实例化对象。

    第一个参数是组件对象

    第二个参数是配置对象(propsData: 传递给组件的属性数据)

  提供了text方法,可以获取其视图中的内容。

注意:使用单元测试,去测试视图等很麻烦,效率低,因此工作中慎用。我们用单元测试,去测试一些业务逻辑收益还是很大的。

七、实现 Vue cli

我们基于webpack来实现一个vue cli的功能

实现vue cli的目录部署

实现一些性能优化的功能。

  静态资源压缩,打包,添加指纹等等。

资源发布

  将静态资源发布到外面的dzx/static目录中

  将模板资源发布到外面的dzx/views/index.html文件中

发布模板
  发布html文件用html-webpack-plugin插件

    template 定义模板文件位置

    filename 模板文件发布位置

    hash 是否添加指纹(添加在query上)

    inject 是否注入静态资源(默认是注入的)

压缩资源
    压缩js,压缩html,压缩css

拆分文件

  将模块文件打包在一起:main.js

  将样式文件打包在一起: style.css

    我们使用mini-css-extract-plugin插件

      vue组件中样式拆分: extractCSS: true

      css和scss|less样式拆分,使用该插件加载机

       我们通过插件的filename属性定义文件发布位置。

    对资源添加指纹:css资源,js资源等

      压缩css使用optimize-css-assets-webpack-plugin插件

      压缩js: mode: ‘production’

拆分库文件
  将库文件打包在一起:lib.js
    optimization: {
      splitChunks: { 拆分文件
        cacheGroup: { 公用缓存分组
               lib: {
                name: 库文件名称
                chunks ‘initial’,
                test: 库文件特征
                 }
               }
            }
           }

目录显示

在这里插入图片描述
webpack.config.js

// 引入 path
let path = require('path');
// 引入 vue插件-loader
const { VueLoaderPlugin } = require('vue-loader');

// 引入 html 插件
let HtmlWebpackPlugin = require('html-webpack-plugin');

// 拆分 css
let MiniCssExtractPlugin = require('mini-css-extract-plugin');

// 压缩 css
let OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')

// 引入 根目录
const root = process.cwd();
// 定义配置
module.exports = {
    // 模式 
    // 发布模式
    mode: 'production',

    // 解决问题
    resolve: {
        // 定义别名
        alias: {
            vue$: 'vue/dist/vue.js',
            '@': path.join(root, './src'),
            '@v': path.join(root, './src/views'),
            '@c': path.join(root, './src/compoments'),
        },
        // 拓展名
        extensions: ['.js', '.vue'],
    },
    // 入口
    entry: './src/main.js',

    // 发布
    output: {
        // "文件名"  
        // 第一种添加 hash 指纹的方式
        // filename:'./static/[name].[hash:8].js',
        // 第二种方式 在 插件中添加
        filename: './static/[name].js',
        // 发布位置
        path: path.join(root, './dzx/'),

        // 修改静态文件的相对位置  
        publicPath: '../'
    },

    // 模块
    module: {
        // 加载机
        rules: [
            // vue
            {
                test: /\.vue$/,
                loader: 'vue-loader',
                // 在以前的版本中,打包 css 还需要传递配置
                // use:[
                //     {
                //         loader:'vue-loader',
                //         options:{
                //             extractCSS:true
                //         }
                //     }
                // ]

            },
            // css
            {
                test: /\.css$/,
                use: [
                    "style-loader",
                    // 在样式文件的 style-loader 后天添加 loader
                    MiniCssExtractPlugin.loader,
                    "css-loader"
                ]
            },
            // less 
            {
                test: /\.less$/,
                use: [
                    "style-loader",
                    // 在样式文件的 style-loader 后天添加 loader
                    MiniCssExtractPlugin.loader,
                    "css-loader",
                    "less-loader"
                ]
            },
            // scss
            {
                test: /\.scss$/,
                use: [
                    "style-loader",
                    //  在样式文件的 style-loader 后天添加 loader
                    MiniCssExtractPlugin.loader,
                    "css-loader",
                    "sass-loader"
                ]
            }
        ]
    },
    // vue 插件
    plugins: [
        // 使用 vue-loader
        new VueLoaderPlugin(),
        // 处理模板
        new HtmlWebpackPlugin({
            // 模板位置
            template: './public/index.html',
            // 发布位置
            filename: './views/index.html',
            // 添加指纹
            hash: true
        }),
        // 2 定义文件的发布位置
        new MiniCssExtractPlugin({
            filename: './static/style.css'
        }),
        // 压缩 css 
        new OptimizeCssAssetsWebpackPlugin()
    ],
    // 优化
    optimization: {
        // 拆分文件
        splitChunks: {
            cacheGroups: {
                lib: {
                    name: 'lib',
                    chunks: 'initial',
                    test: /node_modules/
                }
            }
        }
    }
}

public/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app"></div>
    
</body>
</html>

src/App.vue

<template>
    <div id="app">
        <h1>app  page</h1>
        <router-link to="/">home</router-link>
        <router-link to="/list/1">list</router-link>
        <router-link to="/detail/2">detail</router-link>
        <br>
        <router-view></router-view>
    </div>
</template>

src/demo.less


@color:pink;
h1{
    color: @color;
}

src/main.js



import Vue from 'vue';
import App from './App';
import store from './store';
import router from './router';

import './demo.less';


new Vue({
    // 订阅
    store,
    // 安装路由 
    router,
    // 渲染应用程序
    render: h => h(App)
}).$mount("#app")

src/router.js


import Vue from 'vue';

import Router from 'vue-router';

// 引入首页
import Home from '@v/Home';


// 安装
Vue.use(Router);

// 实例化
export default new Router({
    routes: [
        // 列表页
        { path: '/list/:page', component: () => import('@v/List') },
        // 详情页
        { path: '/detail/:id', component: () => import('@v/Detail') },
        // 默认页面
        { path: '*', component: Home }
    ]
})

src/store.js


import Vue  from 'vue';

import Vuex,{ Store } from 'vuex';

// 安装
Vue.use(Vuex);

// 实例化
export default new Store({
    state:{
        num:0
    },
    mutations:{

    },
    actions:{
        
    }
})

src/views/Home.vue

<template>
    <div>
        <h1>Home  page --- {{$store.state.num}} --- {{msg}}</h1>
    </div>
</template>

<style lang="less" scoped>
@color:blue;
h1{
    color:@color,
}
</style>


<script>
export default{
    data(){
        return{
            msg:"dazhaxie"
        }
    }
}
</script>

src/views/List.vue

<template>
    <div>
        <h1>List  page</h1>
    </div>
</template>

src/views/Detail.vue

<template>
    <div>
        <h1>Detail  page</h1>
    </div>
</template>

注意 运行时 运行 发布 文件中的 html 例如 dzx/views/index.html

效果图

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大闸蟹~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值