Vue3.0环境安装

首先全局安装:npm install @vue/cli -g
然后你可以查看vue的版本
很多人项目其实还在用2.0那不用担心继续安装npm install @vue/cli-init -g
你就可以继续使用vue init webpack mydemo 这种方式创建项目vue-cli2.0的项目
如果你要创建vue3.0的项目使用vue create demo即可

创建项目

vue create demo

 这里有两个选项

Vue3和Vue2默认安装

最后一个是自定义安装

 Vue CLI使用了一套基于插件的架构。你查阅package.json,就会发现都是以@vue/cli-plugin-开头的。插件可以修改webpack内部配置,也可以像vue-cli-service注入命令。

我现在使用第三种手动选择安装配置 Manually select features

安装过程省略,不做介绍。

以下是基本配置

一、首先安装一个静态服务

npm install serve --save-dev

npm install serve --save-dev
"scripts": {
  "server": "serve ./dist -p 5000"
}
在package.json里面配置这个就可以启动你打包后的文件了,打包后的输出文件夹是dist       然后你就可以预览你打包的项目dist文件了
以下是vue.config.js的一些基础配置
// const { defineConfig } = require("@vue/cli-service");
// module.exports = defineConfig({
//   transpileDependencies: true,
  
// });
const version = require("./package.json").version;
const path = require('path');
const webpack = require('webpack');
const TerserPlugin = require('terser-webpack-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const resolve=(pathName) => path.resolve(__dirname,pathName);

module.exports = {
  publicPath: '/',
  outputDir: 'build',
  assetsDir: 'static',
  lintOnSave: true,
  productionSourceMap: false,
  devServer: {
    port: 3000,
    host: 'localhost',
    https: false,
    open: true
  },
  configureWebpack: {
    plugins: [
      new webpack.DefinePlugin({
        __VERSION__: JSON.stringify(version),
        __BUILDDATE__: JSON.stringify(new Date().toLocaleString())
      })
    ],
    resolve:{
      alias:{
        '@': resolve('./src'),
        '@utils': resolve('./src/utils')
      }
    },
    devtool: process.env.NODE_ENV === 'development' ? 'source-map' : 'none'
  },
  chainWebpack: config => {
    config.module.rule('svg').exclude.add(path.resolve('src/assets/svg-icon')).end();
    config.module
      .rule('icons')
      .test(/\.svg$/)
      .include.add(path.resolve('src/assets/svg-icon'))
      .end()
      .use('svg-sprite-loader')
      .loader('svg-sprite-loader')
      .options({
        symbolId: 'icon-[name]',
      })
      .end();
    if(process.env.NODE_ENV === 'production'){
      config.optimization.splitChunks({
        chunks: 'all'
      })
      config.optimization.minimizer = [
        new TerserPlugin({ // webpack5模式无cache & sourceMap配置项,具体参照官方文档
          parallel: true,
        }),
        new CssMinimizerPlugin(),
      ];
    }
  }
}

 然后运行会发现很多eslint报错接下来做eslint基本配置

新建.eslintrc.js和.eslintignore文件

由于package.json里面也做了简单的配置,把里面的删除 ,(eslintConfig这块代码删除)

//.eslint.js
module.exports = {
  root: true,
  env: {
    node: true,
  },
  extends: [
    "plugin:vue/vue3-essential",
    "eslint:recommended",
    "plugin:prettier/recommended",
  ],
  parserOptions: {
    parser: "@babel/eslint-parser",
  },
  rules: {
    //代码风格
    "import/no-cycle": "off",
    "import/no-extraneous-dependencies": "off",
    "import/no-named-as-default-member": "off",
    "operator-linebreak": "off", //强制操作符使用一致的换行符
    "import/order": "off",
    "linebreak-style": "off", //强制使用一致的换行风格
    "no-console": "off", // 禁用 console
    "class-methods-use-this": "off", //强制类方法使用 this
    "max-classes-per-file": "off", // 强制每个文件中包含的的类的最大数量
    "consistent-return": "off", // 要求 return 语句要么总是指定返回的值,要么不指定
    "default-case": "off", // 要求 switch 语句中有 default 分支
    "global-require": "off", // 要求 require() 出现在顶层模块作用域中
    "import/no-dynamic-require": "off",
    "generator-star-spacing": "off", // 强制 generator 函数中 * 号周围使用一致的空格
    "max-len": ["error", { "code": 130 }], //强制一行的最大长度
    // typescript
    "@typescript-eslint/no-var-requires": "off",
    "@typescript-eslint/no-inferrable-types": "off",
    "@typescript-eslint/naming-convention": "off",
    "@typescript-eslint/no-unnecessary-type-assertion": "off",
    "@typescript-eslint/no-unused-vars": "off",
    "@typescript-eslint/no-useless-constructor": "off",
    "@typescript-eslint/no-use-before-define": "off",
    "@typescript-eslint/no-unsafe-assignment": "off",
    "@typescript-eslint/no-unsafe-member-access": "off",
    "@typescript-eslint/no-unsafe-call": "off",
    "@typescript-eslint/no-unsafe-return": "off",
    "@typescript-eslint/restrict-template-expressions": "off",
    "@typescript-eslint/await-thenable": "off",
    "@typescript-eslint/unbound-method": "off",
    "@typescript-eslint/restrict-plus-operands": "off",
    "@typescript-eslint/no-floating-promises": "off",
    "@typescript-eslint/explicit-module-boundary-types": "off",
    "@typescript-eslint/no-explicit-any": "off",
    "@typescript-eslint/ban-types": "off",
    "@typescript-eslint/ban-ts-comment": "off",
    "@typescript-eslint/no-namespace": "off",
    "@typescript-eslint/no-misused-promises": "off",
    "@typescript-eslint/prefer-regexp-exec": "off",
    // javascript
    "func-names": "off", //要求或禁止使用命名的 function 表达式
    "no-bitwise": "off", //禁用按位运算符
    "no-plusplus": "off", // 禁用一元操作符 ++ 和 --
    "prefer-template": "off", //要求使用模板字面量而非字符串连接
    "object-curly-newline": "off", //强制大括号内换行符的一致性
    "no-param-reassign": "off", //禁止对 function 的参数进行重新赋值
    "no-restricted-globals": "off", //禁用特定的全局变量
    "no-underscore-dangle": "off", //禁止标识符中有悬空下划线
    "no-restricted-syntax": "off", //禁用特定的语法
    "no-useless-escape": "off", //禁用不必要的转义字符
    "no-confusing-arrow": "off", //禁止在可能与比较操作符相混淆的地方使用箭头函数
    "no-new": "off", //禁止使用 new 以避免产生副作用
    "no-void": "off", // 禁用 void 操作符
    "prefer-rest-params": "off", //要求使用剩余参数而不是 arguments
    "no-async-promise-executor": "off", //禁止使用异步函数作为 Promise executor
    "no-case-declarations": "off", //    不允许在 case 子句中使用词法声明
    // jsx
    "jsx-a11y/anchor-is-valid": "off",
    "react/jsx-first-prop-new-line": "off",
    "react/jsx-max-props-per-line": "off",
    "react/jsx-one-expression-per-line": "off",
    "react/jsx-props-no-spreading": "off",
    "react/jsx-boolean-value": "off",
    "jsx-a11y/label-has-associated-control": "off",
    "jsx-a11y/click-events-have-key-events": "off",
    "jsx-a11y/no-static-element-interactions": "off",
    "jsx-a11y/no-noninteractive-element-interactions": "off",
    "jsx-a11y/alt-text": "off",
    //react
    "react/jsx-uses-react": "off",
    "react/react-in-jsx-scope": "off",
    "react/display-name": "off",
    "arrow-parens": "off", // 要求箭头函数的参数使用圆括号
    "react/sort-comp": "off",
    "react/no-deprecated": "off",
    "react/button-has-type": "off",
    "react/prop-types": "off",
    "arrow-body-style": "off", //要求箭头函数体使用大括号
    "react/require-default-props": "off",
    "react/no-array-index-key": "off",
    "react/static-property-placement": "off",
    "react/prefer-stateless-function": "off",
    "react/state-in-constructor": "off",
    "no-nested-ternary": "off", // 禁用嵌套的三元表达式
    "react/no-danger": "off",
    'vue/multi-word-component-names': 'off',
    'no-unused-vars': 'off',
    "prettier/prettier": "off"
  },
};

做个代码格式化

.vscode

{
  "editor.formatOnSave": false,
  "editor.formatOnPaste": false,
  "editor.tabSize": 2,
  "editor.insertSpaces": true,
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true,
    "source.fixAll.tslint": true,
    "source.fixAll.stylelint": false
  },
  "eslint.validate": [
    "javascript",
    "javascriptreact",
    "typescript",
    "typescriptreact"
  ],
  "eslint.options": {
    "overrideConfigFile": "./.eslintrc.js"
  },
}

