Nuxt开发指南

in #starnote4 days ago

Nuxt开发指南

Nuxt 基于 Vue.js 创建用于生产环境的完整堆栈网页应用和网站, 免费且开源。Nuxt开发指南,包含前端开发的所有方法和技巧,一栈式开发
-> 前往星空笔记

Sort:  

"nuxt": ^4.3.1 nodejs: v22.17.1

1. 直接到github下载模板, https://github.com/nuxt/starter/tree/v4

 - 也可以用npm安装
 npm create nuxt <project-name>
 eg:npm create nuxt nuxtdemo

 - 更改配置: package.json ->  name

2. npm install --global yarn   //yarn --version  1.22.22
  yarn config set registry https://registry.npmmirror.com  切换到淘宝源
  yarn install

3. yarn dev
http://localhost:3000/ 

//vs code插件
Vetur   Vue 3 Snippets
Naive Ui Snippets   //代码提示
UnoCSS              //代码提示
Loading...

浏览器和服务器都可以解释JavaScript代码,将Vue.js组件渲染成HTML元素。这个步骤被称为渲染。Nuxt支持客户端和通用呈现。
客户端渲染 - CSR, 例如 Vue.js、React
通用渲染 - SSR, 例如 Nuxt、Next.js
静态站点生成 - SSG;
混合渲染 - 混合呈现允许每个路由使用路由规则不同的缓存规则,并决定服务器应该如何响应给定URL上的新请求。例如 Nuxt、Next.js
边缘渲染 - edge-side rendering。

Loading...
Loading...
Loading...
Loading...

官网 |
说明 |

yarn add @iconify-json/mdi   //注意按需安装!  //1.2.3
//yarn add @iconify-json/vscode-icons   

<div class="i-mdi-github text-3xl" />
<div class="i-mdi-twitter" />
<div class="i-mdi-arrow-collapse-right" />
<div class="i-mdi-alpha-i-circle" />  //提示
<div class="i-mdi-chevron-down" /> //向下的


(html comment removed:  手机端 )
<div class="ml-auto mr-2 bold lg:hidden" @click="activate('top')">
    <div class="i-mdi-dots-vertical" text-2xl/>
</div> 

<div class="i-mdi-chevron-double-right text-2xl"
  mt-20 block lg:hidden  
  text-gray-600 
  @click="activate('left')"
/>
//app.config.ts
export default defineAppConfig({
    title: 'Hello Nuxt888',
    theme: {
      dark: true,
      colors: {
        primary: '#ff0000'
      }
    }
  })
 //app.vue
 {{ appConfig.title }}
 const appConfig = useAppConfig()

 //另外一个简洁的用法是写在composables中,export即可引用
export const title = "hello nuxt"
Loading...
// 方法一
1. assets -> style.css
2. nuxt.config.ts中配置:
  css: [
    '~/assets/style.css', 
  ],
// 注意: Nuxt会自动导入style.css这个文件,故可以在配置中省略!

// 方法二
//在 app.vue 中引入样式。注意不是在<style>中!
<script setup>
import "~/assets/main.css";
</script>  

// 方法三
//或者直接在 `uno.config.ts`中定义 shortcuts,它也是相当于全局的
shortcuts: {
  // shortcuts to multiple utilities
  'containerX': 'w-[95%] mx-auto text-4.4 lg:w-[85%]'
  'btn': 'py-2 px-4 font-semibold rounded-lg shadow-md',
  'btn-green': 'text-white bg-green-500 hover:bg-green-700',
  // single utility alias
  'red': 'text-red-100'
}

引用本地js
Nuxt入门

在Nuxt中引用第三方js等资源文件,可将文件放在/assets或/public目录下
区别
    /assets目录下的文件会被webpack编译
    /public目录下的文件不会被编译
第三方文件放置在/public目录下
    /public/videojs/video-js.css
    /public/videojs/video.js
    /public/videojs/videojs-contrib-hls.js

  head: {
    ...
    link: [
      ...
      { rel: 'stylesheet', href: '/videojs/video-js.css' }
    ],
    script: [
      { src: '/videojs/video.js' },
      { src: '/videojs/videojs-contrib-hls.js' }
    ]
  },
Loading...

Nuxt使用 utils/ 目录在整个应用程序中使用auto-imports自动导入辅助函数和其他实用程序!

export function test2() {
    console.log(12793, "test.js2")
}

//也可以自定义导出目录
//nuxt.config.ts
imports: {
  dirs: ["apis"]
}

