如何使用Nuxt + tsx 编写页面(创建并配置项目)

2,791 阅读3分钟

读懂本文,您可能要熟悉 Nuxt的项目结构,熟悉tsx,了解css module的作用

Nuxt就是VueSSR(Server-Side-Render)版本,使用SSR的方式就是首屏渲染,其他的与SPA(Single-Page-Application)不一样的就是,ssr自带服务,如果你熟悉Java可以类比spring-boot,默认带一个tomcat,但是也可以换成jetty一样,nuxt默认使用的是自己的服务,但是也可以选择其他服务,具体的可以在创建的时候呈现出来

创建项目服务

推荐官方使用的是 npx create-nuxt-app 的方式创建
* ? Project name `app`
* ? Project description `My stylish Nuxt.js project`
* ? Author name `...`
* ? Choose programming language `TypeScript`
* ? Choose the package manager `Npm`
* ? Choose UI framework `None`
* ? Choose custom server framework `Express`
* ? Choose Nuxt.js modules `Axios, DotEnv`
* ? Choose linting tools `Prettier`
* ? Choose test framework `None`
* ? Choose rendering mode `Universal (SSR)`
* ? Choose development tools `None`

先讲解一下每一个选项

  • Project name 项目名称,这个内容会被写到package.jsonname,并且默认会在nuxt.config.jshead下的title使用,也就是网站的全局标题
  • Project description 项目描述,这个内容会被写到package.jsondescription
  • Author name 作者,通常会用注册的npm的作者,要么就是本机的用户
  • Choose programming language 程序的语言,通常是JavaScript,但是我们这里选TypeScript
  • Choose the package manager yarn和npm,我习惯用npm
  • Choose UI framework 一款ui框架
  • Choose custom server framework 自定义服务框架,就像上文说的,tomcat换成jetty,也可以不换 我选的是Express
  • Choose Nuxt.js modules nuxt的模块,通常axios是必要的,dotenv配置环境参数,通常也会选上
  • Choose linting tools 语法校验工具,我不太习惯,建议新手开启,可以强化自己的规范
  • Choose test framework 测试框架,对代码要求较高的时候需要自己编写一些测试模块
  • Choose rendering mode 渲染模式,universal 也就是我们需要的ssr,如果选spa,不如直接上vue好了
  • Choose development tools 选择一款开发工具,使用vscode就用这个吧,其实用了ts也会生成一个tsconfig.json,这个就够了

一切等待创建就绪, 创建好了之后,按照指定的方式开始配置

tsx配置:安装 vue-tsx-support后配置tsconfig.json

参照:Nuxt Typescript

compilerOptions 属性下增加:关于jsx配置项的说明可以看typescript关于jsx模式说明,在与编译配置统计增加类型引入类型 "node_modules/vue-tsx-support/enable-check.d.ts",这样就可以初步使用.tsx编写vue了

    {
        "compilerOptions": {
            ... //其他配置项
            "jsx": "preserve",
            "importHelpers": true,
        },
        "exclude":[
        // 需要去掉 "node_modules" ,不然enable-check.d.ts 不会被引入,jsx语法校验就会出错
        ]
        "include": [
            "node_modules/vue-tsx-support/enable-check.d.ts",
            "./**/*.ts",
            "./**/*.tsx",
            "./**/*.vue",
          ]
    }

scss modules 配置

我个人习惯使用scss来编写css样式,因此增加了scss的配置,但是使用tsx之后,如何使用scoped呢?这就是另一个问题了,有些人习惯使用styl,而我还是喜欢用css module,但是关于cssmodule的配置nuxt官方给出的仅寥寥无几的描述,因此我给出一些详细的步骤配置 .scsscss module

  • 第一步:安装必要模块

    npm install --save-dev node-sass sass-loader

  • 第二步:配置 nuxt.config.js文件,配置这一章在官方文档描述中配置在build.loaders.css里,而不是同级的css属性下

configuration-build#loaders

// 这是使用nuxt的配置
module.exports = {
    ... // 其他配置
    build: {
        loaders: {
          css: {
             modules: true,
          }
        }
      }
}
// 这是使用webpack的配置
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        loader: 'css-loader',
        options: { 
         // 这里对应的就是nuxt配置的css部分,由于其他的动作都已经被nuxt代理了,所以不需要配置太多规则,只要注重规则的options即可
          modules: true,
        },
      },
    ],
  },
};

至于nuxt提供的cssModules配置项,试验过后貌似没有效果,因此不知道这个配置的意义在哪儿,因此,所有的modules配置都放在css下,流程是 sass-loader加载scss文件,使用node-sass编译 --> 输出 css文件 -->使用css-loader加载css文件,提取#id.class模块,输出到对象,样式加载到html上,样式名称手动引入到页面上。之前一直纠结在scss上,其实只要了解loader的运行机制,就可以很好的理解为什么是放在css上而不是scss上了。

// index.module.scss
.name {  background:red }
import style from '/assets/scss/index.module.scss'

...// 其他必要代码
render(){
    return <div className={style.name}> {style.name} </div>
}

翻了github上面关于css-loader#modules的说明,也很少,还好,loader有错误的配置提示,然后一个一个翻,找到了css-loader/dist/options.json里,这里面是描述的说明:

讲解一下各个说明的含义

{
    "additionalProperties":false ,
    "properties": {
        "url": {
            "anyOf":[
                { 
                    "type":"boolean"
                },
                {
                    "enum": ["local", "global", "pure"]
                },
                {
                    "instanceof": "Function"  
                },
                {
                    "type": "object",
                    ...// 其他配置结构类似
                }
            ]
        }
    }
}
"additionalProperties":false 表示配置其他属性不是必要的,可以直接使用
"properties": 代表属性集,里面的属性都是可配置的
"description":属性描述,
"anyOf":[]   这是一个数组,代表任意的某一项,比如  "anyOf":[{ "type":"boolean"}] 即表示这一项可配的属性为 boolean值
"type":这个配置是说明类型值是一个可选的基础值
"instanceof":是具体的对象类型比如Function,RegExp,与type是相同属性
"enum":枚举值,可以从给定的枚举值里面选一个填

如果要使用上面的配置,则:

{
    url:true
}

或者

{
    url:"local"
}

或者

{
    url:function(){ return xxxx }
}

或者

{
    url:{
        ... 其他配置
    }
}

是不是很简单!?

具体关于css的模块化配置,将.module.的样式定义为模块化文件,这样就可以和普通的css文件区分开来,避免了全局样式名称的错乱,其他关于模块化的配置,比如指定模块的名命规则等等,这个就不过多描述了,可以翻看上面提到的具体loader配置描述options.json。

接下来只要将原来的modules:true替换成下面的

modules: {
  auto: /^.+\.module\.(css|scss)$/g
}

完整示例

到这里配置完成了,我们先删除pages下所有的的默认页面,然后新建文件 index.tsx

这时候我们需要用到几个装饰器,nuxt-property-decorator,这个和 我之前的另一个文章如何使用 vue + typescript 编写页面 ( 基础装饰器部分 )里面使用的vue-property-decorator是一样的


import {Vue ,Components} from 'nuxt-property-decorator'
import { Component as VC } from 'vue-tsx-support'
import style from '/assets/scss/index.module.scss'

interface IndexProps {
    name!:string
}

@Component
export default class Index extends VC<IndexProps> {
    @Prop() name!:string;
    render(){
        return <div className={style.name}> {style.name} </div>
    }
}

到这里基础部分就就结束了,关于vuex的ts化可以参照如何使用 vue + typescript 编写页面 ( vuex装饰器补充部分--store装饰器 )