Vue 折腾记 - (11) @Vue/Cli 3.0.0 图形化项目管理,相当人性化

介绍 Vue CLI 3 的 Web UI 初始化流程,包括项目创建、配置管理和插件更新等功能,提供更好的开发者体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

@vue/cli v3从开始到现在已经经历了四个月的迭代(目前RC3),

除了终端初始化的姿势,还引入了一个新的项目初始化姿势;

Web端的初始化,体验了一下,效果很不错;

后方多图,感兴趣的可以瞧瞧,不感兴趣的请止步,免得浪费你的时间,谢谢..


官网及安装

  • 官网 : Vue Cli

  • 安装:npm i -g @vue/cli


常规命令

大体中文注释下



 Usage: vue <command> [options]

  Options:

    -V, --version                         输出当前脚手架版本
    -h, --help                            使用帮助

  Commands:

    create [options] <app-name>           基于vue-cli-service初始化一个项目,终端 
    add <plugin> [pluginOptions]          添加插件到该项目
    invoke <plugin> [pluginOptions]       在项目中激活(调用)插件
    inspect [options] [paths...]          检查项目中的webpack选项
    serve [options] [entry]               零配置运行开发模式
    build [options] [entry]               零配置运行生产模式
    ui [options]                          web端界面初始化项目
    init [options] <template> <app-name>  类似`vue-cli`初始化远程的模板(需要遵循v3规格的)

  执行 vue <command> --help 获取该选项更详细的帮助.

其他不多说,今天只想演示下Web端UI初始化...


UI初始化

0.终端跑起来!!!

在终端执行vue ui, 会默认初始化localhost:8000且自动打开

7c8e428df06316f4a0ef4f202175a1583858f420

点击顶部tab的Create进入初始化界面, 点击Create a new project here进入新项目初始化

里面的目录都是可以展开的,类似本地目录的体验,会遍历出来展示

8ff85e88184ad591976466671d67af9367fdac62

1.填写目录名什么的

dcf6377c5ffeecb7c60189dc690b674364c48ffd

2.选择配置的细粒度

a8424bb47e5685eb404cbf6eef1df8689d817e9d

3.选择需要开启的东东

9f04c478c7a62e0a0919ca069626f0b3dfc71f4d

4.针对上一步的选择进一步的配置

d3e665e95f86c51bc641fd07a94a79f903147f0e

最后点击Create Project就会开始执行相关的操作和安装对应的依赖了

其实就是终端在执行,只是页面也会给你看一些效果,一个遮罩层loading和一些文字

5.创建完毕会有一个管理后台...相当酷炫..

fd8516b0bf278621662790bb905aee798f383cc0

插件库

这个真的很实用,对于项目的拓展什么的

2f95936bbb40a9fa861b2731724f0d5a48a94a13

开发运行

详细的记录了模块大小,这是把分析插件展示出来了...这样写代码的时候更能感知项目的大小了

670db6e5aed8df13df8cbbc8179cd9619b2a02ee

不仅如此,任务还可以配置访问的域名,是否开启https,对应的开发模式

2c57516a14635ab20523c0cedd1ff378e3bf507a

6. 插件更新直观体验

有些更新会有一个感叹号提示该版本可能不稳定,如图所示

6ce621ea6725df12f35ec6e9c247f46a1a38f698

点击更新后显示一个遮罩层,就是终端在安装;


7. 项目配置的可视化

目前这块我看了下还是不大完善的,需要详细配置的还是需要阅读官方脚手架的文档,写一个vue.config.js,

等会我会稍微点一下,也很容易

985cb86ed1f80697b7e64d929b49021fcfe348b3

vue-cli 3的配置文件引入了一个全局配置文件的概念,在根目录新建一个vue.config.js,

比如我们最常用的接口的反向代理,多线程编译(提升编译速度,只有当内核大于1的时候)

  • vue.config.js


module.exports = {
  devServer: {
    proxy: {
      '/': {
        target: 'xxx'
        changeOrigin: true
        // pathRewrite: {
        //     '^/api': '/'
        // }
      }
    }
  },
  parallel:true,

};