然后装一下ui框架  我这里使用vant

安装引入方式很多,全局的就不说了,按需的有两种
一种是在main.js全部import  然后use就可以了。

第二种使用

 unplugin-vue-components  这个插件实现按需导入,具体参考官方网站

 简单配置,在vue.config.js里面做配置

//vue.config.js
const { VantResolver } = require('unplugin-vue-components/resolvers');
const ComponentsPlugin = require('unplugin-vue-components/webpack');

plugins: [
      ComponentsPlugin({
        resolvers: [VantResolver()],
      }),
]
接下来先做rem设置
在public-》index.html引入一个remSet.js
(function (doc, win) {
  var docEl = doc.documentElement,
    resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
    recalc = function () {
      var clientWidth = docEl.clientWidth;
      if (!clientWidth) return;
      if (clientWidth >= 750) {
        docEl.style.fontSize = '100px';
      } else {
        docEl.style.fontSize = 100 * (clientWidth / 750) + 'px';
      }
    };

  if (!doc.addEventListener) return;
  win.addEventListener(resizeEvt, recalc, false);
  doc.addEventListener('DOMContentLoaded', recalc, false);
})(document, window);

防止有些人就无意识使用px加一层兜底

安装这个postcss-pxtorem  将px转换成rem
然后新建postcss.config.js
module.exports = {
  // https://juejin.cn/post/6901943749916491783
  plugins: [
    require("postcss-pxtorem")({
      rootValue: 100,
      unitPrecision: 5, // 最小精度,小数点位数
      propList: ["*"], // !不匹配属性(这里是字体相关属性不转换)
      selectorBlackList: [],
      minPixelValue: 3, // 替换的最小像素值
    }),
  ],
};

