安装
yarn create nuxt-app <项目名>
它会让你进行一些选择:
- 项目名称
- 选择语言 TS/JS
- 选择包管理器 Yarn/Npm
- 选择UI框架
选择nuxtjs模块
选择lint工具
- 选择测试框架
- 渲染模式
- 部署方式
静态部署:全部路径被打包出 index.html a.html b.html 等文件,而实际访问,服务器就把这些文件服务出去,属于是文件服务。
服务端渲染部署:请求会经过 Node.js express/koa等框架 的 render ,如果你想,它会动态改变,因为是拼接的。
- 部署工具
- 持续集成
- 版本控制系统
当运行完时,它将安装所有依赖项,因此下一步是启动项目
cd <project-name>
yarn dev
目录结构
Nuxt.js 的默认应用目录架构提供了良好的代码分层结构,适用于开发或大或小的应用。当然,你也可以根据自己的偏好组织应用代码。
assets 资源目录
资源目录 assets
用于组织未编译的静态资源如 LESS
、SASS
或 JavaScript
。
static 静态文件目录
静态文件目录 static
用于存放应用的静态文件,此类文件不会被 Nuxt.js 调用 Webpack 进行构建编译处理。服务器启动的时候,该目录下的文件会映射至应用的根路径 /
下。
举个例子: /static/robots.txt
映射至 /robots.txt
若无额外配置,该目录不能被重命名。
components
组件目录
组件目录 components
用于组织应用的 Vue.js 组件。Nuxt.js 不会扩展增强该目录下 Vue.js 组件,即这些组件不会像页面组件那样有 asyncData
方法的特性。
layouts
布局目录
布局目录 layouts
用于组织应用的布局组件。
若无额外配置,该目录不能被重命名。
pages
页面目录
页面目录 pages
用于组织应用的路由及视图。Nuxt.js 框架读取该目录下所有的 .vue
文件并自动生成对应的路由配置。
若无额外配置,该目录不能被重命名。
middleware
中间件目录
plugins
插件目录
插件目录 plugins
用于组织那些需要在 根 vue.js 应用
实例化之前需要运行的 Javascript 插件。
Store 目录
store
目录用于组织应用的 Vuex 状态树 文件。 Nuxt.js 框架集成了 Vuex 状态树 的相关功能配置,在 store
目录下创建一个 index.js
文件可激活这些配置。
若无额外配置,该目录不能被重命名。
nuxt.config.js 文件
nuxt.config.js
文件用于组织 Nuxt.js 应用的个性化配置,以便覆盖默认配置。
若无额外配置,该文件不能被重命名。
package.json 文件
package.json
文件用于描述应用的依赖关系和对外暴露的脚本接口。
该文件不能被重命名。
路径别名
别名 | 目录 |
---|---|
~ 或 @ |
srcDir |
~~ 或 @@ |
rootDir |
默认情况下,srcDir
和 rootDir
相同。
提示: 在您的 vue
模板中, 如果你需要引入 assets
或者 static
目录, 使用 ~/assets/your_image.png
和 ~/static/your_image.png
方式。
项目基础依赖配置
git cz
git cz 相当于是一个对于 git commit 的提交命令的规范化工具,使 git commit 提交规范化。
直接写commit 命令,feat、fix 等提交类型有可能写错导致提交不规范
git commit -m 'feat: add list '
- feat:新功能(feature)
- fix:修补bug
- docs:文档(documentation)只是文档的更改
- style: 格式(不影响代码运行的变动,例如空格、格式化、少了分号等等)
- refactor:重构(即不是新增功能,也不是修改bug的代码变动)
- test:增加测试
- chore:构建过程或辅助工具的变动
- perf:提高性能的代码提交
- revert: 撤回提交
- test:添加或修正测试
git cz 工具可以直接选择提交类型,不容易出错
git cz
cz-cli@4.2.3, cz-conventional-changelog@3.3.0
#指定commit的类型,约定了feat、fix两个主要type,以及docs、style、build、refactor、revert五个特殊type
? **Select the type of change that you're committing:** fix: A bug fix
#用于描述改动的范围,格式为项目名/模块名
? **What is the scope of this change (e.g. component or file name): (press enter t**
**o skip)** index.html
#对改动进行简短的描述
? **Write a short, imperative tense description of the change (max 83 chars):**
(11) add a blank
#对改动进行长的描述
? **Provide a longer description of the change: (press enter to skip)**
#是破坏性的改动吗
? **Are there any breaking changes?** No
#影响了哪个issue吗,如果选是,接下来要输入issue号
? **Does this change affect any open issues?** No
yarn add cz-conventional-changelog@3.3.0 -D
安装完之后在 package.json 添加如下命令:
"config": {
"commitizen": {
"path": "./node_modules/cz-conventional-changelog"
}
}
tsconfig.js
{
"compilerOptions": {
"target": "ES2018",
"module": "ESNext",
"moduleResolution": "Node",
"jsx": "preserve",
"noImplicitAny": false,
"lib": ["ESNext", "ESNext.AsyncIterable", "DOM"],
"esModuleInterop": true,
"allowJs": true,
"sourceMap": true,
"strict": true,
"noEmit": true,
"experimentalDecorators": true,
"baseUrl": ".",
"paths": {
"~/*": ["./*"],
"@/*": ["./*"]
},
"types": ["@nuxt/types", "@nuxtjs/axios", "@nuxt/content", "@types/node"]
},
"exclude": ["node_modules", ".nuxt", "dist"]
}
Eslint 校验 js 代码
安装 eslint-plugin-prettier
yarn add eslint-plugin-prettier --dev
.eslintrc.js
module.exports = {
root: true,
env: {
browser: true,
node: true
},
parserOptions: {
ecmaVersion: 2020
},
extends: [
'@nuxtjs/eslint-config-typescript',
'plugin:nuxt/recommended',
'plugin:prettier/recommended'
],
plugins: [],
// add your custom rules here
rules: {}
}
Stylelint 校验 css 代码
Tutorial.vue 尝试加入css,stylelint检测正常
项目使用less预处理器,stylelint检测失效
yarn add -D postcss-less
stylelint.config.js 中注释或者移除一下代码
// customSyntax: 'postcss-html',
否则less文件vscode不会报错
安装 stylelint-order
yarn add stylelint-order --dev
module.exports = {
customSyntax: "postcss-html",
extends: [
"stylelint-config-standard",
"stylelint-config-recommended-vue",
// "stylelint-config-prettier",
],
plugins: ["stylelint-order"],
// add your custom config here
// https://stylelint.io/user-guide/configuration
rules: {},
};
添加自定义规则
rules: {
'at-rule-no-unknown': null,
'font-family-no-missing-generic-family-keyword': null,
'declaration-block-trailing-semicolon': null,
'selector-pseudo-element-colon-notation': null,
'font-family-name-quotes': null,
'declaration-colon-newline-after': null,
'string-quotes': 'single',
'property-no-vendor-prefix': null
}
Prettier 格式化代码
修改.prettierrc
{
"printWidth": 100, // 超过最大值换行
"tabWidth": 2, // 缩进字节数
"useTabs": false, // 缩进不使用tab,使用空格
"semi": false, // 末尾不加尾号
"singleQuote": true, // 默认单引号
"quoteProps": "as-needed", // 仅在需要时在对象属性添加引号
"jsxSingleQuote": false, // 在jsx中使用单引号代替双引号
"trailingComma": "none", // es5对象属性最后加逗号。none不加
"bracketSpacing": true, // 在对象,数组括号与文字之间加空格
"jsxBracketSameLine": false, // 在jsx中把'>' 是否单独放一行
"arrowParens": "always", // 箭头函数参数只有一个时是否要有小括号
"htmlWhitespaceSensitivity": "ignore", // HTML空白灵敏度,空格被认为是不敏感的
"vueIndentScriptAndStyle": false, // script、style标签不缩进
"endOfLine": "auto",
// 覆写默认配置,为某些特定文件制定特定配置
"overrides": [
{
"files": "*.json",
"options": {
"printWidth": 200
}
}
]
}
.prettierrc 中设置的单引号等规则未生效,编辑器报错
需要去掉配置后的说明注释
{
"printWidth": 100,
"tabWidth": 2,
"useTabs": false,
"semi": false,
"singleQuote": true,
"quoteProps": "as-needed",
"jsxSingleQuote": false,
"trailingComma": "none",
"bracketSpacing": true,
"jsxBracketSameLine": false,
"arrowParens": "always",
"htmlWhitespaceSensitivity": "ignore",
"vueIndentScriptAndStyle": false,
"endOfLine": "auto",
"overrides": [
{
"files": "*.json",
"options": {
"printWidth": 200
}
}
]
}
配置生效,保存时自动格式化
git 提交时 eslint、prettier、stylelint、tsconfig配置修改时,发现未通过 commitlint 工具的校验
yarn lintfix
less 预处理器
安装指定版本,不带版本号默认安装最新版,可能会出错
yarn add less@3.0.4 less-loader@5.0.0 -D
package.json
3
引入全局 less 样式
css: [
'element-ui/lib/theme-chalk/index.css',
'@/assets/styles/global.less',
],
这个时候全局样式已经生效,在组件内也可以使用 less
<style lang="less" scoped>
@prefix-cls: ~'basic-footer';
.@{prefix-cls}__qrcode {
width: 5.8rem;
height: 5.8rem;
}
<style>
但是使用全局less文件中声明的 less 变量还是报错
nuxtjs 可以使用 style-resources 自动化导入文件(用于颜色、变量、mixin……)
yarn add @nuxtjs/style-resources --dev
buildModules: [
'@nuxtjs/style-resources',
],
styleResources: {
less: './assets/global.less'
}
注意:styleResources 配置的资源路径不能使用 ~ 和 @,要使用绝对或者相对路径
组件中使用
p.@{prefix-cls}__company-name {
color: @text-color-inverse;
opacity: 1;
}
pwa
nuxt.config.js 中添加以下配置
pwa: {
manifest: {
name: '关河智图',
short_name: '关河智图',
lang: 'zh-CN'
},
icon: { cacheDir: '/icon.png' },
workbox: {
config: { modulePathPrefix: '/workbox-5.1.4' }
}
},
modules: ["@nuxtjs/pwa"]
在静态static目录中添加icon.png图片文件(512 X 512)
Element UI按需引入
Element-UI 开启按需引入,必须安装 babel-plugin-component 插件
yarn add babel-plugin-component --dev
安装完成后,在文件根目录创建(或已经存在) plugins/ 目录下创建相应的插件文件,创建名为:element-ui.js 的文件
import Vue from 'vue'
import locale from 'element-ui/lib/locale/lang/zh-CN'
import {
Icon,
Container,
Header,
Aside,
Main,
Menu,
MenuItem,
Button,
Form,
FormItem,
Input,
Row,
Col,
Carousel,
CarouselItem,
Popover
} from 'element-ui'
const Element = {
install(Vue) {
;[
Icon,
Container,
Header,
Aside,
Main,
Menu,
MenuItem,
Button,
Form,
FormItem,
Input,
Row,
Col,
Carousel,
CarouselItem,
Popover
].forEach((component) => Vue.component(component.name, component))
}
}
Vue.use(Element, { locale })
- 在 nuxt.config.js 文件中,配置 plugins 选项。
plugins: ["@/plugins/element-ui"],
如果在 create-nuxt-app 中默认选了 Element-UI 的,还需要将 Element-UI 的全局样式去掉,即在 nuxt.config.js 中:
// css: ['element-ui/lib/theme-chalk/index.css'],
// 改为
css: [],
在 nuxt.config.js 文件中,在选项 build 中配置 babel 选项:
build: {
babel: {
plugins: [
[
'component',
{
libraryName: 'element-ui',
styleLibraryName: 'theme-chalk'
}
]
]
}
}
到此,Element-UI 按需引入配置完成。
vue-in8n 多语言
export default function ({ isHMR, app, store, route, params, error, redirect }) {
const defaultLocale = app.i18n.fallbackLocale
// If middleware is called from hot module replacement, ignore it
if (isHMR) { return }
// Get locale from params
const locale = params.lang || defaultLocale
if (!store.state.locales.includes(locale)) {
return error({ message: 'This page could not be found.', statusCode: 404 })
}
// Set locale
store.commit('SET_LANG', locale)
app.i18n.locale = store.state.locale
// If route is /<defaultLocale>/... -> redirect to /...
if (locale === defaultLocale && route.fullPath.indexOf('/' + defaultLocale) === 0) {
const toReplace = '^/' + defaultLocale + (route.fullPath.indexOf('/' + defaultLocale + '/') === 0 ? '/' : '')
const re = new RegExp(toReplace)
return redirect(
route.fullPath.replace(re, '/')
)
}
}
import Vue from 'vue'
import VueI18n from 'vue-i18n'
Vue.use(VueI18n)
export default ({ app, store }) => {
// Set i18n instance on app
// This way we can use it in middleware and pages asyncData/fetch
app.i18n = new VueI18n({
locale: store.state.locale,
fallbackLocale: 'zh-CN',
messages: {
'en-US': require('@/locales/en-US.json'),
'zh-CN': require('@/locales/zh-CN.json')
}
})
app.i18n.path = (link) => {
if (app.i18n.locale === app.i18n.fallbackLocale) {
return `/${link}`
}
return `/${app.i18n.locale}/${link}`
}
}
export const state = () => ({
locales: ['en-US', 'zh-CN'],
locale: 'zh-CN'
})
export const mutations = {
SET_LANG(state, locale) {
if (state.locales.includes(locale)) {
state.locale = locale
}
}
}
locales下创建翻译文件
{
"links": {
"home": "Home",
"about": "About",
"english": "English version",
"french": "French version"
},
"home": {
"title": "Welcome",
"introduction": "This is an introduction in English."
},
"about": {
"title": "About",
"introduction": "This page is made to give you more informations."
}
}
export default {
router: {
middleware: ['i18n']
},
plugins: ['~/plugins/i18n.js'],
generate: {
routes: ['/', '/about', '/zh-CN', '/zh-CN/about'],
fallback: true
}
}
修改 dev 端口
修改 package.json文件的scripts节点下的”dev”,在nuxt 后面加上 —port 9001,
"scripts": {
"dev": "nuxt --port 9001",
"build": "nuxt build",
"start": "nuxt start --port 9001",
"generate": "nuxt generate"
},
或者直接在package.json里面去加一段(这种方式还可以通过ip访问)
"config": {
"nuxt": {
"host": "0.0.0.0",
"port": "3333" //你就写与冲突的端口号不同的就行
}
}