在composables/目录中编写自己的自动导入可重用函数。但它只导入顶层函数,如有二级目录,则必须在config中配置!

export const newFun = (i) => {
    return i+5
  }

//composables/gets/foo.js
imports: {
    dirs: ["composables/**"] 
},  
Loading...
Loading...
layouts -> default.vue, <slot/>可以将其它页面插入
eg:
<template>
    <div class="body">
        <NavBar/>      
        <main class="containerX"> 
            <slot/>
        </main>
    </div>
</template>

//指定页面布局
layouts -> login.vue
//pages -> login.vue
definePageMeta({
    layout:"login",
    middleware:["only-visitor"]
})
另外,命名不能使用小驼峰的方法,要使用 `-`
Loading...

Nuxt会自动使用Vue Router在底层创建路由,页面的名字就是路由地址。
app -> pages 文件夹,在此文件夹内创建页面。

app/pages/about.vue ->  localhost:3000/about

默认情况下`app/pages/index.vue`是根路径 /

//二级路由: 页面文件在一个目录下
app/pages/user/info.vue ->  localhost:3000/user/info

//二级路由中保留父组件内容
1. 在同级目录下创建同名的 vue 文件,eg: pages/user + pages/user.vue
2. `user.vue`中加入`<NuxtPage/>`即可索引到下一级的页面(page)文件

//组件导入则用slot
<slot/>

如果您在文件名中使用方括号 [ ],它将被转换为 动态路由 参数。您可以在文件名或目录中混合使用多个参数。

如果您希望参数是 可选的,必须使用双括号 [[]] 括起来,例如 ~/pages/[[slug]]/index.vue 或 ~/pages/[[slug]].vue 将匹配 / 和 /test。

目录结构
-| pages/
---| index.vue
---| users-[group]/
-----| [id].vue
在上述示例中,您可以通过 $route 对象在组件中访问 group/id:
pages/users-[group]/[id].vue

pages/users-[group]/[id].vue
<template>
  <p>{{ $route.params.group }} - {{ $route.params.id }}</p>
</template>

访问路由可以使用全局的 useRoute 函数,它与 Options API 中的 this.$route 功能相同。
const route = useRoute()
const group = route.params.group
const id = route.params.id

useRoute 返回当前路由, 必须在setup函数、插件或路由中间件中调用。
在Vue组件的模板中,可以使用$route访问路由。

const route = useRoute()  // == $route
console.log(route.path) // '/about'

//获取路径id
$route.params.id

//除了动态参数和查询参数, useRoute() 还提供了以下与当前路由相关的计算引用:
fullPath: 与当前路由关联的编码URL,包含path、query和hash
hash: 以#开头的URL的解码hash部分
matched: 与当前路由位置相匹配的归一化路由数组
meta: 附加到记录的自定义数据
name: 路由记录的唯一名称
path: URL的编码路径名部分
redirectedFrom: 在到达当前路由位置之前试图访问的路由位置
Loading...
Loading...

<NuxtLink> 组件来处理您应用程序中的各种链接。

<NuxtLink to="/about">About page</NuxtLink>

<NuxtLink :to="'/miaos/'+'@'+item.author+'/'+item.permlink">
  <img width=98% mt-3 :src="takeImage2(item.body)" rounded-2 /> 
</NuxtLink>

//将 `id` 参数传递到路由 `~/pages/posts/[id].vue` 进行链接。
<NuxtLink :to="{ name: 'posts-id', params: { id: 123 } }">
  Post 123
</NuxtLink>

// 外部链接
<NuxtLink to="https://nuxtjs.org.cn">
  Nuxt website
</NuxtLink>
target="_blank"  表示在新标签页中打开链接,
rel="noopener noreferrer" 是出于安全考虑,防止新页面获取对原页面的访问权限。

手册

Nuxt 提供了一个强大的钩子系统,可以通过钩子扩展几乎每个方面。
由于 Nuxt 整合了 Vue、Nitro 前后端两个运行时,再加上它自身的创建过程,因此框架生命周期钩子分为三类:
Nuxt 钩子;
Vue App 钩子;
Nitro App 钩子。

const nuxtApp = useNuxtApp()
eg:
nuxtApp.hook("page:start",(e)=>{
        bar.value?.start()
        // console.log("page:start");
    })
nuxtApp.hook("page:finish", () => {
  window.scrollTo(0, 0)
})

参考

//页面自动加载,会自动执行。
//在前端推荐使用,不推荐 process.client 
onMounted(() => {
    console.log(699, "moundted")
    function x (){
      console.log(722, "moundted")
    }
    x()
})