你在项目初始化的还可以选择.babelrc,postcss这类插件文件独立出来,也能集中在package.json

所以说,配置最多分三块,最少是集中化

  1. 独立文件这类,.babelrc,.postcssrc.js
  2. vue.config.js
  3. package.json

更多的配置请查阅官方手册: Vue Cli


书写demo

想知道大概写起来是什么样的么..

我拿了一个下载页面来改了改,可以跑起来大概是这样的

产品的url我就不展示了,统一用xxx

  • AppDownload.vue


<template>
  <div class="page">
    <div class="appicon">
      <img src="../../assets/share/yourAppIcon@2x.png">
      <p>
        <span>真实的
        </span><br>
        <span>才是最精彩的</span>
      </p>
    </div>
    <wechat-browser-check :check-open="checkBrowser" />
    <a
      :href="downloadUrl"
      class="goto-download"
      @click="checkWXPlatform">{{ storeName }}</a>
  </div>
</template>

<script lang="ts">
    import {Component, Vue} from 'vue-property-decorator';

    import WechatBrowserCheck from '@/components/WechatBrowserCheck.vue';

    import service from '@/api/index.ts';

    const device: any = require('current-device').default;


    @Component({
        components: {
            WechatBrowserCheck,
        },
        metaInfo() {
            return {
                title: 'App Download', // set a title
                titleTemplate: '%s -  Welcome!', // title is now "My Example App - Yay!"
                htmlAttrs: {
                    lang: 'zh'
                }
            }
        }
    })
    export default class AppDownload extends Vue {

        private checkBrowser: boolean = false;// 检测浏览器运行 UA
        private downloadUrl: string = ''; // 下载链接
        private storeName: string = 'APP 下载'; // 商店名称
        private country: string = 'CN' // 国家

        created() {
            // 若是 PC 端
            if (device.desktop()) {
                window.location.href = 'xxx';
            }
            this.fetchBasicInfo();
        }

        checkWXPlatform():void {
            this.checkBrowser = true;
        }

        async fetchBasicInfo() {
            try {
                const [
                    country = 'CN',
                    downloadUrl = 'xxx'
                ] = await Promise.all([
                    service
                        .get('/country')
                        .then((res: any) => res.state === 200 && res.data),
                    service
                        .get('/android_v')
                        .then((res: any) => res.state === 200 && res.data.android_apk_url)
                ]);
                this.getMobileApp(country, downloadUrl);
            } catch (error) {
                console.log('网络错误');
            }
        }

        getMobileApp(country: string, downloadUrl: string): void {
            if (device.ios() || device.ipad() || device.iphone()) {
                country === 'CN'
                    ? (this.storeName = 'IOS 下载')
                    : (this.storeName = 'App Store');
                this.downloadUrl =
                    'xxx';
            }

            // 获取下载链接
            if (
                device.android() ||
                device.androidPhone() ||
                device.androidTablet()
            ) {
                this.country === 'CN'
                    ? (this.storeName = 'Android 下载')
                    : (this.storeName = 'Google Play');
                this.downloadUrl = downloadUrl;

            }
        }


    }
</script>

<style scoped lang="scss">
    .page {
      position: relative;
      -webkit-overflow-scrolling: touch;
      height: 100%;
      background: url(../../assets/share/mountainWater.png) no-repeat left top;
      background-size: cover;

      .appicon {
        position: absolute;
        top: 65px;
        left: 56px;

        width: 251px;
        img {
          display: block;

          width: 150px;
          height: 150px;

          border-radius: 22px;
          box-shadow: 0 0 1px rgba(32, 89, 138, 0.31);
        }
        p {
          margin: 35px 0;

          text-align: left;
          letter-spacing: 1px;

          color: #205b8a;

          font-size: 24px;
          font-weight: 600;
          font-stretch: normal;
          line-height: 15px;
          > span {
            display: block;

            padding: 5px 0;

            white-space: nowrap;
          }
        }
      }

      .goto-download {
        position: absolute;
        z-index: 3;
        bottom: 81px;
        left: 50%;

        display: block;

        width: 638px;
        height: 87px;

        transform: translateX(-50%);
        text-align: center;
        text-decoration: none;

        color: #fff;
        border-radius: 100px;
        background: rgba(70, 55, 61, 1);
        box-shadow: #000 0 2px 4px;

        font-size: 32px;
        line-height: 87px;
      }
    }