做一下简单配置

然后做一下环境变量配置,指令配置

"dev": "cross-env STAGE=Dev vue-cli-service serve",
在封装接口调用的地方引入initEnv.js文件
switch (process.env.STAGE) {
    case 'Dev':
        global.设置变量例如域名
        global.command= 'DEV'
        break;
    case 'Pro'
      ...省略
}     
 然后做简单的axios封装
这里不介绍方法太多了,全凭个人喜好
请求拦截器和响应拦截器一定要写
再然后就是做路由拦截器
在main.js里面引入一个文件
使用router钩子
router.beforeEach 这里可以做登录验证,或者白名单之类的具体看业务场景
项目基本搭建就结束了
脚手架配置还能做一些优化 例如css压缩 js压缩之类的等等,不多做介绍,自己边查边看
 
要不顺便介绍下vue3.0
vue3.0和vue2变化还是有的,但是他做了包容
vue3.0 api风格有两种 :选项式api和组合api
选项api就是vue2.0里面的写法 例如 datamethods 和 mounted。选项所定义的属性都会暴露在函数内部的 this 上
//官网拷贝的
<script>
export default {
  // data() 返回的属性将会成为响应式的状态
  // 并且暴露在 `this` 上
  data() {
    return {
      count: 0
    }
  },

  // methods 是一些用来更改状态与触发更新的函数
  // 它们可以在模板中作为事件监听器绑定
  methods: {
    increment() {
      this.count++
    }
  },

  // 生命周期钩子会在组件生命周期的各个不同阶段被调用
  // 例如这个函数就会在组件挂载完成后被调用
  mounted() {
    console.log(`The initial count is ${this.count}.`)
  }
}
</script>

<template>
  <button @click="increment">Count is: {{ count }}</button>
</template>

组合api就多了

随便介绍两种

//只是用setup其他保持选项式api
export default{
  setup(){
    const count=ref(0)
    //const {getTableModuleJson,等等} = toRefs(state)
    const increment= ()=>{
       count.value+=1
    }

    return {
      state,
      increment
      //getTableModuleJson 每个都可以return出去
    }
  },
} 

这种只是使用setup来声明响应式数据,这里其实还有一种就是把整个包裹在setup里面,不需要手动return了,是不是更加简单,但是个人感觉有点乱

还有一种类似函数是编程

<script setup>
// 变量
const msg = 'Hello!'

// 函数
const log=()=>{
}
</script>

<template>
  <button @click="log">{{ msg }}</button>
</template>

等等

灵活性变化很大了,具体自己去验证,我只做简单的介绍

posted on 2022-09-22 10:26  执候  阅读(2838)  评论(0编辑  收藏  举报