onMounted(() => {
  console.log('1123, mounted')
  let s = localStorage.getItem('farcasterid') //farcasterid
  if(s != null){
    // 读取数据
    farcasterid.value = s
  } else{
    console.log("115, null")
  }
})

//beforeMount mounted
components -> NaveBar.vue, 
<NaveBar /> 可直接导入无需引入

// 嵌套组件
components -> Ui -> Menu.vue
<UiMenu>
  test
</UiMenu>
// 或者这样写:
<ui-menu>
  test
</ui-menu>
Loading...
Loading...

脱离上下文的API
使用 createDiscreteApi 来创建一系列消息提示,它比较自由,推荐。

import { createDiscreteApi } from "naive-ui"
// import { useMessage } from "naive-ui" useMessage要有专门设置,暂时不用

let { message } = createDiscreteApi(["message"])
message.error("注册失败!\n"+error.value.data, { duration: 5e3 })
// message.error("注册失败!\n"+error.value.data)
message.success("注册成功", { duration: 5e3 })
// message.success("注册成功")
message.warning("How many roads must a man walk down")
message.loading("If I were you, I will realize that I love you more than any other guy")
message.info(
  "I don't know why nobody told you how to unfold your love",
  {
    keepAliveOnHover: true
  }
)
 
// 注意: 如果已经导入 message 而没有使用可能会导致错误!尤其是下拉菜单!
Loading...
//可以用以下测试是否在客户端:
console.log(12, document.cookie)
console.log(33, window)
注意: setup是在服务端,其中的函数却基本都在客户端渲染!

//组件中客户端渲染
<ClientOnly> component 只在客户端呈现它的slot。若只在客户端导入组件,请在客户端插件中注册该组件。
<ClientOnly fallback-tag="span" fallback="Loading comments...">
  客户端渲染
</ClientOnly>

//js中的使用
if (process.server){
  //服务器端
}
process.client  //客户端
// //import.meta.client

//在路由中设为单页面渲染,也就是关闭ssr
//nuxt.config.ts 如下设置,则gpt页面则只客户端渲染
routeRules: {
    '/gpt': { ssr: false },    
},
Loading...
Loading...
Loading...

server/utils 目录中的工具函数,会自动导入
若用默认导出 export default ,则自动导入的函数名为文件名
若用具名导出 export function useSum ,则自动导入的函数名为函数定义的名称。

// server/utils/sum.ts
export function useSum(a: number, b: number) {
  return a + b;
}

//在接口文件中直接使用即可
// routes/index.ts
export default defineEventHandler(() => {
  const sum = useSum(1, 2) // auto-imported
  return { sum }
})
Loading...
//开发环境
//package.json
"dev": "nuxt dev --port 3200"
// 或是这样:
"config": {  // here are the changes
    "nuxt": {
        "host": "0.0.0.0",
        "port": "3333"
    }
}
//或者在 nuxt.config.ts 中设置 只在开发中有效
devServer: {
  port: 9685
}
//或者,在 .env 中设置 `PORT = 9685` 即可!  
这样访问:
 if(process.server){
  console.log(566, process.env.PORT)
 } 

//设置服务器端口 port, 找到源码,直接修改即可!
源码: .output/server/index.mjs
//const port = destr(process.env.NITRO_PORT || process.env.PORT) || 3e3;
const port = 5896
Loading...
// 用localStorage来实现一个预设值
1. 先从localStorage读取,有值则赋给它设初值
const defaultRole = ref(null)
if(process.client){
  let latest = localStorage.getItem("defaultRole")
  console.log(566, "latest", latest)
  if(latest != null){
    defaultRole.value = latest
    console.log(599, "latest")
  }
}   
2. //设置或更新 如果是空值 或是与前值不同,都重新赋值
let latest = localStorage.getItem("defaultRole")
if(latest == null || role != latest){
   localStorage.setItem('defaultRole', role)
   console.log(899, "set lastname")
}
Loading...
Loading...
Loading...

[参考https://juejin.cn/post/7352797634556395535)

Github Pages 构建部署时候,会忽略隐藏文件比如.文件_文件的文件也会忽略,而我们的构建产物,刚好是在_nuxt目录下面,这些都被忽略,导致文件找不到。所以在配置时,不要用下划线作为文件夹开头!

//nuxt.config.ts
export default defineNuxtConfig({
    ...
    app: {
        buildAssetsDir: 'nuxt_assets',
    },
    experimental: {
        payloadExtraction: false
    },
    ssr: false,
    ...
})

yarn generate
Loading...
Loading...