</style>



  • WechatBrowserCheck.vue


<template>
    <div v-if="showIntro"
         class="intro-layer">
        <div class="desrc">
            <p class="desrc-tips">请点击右上角的选择浏览器打开,谢谢!</p>
        </div>
    </div>
</template>

<script lang="ts">

    import {Component, Emit, Model, Prop, Vue, Watch} from 'vue-property-decorator'

    @Component({})
    export default class WechatBrowserCheck extends Vue {
        private deviceType: string = ''; // 设备类型
        private showIntro: boolean = false;


        @Prop({default: 'wechat'})
        types!: String;

        @Prop({default: false})
        checkOpen!: Boolean;

        @Watch('checkOpen')
        oncheckOpenChanged(val: string, oldVal: string) {
            if (val) {
                this.openAlert();
            }
        }


        openAlert() {
            if (this.checkOpen) {
                if (Array.isArray(this.types)) {
                    this.types.map(item => {
                        if (item === this.deviceEnvCheck()) {
                            this.showIntro = true;
                        }
                        return item;
                    });
                } else {
                    this.deviceEnvCheck() === this.types
                        ? (this.showIntro = true)
                        : (this.showIntro = false);
                }
                console.log('deviceType:' + this.deviceEnvCheck(), 'types:' + this.types);
            }
        }

        deviceEnvCheck() {
            // 检测需要弹窗的设备类型
            // 获取访问的user-agent
            let ua: string = navigator.userAgent.toLowerCase() || window.navigator.userAgent.toLowerCase();

            if (/MicroMessenger/gi.test(ua)) {
                return 'wechat';
            }
            if (/WeiBo/gi.test(ua)) {
                return 'weibo';
            }
            if (/QQ/gi.test(ua)) {
                return 'qq';
            }
            if (/(iPhone|iPad|iPod|iOS)/gi.test(ua)) {
                return 'ios';
            }
        }
    };
</script>

<style lang="scss" scoped>
    .intro-layer {
        position: fixed;
        z-index: 9999;
        top: 0;
        left: 0;

        width: 100%;
        height: 100%;

        background-color: #f2f2f2;
        background-image: url(../assets/share/openbrowser.png);
        background-repeat: no-repeat;
        background-position: center 80px;
        background-size: 100% auto;
        .desrc {
            width: 90%;
            height: auto;
            margin: 10px auto;
            padding: 10px;

            border-radius: 10px;
            background-color: #fff;
            .desrc-tips {
                font-size: 15px;
            }
        }
    }
</style>



编码体验目前来说并不好,周边库还不够完善,需要迭代一段时间才有改善;

目前class书写风格是依赖vue-class-component来实现[装饰器]

一些特性(prop,watch这些)也是依赖一个库vue-property-decorator[装饰器]

jsx结合的也不是很彻底..需要做一些妥协,和react的jsx也有所差异


总结

总体的感觉是很不错的,感觉以后其他的脚手架也会引入这类的WEB UI,大大改善了体验;

不过目前来说,用ts + 装饰器结合Vue的开发体验还不是很好,因为有一些BUG...

JSX的支持,并不完善,和reactjsx也有所差异

目前来说ts+装饰器组合配合最好的是angular, 从ng2开始就引入了,现在都ng6了;

期待Vue及周边库下半年的改进..下个月新脚手架应该就正式版了(最晚不过中秋)



