Nuxtjs3 rewrite blog process memo

Original link: https://blog.kelu.org/tech/2022/05/10/nuxtjs.html

As a back-end person whose job is infrastructure development, I compare js to linux system, vue to docker/containerd, and nuxt to kubernetes. Of course this analogy is not very accurate. The front end is much softer than the container war, and it feels like everyone is repeating construction on the bottom layer. Comparing container technology, swarm/k8s/mesos will be the winner in about 5 years. The current mainstream of the front-end is still react/vue/Angular. Based on these three, there are their own server-side frameworks (the lower-level typescript has been unified), resulting in a high front-end learning threshold, and framework concepts and design patterns have actually gone. After the old road of the back-end framework, many concepts of back-end development can be translated. I believe more in authority, I believe in Taylor Otwell (creator of Laravel), he said that vue is good, so I followed him to use it.

The first two recorded notes on vue2 and vue3 . This one records nuxtjs3, which is the official website . Nuxt3 will be officially released on April 20, 2022, codenamed “Mount Hope” .

Nuxt3 is an SSR framework released based on Vue3:

  • SPA applications: that is, single-page applications, these are mostly client-side applications and cannot be optimized for SEO (search engine optimization).
  • SSR application: Rendering on the server, and returning to the client after rendering is completed, each page has an independent URL, which is SEO friendly and corresponds to display websites such as corporate websites, product displays, and blogs.

Here are some of the advantages shown on the official website:

  • Lighter weight: Up to 75 times smaller server deployments and client artifacts when based on modern browsers.
  • Faster: Optimize cold starts with dynamic server-side code.
  • Hybrid: Incremental dynamic generation and other advanced modes are now possible.
  • Suspense: Get data in any component before and after navigation.
  • Composition API : Use the Composition API and Nuxt3’s composables for true reusability.
  • Nuxt CLI: A permission-free experience that helps you easily build projects and integrate modules.
  • Nuxt Devtools: Dedicated debugging tools, more information and quick fixes to work efficiently in the browser.
  • Nuxt Kit: New TypeScript-based and cross-version compatible module development.
  • Webpack5: Faster builds and smaller buildpacks with zero configuration.
  • Vite: Experience lightweight and fast HMR with Vite as your bundler.
  • Vue3: Full support for Vue3 syntax, which is especially critical.
  • TypeScript: Consists of native TypeScript and ESM with no additional configuration steps.

Install

npx is a command added by npm since version 5.2

Official link

 npx nuxi init nuxt3-test # 快速创建

image-20220517113727498

 npm install npm run dev 

image-20220517113912229

The generated files are as follows:

image-20220517114211393

The important thing to mention here is the nuxt.config.js file, where all the configurations are.

Some commonly used directories are as follows:

 - pages // 页面目录,Nuxt.js 框架读取该目录下所有的.vue 文件并自动生成对应的路由配置。 - components // 组件目录- assets // 静态资源目录- public // 不需要vue 处理的静态资源,此类文件不会被Nuxt.js 调用Webpack 进行构建编译处理。 服务器启动的时候,该目录下的文件会映射至应用的根路径/ 下。 - layouts // 项目布局目录- common // 存储js文件- plugins // nuxt扩展的js文件- store // vuex的配置文件,Nuxt.js 框架集成了Vuex 状态树的相关功能配置,在store 目录下创建一个index.js 文件可激活这些配置。

Configuration reference link:

Delete app.vue in the root directory, and then create a new index.vue file in the pages directory, which will automatically associate vue-router to support dynamic routing.

Because I developed it in a containerized environment, I changed the running port to port 80 for easier access. If you find that the configuration does not take effect, you can try to restart the one-card container (multiple containers feel conflicting when starting npm run in the same directory, and some configurations do not take effect).

image-20220519113053640

Some official website memos

head

In the setup function, useHead can be called with a meta-attribute object with the keys corresponding to the meta tags: title , titleTemplate , base , script , style , meta and link , and htmlAttrs and bodyAttrs . There are also two shorthand properties charset and viewport .

data-fetching

Nuxt provides useFetch , useLazyFetch and useAsyncData to useLazyAsyncData to handle data fetching in the application.

state-management

useState is an SSR friendly ref replacement. Its value will be preserved after server-side rendering (during client-side hydration) and shared across all components using a unique key.

server-routes

Nuxt will automatically scan for files in the directory ~/server/api , and ~/server/routes to register API and server handlers with HMR support in ~/server/middleware .

Each file should export a file defineEventHandler() .

routing

Nuxt uses the scheme of auto-loading routes, which will automatically create router objects according to the directory of your project;

A simple example, a directory example under pages and its corresponding route is as follows:

 test: a.vue -- 对应路径:/test/a index.vue -- 对应路由:/test index: _id: a.vue -- 对应路由:/{id}/a index.vue -- 对应路由:/{id} index.vue -- 对应路由:/,会被包含到上一级的index.vue的<nuxt-child>中index.vue -- 对应路由:/,其中如果包含有nuxt-child元素,那么会将index目录下的index.vue加载到nuxt-child元素位置
  • To define a dynamic route with parameters in Nuxt.js, you need to create a corresponding Vue file or directory prefixed with an underscore.
  • If you want to set _id as a required route, you need to create an index.vue file in the users/_id directory.

Routing parameter verification

Nuxt.js allows you to define parameter validation methods in dynamically routed components.

