nuxt3初次使用问题记录

261 阅读3分钟

1.proxy代理

在nuxt.config.ts文件中增加nitro.的devProxy完成代理:

nitro: {
    devProxy: {
      '/api': {
        target: process.env.PROD_BASE_URL,  //你的后台服务器的ip
        changeOrigin: true,
      }
    }
},

2.api封装和服务端渲染

  • ①utils\request.ts封装请求
import { nextTick } from 'vue'
const fetch = async (url: string, options?: any): Promise<any> => {
    if(!process.server){
        await nextTick()
    }
    const reqUrl = '/api' + url;
    return new Promise((resolve, reject) => {
        useFetch(reqUrl, { ...options }).then(({ data }: any) => {
            if (!data._rawValue) {
                reject("接口500")
            } else if (data._rawValue.status !== 200) {
                if(!process.server){
                    console.log("接口500");
                }
            } else {
                resolve(ref(data))
            }
        }).catch((err: any) => {
            reject(err)
        })
    })
}

export default new class Http {

    get(url: string, params?: any): Promise<any> {
        return fetch(url, { method: 'get', params })
    }

    post(url: string, params?: any): Promise<any> {
        return fetch(url, { method: 'post', params })
    }

    put(url: string, body?: any): Promise<any> {
        return fetch(url, { method: 'put', body })
    }

    delete(url: string, body?: any): Promise<any> {
        return fetch(url, { method: 'delete', body })
    }
}
  • ②nuxt.config.ts添加runtimeConfig
runtimeConfig: {
    public: {
      baseURL: process.env.PROD_BASE_URL  //后台服务ip
    },
}
  • ③ server\middleware (注意这里是server下的中间件)
const { public: { baseURL } } = useRuntimeConfig()
export default defineEventHandler(async (event) => {
    if (event.node.req.url?.includes('/api')) {
        const { method, url } = event.node.req
        const options: any = {
            responseType: 'json',
        }
        options.headers = {
            'content-type': 'application/json',
            accept: 'application/json'
        }
        options.method = method
        if (method !== 'get' && method !== 'GET') {
            options.body = JSON.stringify(await readBody(event))
        }
        let urls = url.replace('/api','');
        const resBody = await $fetch(baseURL + urls, options)
            .then(res => {
                return res
            })
            .catch(err => {
                return {
                    status: '500',
                    code: '500',
                    msg: '服务端错误',
                    payload: { }
                }
            })
        return resBody
    }
})

然后再setup中请求接口 页面源代码就可以显示到动态的数据啦

3.页面响应式处理(官网适配手机端)

  • ①目录结构整理的时候 尽量让每个页面对应的手机端页面 都用相同的路由名,手机端路由只多一个手机的前缀,放一下我们项目的页面目录结构

image.png

这样处理我们直接访问 http://localhost:6565 ,就是pc端首页, http://localhost:6565/mobile 就是手机端首页, http://localhost:6565/news 就是pc新闻页面,http://localhost:6565/mobile/news 就是手机端新闻页面

  • ②安装插件postcss-px-to-viewport-8-plugin,然后配置nuxt.config.ts
postcss:{
    plugins:{
      'postcss-px-to-viewport-8-plugin':{
        unitToConvert: 'px', // 需要转换的单位,默认为"px"
        viewportWidth: 750, // 设计稿的视口宽度
        unitPrecision: 5, // 单位转换后保留的精度
        propList: ['*'], // 能转化为vw的属性列表
        viewportUnit: 'vw', // 希望使用的视口单位
        fontViewportUnit: 'vw', // 字体使用的视口单位
        selectorBlackList: [], // 需要忽略的CSS选择器,不会转为视口单位,使用原有的px等单位。
        exclude:[
          /node_modules/,
          /components/,
          /pages\/index/,
          /pages\/news/,
          /pages\/aboutUs/,
          /pages\/employee/,
          /pages\/enterpriseService/,
        ],
        minPixelValue: 1, // 设置最小的转换数值,如果为1的话,只有大于1的值会被转换
        mediaQuery: false, // 媒体查询里的单位是否需要转换单位
        replace: true, //  是否直接更换属性值,而不添加备用属性
        landscape: false, // 是否添加根据 landscapeWidth 生成的媒体查询条件 @media (orientation: landscape)
        landscapeUnit: 'vw', // 横屏时使用的单位
        landscapeWidth: 1125 // 横屏时使用的视口宽度
      }
    }
  },

根据设计稿调整viewportWidth,然后排除掉pc端页面(配置exclude),因为当时写include发现不好使,就写了排除了

  • ③配置middleware\default.global.js
export default defineNuxtRouteMiddleware((to, from) => {
    if (!process.server) {
        // 是否是移动端设备
        const isMobile = /(Android|webOS|iPhone|iPod|tablet|BlackBerry|Mobile)/i.test(navigator.userAgent)
        // 是否是手机端路由
        const isRouterMobile = /mobile/i.test(to.fullPath)

        if(to.fullPath === "/aboutUs" && isMobile){
            let path = "/mobile"
            return navigateTo(path)
        }else if (!isMobile && isRouterMobile) { // 手机端路由跳转pc端
            let path = to.fullPath.replace('/mobile', '')
            return navigateTo(path)
        } else if (isMobile && !isRouterMobile) { // pc端路由跳转手机端
            let path = '/mobile' + to.fullPath.slice(0, to.fullPath.length)
            return navigateTo(path)
        }
    } 
})

这样处理 同样的路径放到pc端和手机端 都会打开它适配的页面了

到现在遇到的值得记录的问题就是这些,后面想到了在补充