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
// 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就可以了。
第二种使用
简单配置,在vue.config.js里面做配置
//vue.config.js const { VantResolver } = require('unplugin-vue-components/resolvers'); const ComponentsPlugin = require('unplugin-vue-components/webpack'); plugins: [ ComponentsPlugin({ resolvers: [VantResolver()], }), ]
(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加一层兜底
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' ...省略 }
脚手架配置还能做一些优化 例如css压缩 js压缩之类的等等,不多做介绍,自己边查边看
data
、methods
和 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>
等等
灵活性变化很大了,具体自己去验证,我只做简单的介绍