原文发布时间为:2018年06月16日
原文作者:CRPER
本文来源: 掘金  如需转载请联系原作者
run `npm fund` for details fanwei@192 eam % npm install @vue/cli-service@latest --save-dev npm WARN ERESOLVE overriding peer dependency npm WARN While resolving: eam@1.0.5 npm WARN Found: @vue/cli-service@4.5.19 npm WARN node_modules/@vue/cli-service npm WARN peer @vue/cli-service@"^3.0.0 || ^4.0.0-0" from @vue/cli-plugin-babel@4.5.19 npm WARN node_modules/@vue/cli-plugin-babel npm WARN dev @vue/cli-plugin-babel@"~4.5.0" from the root project npm WARN 3 more (@vue/cli-plugin-router, @vue/cli-plugin-vuex, the root project) npm WARN npm WARN Could not resolve dependency: npm WARN peer @vue/cli-service@"^3.0.0 || ^4.0.0-0" from @vue/cli-plugin-babel@4.5.19 npm WARN node_modules/@vue/cli-plugin-babel npm WARN dev @vue/cli-plugin-babel@"~4.5.0" from the root project npm WARN ERESOLVE overriding peer dependency npm WARN While resolving: eam@1.0.5 npm WARN Found: @vue/cli-service@4.5.19 npm WARN node_modules/@vue/cli-service npm WARN peer @vue/cli-service@"^3.0.0 || ^4.0.0-0" from @vue/cli-plugin-babel@4.5.19 npm WARN node_modules/@vue/cli-plugin-babel npm WARN dev @vue/cli-plugin-babel@"~4.5.0" from the root project npm WARN 3 more (@vue/cli-plugin-router, @vue/cli-plugin-vuex, the root project) npm WARN npm WARN Could not resolve dependency: npm WARN peer @vue/cli-service@"^3.0.0 || ^4.0.0-0" from @vue/cli-plugin-router@4.5.19 npm WARN node_modules/@vue/cli-plugin-router npm WARN @vue/cli-plugin-router@"^4.5.19" from @vue/cli-service@4.5.19 npm WARN 1 more (the root project) npm WARN ERESOLVE overriding peer dependency npm WARN While resolving: eam@1.0.5 npm WARN Found: @vue/cli-service@4.5.19 npm WARN node_modules/@vue/cli-service npm WARN peer @vue/cli-service@"^3.0.0 || ^4.0.0-0" from @vue/cli-plugin-babel@4.5.19 npm WARN node_modules/@vue/cli-plugin-babel npm WARN dev @vue/cli-plugin-babel@"~4.5.0" from the root project npm WARN 3 more (@vue/cli-plugin-router, @vue/cli-plugin-vuex, the root project) npm WARN npm WARN Could not
03-31
npm ERR! code ERESOLVE npm ERR! ERESOLVE could not resolve npm ERR! npm ERR! While resolving: @vue/cli-plugin-vuex@4.4.6 npm ERR! Found: @vue/cli-service@5.0.8 npm ERR! node_modules/@vue/cli-service npm ERR! dev @vue/cli-service@"^5.0.8" from the root project npm ERR! peer @vue/cli-service@"^3.0.0 || ^4.0.0 || ^5.0.0-0" from @vue/cli-plugin-babel@5.0.8 npm ERR! node_modules/@vue/cli-plugin-babel npm ERR! dev @vue/cli-plugin-babel@"^5.0.8" from the root project npm ERR! 3 more (@vue/cli-plugin-pwa, @vue/cli-plugin-router, @vue/cli-plugin-vuex) npm ERR! npm ERR! Could not resolve dependency: npm ERR! peer @vue/cli-service@"^3.0.0 || ^4.0.0-0" from @vue/cli-plugin-vuex@4.4.6 npm ERR! node_modules/@vue/cli-plugin-vuex npm ERR! dev @vue/cli-plugin-vuex@"~4.4.0" from the root project npm ERR! npm ERR! Conflicting peer dependency: @vue/cli-service@4.5.19 npm ERR! node_modules/@vue/cli-service npm ERR! peer @vue/cli-service@"^3.0.0 || ^4.0.0-0" from @vue/cli-plugin-vuex@4.4.6 npm ERR! node_modules/@vue/cli-plugin-vuex npm ERR! dev @vue/cli-plugin-vuex@"~4.4.0" from the root project npm ERR! npm ERR! Fix the upstream dependency conflict, or retry npm ERR! this command with --force or --legacy-peer-deps npm ERR! to accept an incorrect (and potentially broken) dependency resolution. npm ERR! npm ERR! npm ERR! For a full report see: npm ERR! C:\Users\35514\AppData\Local\npm-cache\_logs\2023-06-08T07_30_06_817Z-eresolve-report.txt npm ERR! A complete log of this run can be found in: npm ERR! C:\Users\35514\AppData\Local\npm-cache\_logs\2023-06-08T07_30_06_817Z-debug-0.log
06-09
npm ls loader-utils less-loader webpack webpack-cli my-project1@0.1.0 D:\svw3\mbv-vw-applet +-- @dcloudio/uni-quickapp-native@2.0.0-alpha-33020211130001 | +-- @hap-toolkit/dsl-vue@0.6.13 | | +-- @hap-toolkit/compiler@0.6.15 | | | +-- loader-utils@1.4.0 deduped | | | `-- webpack@4.47.0 deduped | | +-- css-loader@2.1.1 | | | `-- loader-utils@1.4.0 deduped | | `-- mini-css-extract-plugin@0.5.0 | | `-- loader-utils@1.4.0 deduped | `-- @hap-toolkit/packager@0.6.13 | +-- loader-utils@1.4.0 deduped | `-- webpack@4.47.0 deduped +-- @dcloudio/vue-cli-plugin-uni@2.0.0-alpha-33020211130001 | +-- copy-webpack-plugin@5.1.2 | | `-- loader-utils@1.4.0 deduped | +-- loader-utils@1.4.0 deduped | `-- wrap-loader@0.2.0 | `-- loader-utils@1.4.0 deduped +-- @vue/cli-plugin-babel@4.5.19 | +-- babel-loader@8.4.1 | | `-- loader-utils@2.0.4 | +-- cache-loader@4.1.0 | | `-- loader-utils@1.4.0 deduped | +-- thread-loader@2.1.3 | | `-- loader-utils@1.4.0 deduped | `-- webpack@4.47.0 deduped +-- @vue/cli-plugin-typescript@5.0.8 | +-- thread-loader@3.0.4 | | `-- loader-utils@2.0.4 | `-- webpack@5.99.9 +-- @vue/cli-service@4.5.19 | +-- css-loader@3.6.0 | | `-- loader-utils@1.4.0 deduped | +-- file-loader@4.3.0 | | `-- loader-utils@1.4.0 deduped | +-- html-webpack-plugin@3.2.0 | | `-- loader-utils@0.2.17 | +-- mini-css-extract-plugin@0.9.0 | | `-- loader-utils@1.4.0 deduped | +-- url-loader@2.3.0 | | `-- loader-utils@1.4.0 deduped | +-- vue-loader@15.11.1 | | `-- loader-utils@1.4.0 deduped | +-- vue-loader-v16@npm:vue-loader@16.8.3 | | `-- loader-utils@2.0.4 | +-- vue-style-loader@4.1.3 | | `-- loader-utils@1.4.0 deduped | `-- webpack@4.47.0 deduped +-- file-loader@6.2.0 | `-- loader-utils@2.0.4 +-- loader-utils@1.4.0 +-- mini-css-extract-plugin@1.6.2 | `-- loader-utils@2.0.4 +-- postcss-loader@3.0.0 | `-- loader-utils@1.4.0 deduped +-- sass-loader@8.0.2 | `-- loader-utils@1.4.0 deduped +-- style-loader@1.3.0 | `-- loader-utils@2.0.4 +-- ts-loader@8.2.0 | `-- loader-utils@2.0.4 +-- webpack@4.47.0 | `-- loader-utils@1.4.0 deduped `-- webpack-cli@3.3.12 `-- loader-utils@1.4.0 deduped
最新发布
06-28
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值