Nuxt.js項目開發

最近小編新接手了兩個項目,這兩個項目均是使用nuxt.js框架進行開發的,這對小編來說又是一個新的大陸,故而和各位小夥伴們絮叨絮叨這個東西。
首先先說明一下這個東西是個啥。
Nuxt.js 是一個基於 Vue.js 的通用應用框架,如同Next.js之於React一樣(Next.js 是一個輕量級的 React 服務端渲染應用框架)
通過對客戶端/服務端基礎架構的抽象組織,Nuxt.js 主要關注的是應用的 UI渲染。
Nuxt.js 預設了利用Vue.js開發服務端渲染的應用所需要的各種配置。
小編的個人看法是,nuxt.js相對於vue而言確實便捷一些。
創建:npx create-nuxt-app 項目名 (npx在安裝npm的時候已經安裝,因此不用擔心,直接使用就好)
創建
各項配置的選擇:
在這裏插入圖片描述
在這裏插入圖片描述
這些配置如果沒有有特殊需要的話,直接按回車鍵就好,如果前兩項需要填寫也可以進行填寫,第三項是使用nuxt默認的服務器端框架。
創建成功之後,是需要進入的文件夾中還是可以直接進行運行均會有提示,按照提示操作即可,之後打開提供的鏈接進行訪問即可。

1、路由
①一般路由
在vue中,路由的跳轉使用的是vue-router,路由的跳轉需要開發人員自己進行編寫配置,nuxt.js不需要自行編寫,它會根據開發者page文件夾下的結構自動生成路由配置。
假設 pages 的目錄結構如下:

pages/
--| user/
-----| index.vue
-----| one.vue
--| index.vue

那麼,Nuxt.js 自動生成的路由配置如下:

router: {
  routes: [
    {
      name: 'index',
      path: '/',
      component: 'pages/index.vue'
    },
    {
      name: 'user',
      path: '/user',
      component: 'pages/user/index.vue'
    },
    {
      name: 'user-one',
      path: '/user/one',
      component: 'pages/user/one.vue'
    }
  ]
}

②子路由
在 Nuxt.js 裏面定義帶參數的動態路由,需要創建對應的以下劃線作爲前綴的 Vue 文件 或 目錄。如果想生成的路由爲二級(/index/1)、三級(/index/1/2)或是更多級,以及需要url後添加id等皆可使用子路由實現。
目錄結構:

pages/
-----| comments.vue
-----| users.vue
-----| users/
      --| _id.vue

Nuxt.js 生成對應的路由配置表爲