For example: pages/users/_id.vue

 export default { validate ({ params }) { // 必须是number类型return /^\d+$/.test(params.id) } }

If the value returned by the validation method is not true or the resolve in the Promise resolves to false or an Error is thrown, Nuxt.js will automatically load and display a 404 error page or a 500 error page.

Dynamic nested routing with unknown nesting depth

If you don’t know the depth of the URL structure, you can use _.vue to dynamically match nested paths. This will handle the case of a mismatch with a more specific request.

File structure:

 pages/ --| people/ -----| _id.vue -----| index.vue --| _.vue --| index.vue

Knowledge point

Some codes are just for memorizing the structure of the code, which does not mean that the logic is correct.

There is too much syntactic sugar on the front end, and I think these syntactic sugars are a major reason for the obscurity of the front end.

However, “without him, but familiar with you” is the same at the front end.

  1. command line nuxi

     npx nuxi init nuxt3-test # 快速创建
  2. layout layout html (static)

     layout文件夹page文件夹
  3. import css

     < style scope > .abc {} </ style >
  4. application state

     < script setup > const options = reactive ({ xxx : " xxx " }); </ script > < template > <button class= "abc" :class= "options.xxx === 'xxx' && 'option-active'" > abc </button> </ template >
  5. a tag replaced with NuxtLink tag

     <NuxtLink to= "/" > Home </NuxtLink>
  6. simple typescript

    I think the syntax of typescript is a bit like golang. It looks very comfortable~

    First define an interface type, some options/constants are defined with enum, and then const an instance.

     < script setup lang= "ts" > interface OptionState { xxx : string , yyy : string } enum Xxx { AAA = " aaa " , BBB = " bbb " } const obj : = OptionState { xxx : Xxx . AAA , yyy : Xxx . BBB } const options = reactive < OptionState > ({ xxx : Xxx . AAA , yyy : Xxx . BBB }); </ script >
  7. import content defined in other files

     import {OptionState} from "@/data" // 其他文件要export特定的定义

    In some tutorials, in order to simplify the content, a json file is directly prepared, and then the data is imported:

     < script setup lang= "ts" > import { xxx } from " @/data.json " const rest = { first : [... xxx ]. splice ( 0 , 25 ), second : [... xxx ]. spice ( 25 , 25 ), }; </ script > < template > <Row v-for= "r in rest.first" :key= "r.id" /> <Row v-for= "r in rest.second" :key= "r.id" /> </ template >
  8. update state

     < script setup lang= "ts" > const computeSelectedNames = () => { const filterNames = names . filter (( name ) => name . xxx === options . xxx ) . filter (( name ) => name . yyy === options . yyy ) . filter (( name ) => { return ... }) selectdNames . value = filterdNames . map (( name ) => name . xxx ) }; const selectdNames = ref < string [] > {[]} </ script > < template > <button class= "abc" @ click= "computeSelectName" > Find </button> </ template >
  9. Pay attention to splitting components and passing values ​​in parent and child components through props

     < script setup lang= "ts" > interface OptionProps { option : { id : string , title : string , catagory : string , index : number }; } const props = defindProps < OptionProps > () </ script >

    Pass in the parent component:

    “`vue

<Row v-for=”(r,index) in rest.first” :key=”r.id” :index=”index”/>
<Row v-for=”(r,index) in rest.second” :key=”r.id” :index=”index”/>

“`

The tags that start with capitals are components, some of which are reserved by nuxt and used as header content, similar to metadata

  1. Triggering parent-child components to pass values ​​through events.

     // 父: < script setup lang= "ts" > const removeName = ( index : number ) => { const filteredNames = [... selectdNames . value ] filterNames . splice ( index , 1 ) selectedName . value = filterNames } </ script > < template > <CardName v-for= "(name, index) in selectedNames" :key= "name" :name= "name" @ remove= "()=> removeName(index)" :index= "index" /> </ template > // 子CardName: < script setup lang= "ts" > interface NameProps { name : string ; index : number } const props = defindProps < NameProps > (); const emit = defindEmits ([ " remove " ]) const removeName = () => { emit ( " remove " , props . index ) } </ script > < template > <p @ click= "removeName" > xxx </p> </ template >
  2. Common loop statements

     v-for
  3. Pages, file-based routing

     < script setup lang= "ts" > // import {} from "#app"; // 用来让编辑器不报错的,其实没什么用。 import xxx from " @/data.json " const route = useRoute (); const name = route . params . name ; const x = xxx . find ( r => r . name === name ) </ script > < template > </ template >
  4. 404 page

  5. Layouts

    Create the layouts folder and create the default.vue file.

    Declare the use of a specific layout in the page

     < template > <div> <NuxtLayout name= "custom" > <Xxx /> </NuxtLayout> </div> </ template >

    Insert a slot in the layout (assuming the layout name is error)

     < template > <div> <slot name= "xxx" /> <div> ... </div> </div> </ template >

    In the page:

     < template > <div> <NuxtLayout name= "error" > <template #xxx > <h1></h1> </ template > </NuxtLayout> <div> ... </div> </div> </template>
  6. metadata

    image-20220523155833406

    In order to facilitate control, it can also be written in script ,

    image-20220523160139589

    You can also use outside stylesheets :

    Configured in nuxt.config.js.

     export default defineNuxtConfig ({ charset : " utf-8 " , viewport : " width=device-width, initial-scale=1, maximum-scale=1 " , meta : { link : [ { rel : " stylesheet " , href : " /assets/css/style.css " }, { rel : " stylesheet " , href : " /assets/css/font-awesome.min.css " }, ], script : [ { src : ' /assets/js/jquery.min.js ' }, ], } })
  7. Web Data Status Design

  8. composable, useState

    Used to save state. You cannot use ref for tracking, because there is no render here, which will cause memory leaks.

    image-20220523162132417

    image-20220523162252693

  9. Global State

    image-20220523162655826

    image-20220523162728965

  10. Generate static website

References

This article is reprinted from: https://blog.kelu.org/tech/2022/05/10/nuxtjs.html
This site is for inclusion only, and the copyright belongs to the original author.

Leave a Comment