router: {
  routes: [
    {
      name: 'index',
      path: '/',
      component: 'pages/index.vue'
    },
   {
      name: 'users',
      path: '/users/:id?',//url爲/users/id
      component: 'pages/users/_id.vue'
   }
}

注:_id.vue中可以什麼都不寫

nuxt.js中還有其他的路由,在此我就不一一介紹了,畢竟除了以上的兩種,其他的路由小編在此次項目中並沒有使用到,瞭解的不是很多,故而就不在這裏多說了,有興趣或是需要的小夥伴可以自行到官網中瞭解。

2、asyncData
①在組件(限於頁面組件)每次加載之前被調用。返回的數據融合組件 data 方法返回的數據一併返回給當前組件。
②例子1.get請求:let [request1Data] = await Promise.all([ axios.get(url1), axios.get(url2), ])
例子2:post請求,如果post請求的參數傳遞和get請求一樣是直接使用?連接在url後邊的話便可使用
let [request1Data] = await Promise.all([ axios.postForm(url1), axios.postForm(url2), ])

 注:請求的函數,例如get和postForm可以自行封裝在一個js中,小編封裝的js函數是http.js,並把它放在plugins文件夾下。
 http.js

import axios from ‘axios’;
import qs from ‘qs’;
import config from ‘…/conf/config.service’;
// 超時時間
// axios.defaults.timeout = 5000
axios.defaults.headers.post[‘Content-Type’] = ‘application/x-www-form-urlencoded;’;
// response.addHeader( “Cache-Control”, “no-cache” );
axios.defaults.headers[‘Cache-Control’] = “no-cache”;
axios.defaults.withCredentials = true;
axios.defaults.baseUrl = config.proxyUrl;
axios.postByQs = function (url, data) {
return axios.post(url, qs.stringify(data), {
headers: {
‘Content-Type’: ‘application/x-www-form-urlencoded’,
‘Cache-Control’: ‘no-cache’,
}
})
}
axios.GET = function (url) {
return axios.get(url, {
headers: {
‘Cache-Control’: ‘no-cache’,
}
})
}
axios.postForm = function (url, data) {
return axios.post(url, data, {
headers: {
‘Content-Type’: false,
‘Cache-Control’: ‘no-cache’,
}
})
}

axios.postFile = function (url, data) {
return axios.post(url, data, {
headers: {
‘Content-Type’: ‘multipart/form-data’,
‘Cache-Control’: ‘no-cache’
}
})
}
axios.interceptors.response.use(
response => {
if (response.data.status == 401) {
window.location.hash = ‘login’;
window.location.reload()
}
return response;
},
error => {
return Promise.reject(error.response.data) // 返回接口返回的錯誤信息
});
export default axios

③使用asyncData獲取數據可以更好的進行SEO優化。但若該頁面的數據是隨時改變的,小編不建議該頁面使用此方法,因爲數據隨時的改動,今日收錄的數據對於明日來說並沒有多大的用處。所以小編推薦,當確認該頁面顯示的數據並不是時時更新再使用此方法。使用此方法獲取數據時,只有數據獲取成功並完成後客戶端纔會顯示並進行渲染,否則,頁面將一直處於加載狀態。
3、關於plugins文件夾
plugins文件夾爲插件目錄,顧名思義,是用於組織那些需要在 根vue.js應用 實例化之前需要運行的 Javascript 插件。這麼說也比較模糊,在此和大家舉個例子吧。比如,在此次項目中,小編要用到swiper插件,於是到npm中找到了vue-awesome-swiper插件。通過npm安裝依賴成功之後,並不能夠直接使用,需要進行以下幾個步驟:
①在plugins文件夾中新建js文件,例如取名爲swiper.js。此js文件是說明該項目使用vue-awesome-swiper/dist/ssr插件。
swiper.js:

import Vue from 'vue'

export default () => {
  if (process.browser) {
    //console.log('瀏覽器端渲染');
    Vue.use(require('vue-awesome-swiper/dist/ssr'), /* { default global options } */)
  }else{
    //console.log("非瀏覽器端渲染");
  }
}

②到nuxt.config.js文件中添加

....
  plugins: [
    {src:'@/plugins/swiper.js',ssr:false}
  ]
  ....

③通過以上兩步,該插件才叫做可以使用了。在components文件夾中新建文件,例如:slider.vue。
slider.vue:

<template>
  <div class="swiper_container swiper-no-swiping">
    <div class="swiper_wrapper_content">
      <no-ssr>
        <div v-swiper:mySwiper="swiperOption" @someSwiperEvent="swiperEvent" class="swiper_wrapper_content_con">
          <div class="swiper-wrapper">
            <div class="swiper-slide img1"><span></span></div>
          </div>
<!--          <div class="swiper-pagination"></div>-->
        </div>
      </no-ssr>
    </div>
  </div>
</template>

<script>
  export default {
    name: '',
    layout: 'welcomeIndex',
    data() {
      return {
        swiperOption: {
          pagination: {
            el: '.swiper-pagination',
            clickable: false
          },
          autoplay: {
            delay: 5000,
          },
          effect: 'slide',
          paginationClickable: true,
          speed: 800,
          loop:true,
          observer: true,
          observeParents: true,
          autoplayDisableOnInteraction: false
        }
      }
    },
    computed: {},
    created() {
         },
    mounted() {

    },
    methods: {
    
    }
  }
</script>

<style lang="scss" scoped>
  .swiper_container{
    width: 100%;
    height: 100%;
    .swiper_wrapper_content{
      width: 100%;
      height: 100%;
      .swiper_wrapper_content_con{
        width: 100%;
        height: 100%;
        .swiper-wrapper{
          width: 100%;
          height: 100%;
          .swiper-slide {
            width: 100%;
            height: 100%;
            span {
              width: 100%;
              height: 100%;
              display: inline-block;
              background-color: #00dad7;
              background: url("../static/images/banner/banner1.jpg") no-repeat top center;
            }
          }
          img{
            width: 100%;
            height: 100%;
          }
        }
      }
    }
  }

</style>

在此,小編將輪播圖作爲背景圖是爲了適配,防止圖片由於屏幕大小、分辨率問題導致圖片變形。
④在頁面中使用該組件

<template>
  <div class="container">
    <div class="banner">
      <Slider></Slider>
    </div>
  </div>
</template>

<script>
  import Slider from "~/components/slider.vue"
  export default {
	  name:"index",
	  data() {
		  return{
		  }
	  },
	  components: {
	    Slider,
	  },
 }
 </script>

注:引入bootstrap、jq等插件時,小編不推薦直接在頁面中的head裏直接引用,即最好不要使用以下方式引用

<script>
export default {
	data(){
		return{
		}
	},
	head(){
      return {
        title: '',
        meta: [
          { hid: 'description', name: 'description', content: '' },
          { hid: 'keywords', name: 'keywords', content: '' }
        ],
        srcipt:[
        	{src:'xxxxx.js'}
        ]
      }
    },
}
</script>

溫馨提示:
1、若想使用asyncData進行異步獲取數據,頁面的跳轉建議不使用nuxt-router,若使用nuxt-router進行路由跳轉,當用戶點擊瀏覽器返回箭頭時會報錯,需要進行手動刷新。當頁面停留時間過長,進行刷新時也會報錯,這時建議在使用asyncData前先判斷是否是服務端渲染,若是服務端則再進行數據的請求,這樣就不會出現以上問題。
2、使用asyncData異步獲取數據時,除了return所需的數據字段,不要在其他的地方使用return,否則會導致數據無法正常返回而造成數據渲染顯示異常。
3、若項目中使用element-ui的NavMenu組件,循環渲染el-dropdown-item標籤時,不要使用v-text進行數據渲染,頁面會報虛擬DOM的警告,雖然只是警告,但作爲一名合格的程序員,控制檯報紅都是分分鐘刺眼的事。

官方文檔:https://zh.nuxtjs.org/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章