天天看點

手牽手學習vue之從0到1搭建項目

手牽手學習vue之從0到1搭建項目

背景

作為一個三年左右的程式員,時常是焦慮的,總是感覺會的不多,想着後面的路到底怎麼走?要不要繼續接着往下走!質疑的聲音就慢慢出現在自己的耳邊,但是我不能放棄,走到今天挺不容易的,面對自己對自己的質疑,要坦然面對,積極克服,失敗者才會放棄。我不是聰明的大多數,我想做勤奮的小部分。是以今年就萌生了好好寫文章來記錄知識點的想法,畢竟現在的學習成本太高,忘記了重新再去學習,精力、時間都是不允許,文章記錄下來可以時不時鞏固一下。這可能不是最好的方式,但是我目前認為最好的方式,我不會放棄,我一直在路上。緻敬每一位為夢想堅持的人,平凡人是大多數,不要總被外部環境影響。加油!!! :)

全局安裝

// 基于目前最新的@vue/cli,全局安裝快速原型開發。

cnpm install -g @vue/cli
           

建立項目

vue create vue-project-template
//或者
vue ui //使用界面化建構,vuex、vue-router都會配置好
           

安裝vue-router

npm install vue-router -S
           
  • 建立router檔案夾 index.js檔案,并注入根節點
import Vue from "vue";
import VueRouter from "vue-router";

Vue.use(VueRouter);

const routes = [
  {
    path: "/",
    name: "Home",
    component: () => import("../views/Home.vue"),
  },
  {
    path: "/about",
    name: "About",
    component: () => import("../views/About.vue"),
  },
];

const router = new VueRouter({
  mode: "history",
  base: process.env.BASE_URL,
  routes,
});

export default router;
           
//[email protected]版本
import Vue from 'vue'
import App from './App.vue'
import router from './router'

Vue.config.productionTip = false

new Vue({
  router,
  render: h => h(App)
}).$mount('#app')

//[email protected]以上版本
import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";

createApp(App)
  .use(router)
  .mount("#app");
           
// App.vue 路由視圖

<template>
  <div id="app">
    <router-view/>
  </div>
</template>
           

安裝vuex

npm install vuex -S
           
  • 建立store檔案夾 index.js檔案,并注入根節點
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
  },
  mutations: {
  },
  actions: {
  },
  modules: {
  }
})
           
import Vue from 'vue'
import App from './App.vue'
import store from './store'

Vue.config.productionTip = false

new Vue({
  store,
  render: h => h(App)
}).$mount('#app')
           

總結:如果項目夠大,我們可以分子產品去管理,詳情

安裝axios

npm install axios -S
           
  • 封裝請求
import axios from 'axios'
import { Notification, MessageBox, Message } from 'element-ui'
import store from '@/store'
import { getToken } from '@/utils/auth'
 
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
 
// 建立axios執行個體
const service = axios.create({
    // axios中請求配置有baseURL選項,表示請求URL公共部分
    baseURL: process.env.VUE_APP_BASE_API,
    // 逾時
    timeout: 10000
})
// request攔截器
service.interceptors.request.use(
    config => {
        if (getToken()) {
            config.headers['Authorization'] = 'Bearer ' + getToken() // 讓每個請求攜帶自定義token 請根據實際情況自行修改
        }
        return config
    },
    error => {
        console.log(error)
        Promise.reject(error)
    }
)
 
// 響應攔截器
service.interceptors.response.use(res => {
    const code = res.data.code
    if (code === 401) {
        MessageBox.confirm(
            '登入狀态已過期,您可以繼續留在該頁面,或者重新登入',
            '系統提示',
            {
                confirmButtonText: '重新登入',
                cancelButtonText: '取消',
                type: 'warning'
            }
        ).then(() => {
            store.dispatch('LogOut').then(() => {
                location.reload() // 為了重新執行個體化vue-router對象 避免bug
            })
        })
    } else if (code !== 200) {
        Notification.error({
            title: res.data.msg
        })
        return Promise.reject('error')
    } else {
        return res.data
    }
},
    error => {
        console.log('err' + error)
        Message({
            message: error.message,
            type: 'error',
            duration: 5 * 1000
        })
        return Promise.reject(error)
    }
)
 
export default service
           
  • 根據功能子產品建立請求
import service from "../../src/utils/request";
 
/**
 * 登入接口
 */
 
export function Login(data) {
  return service.request({
    url: "/login/",
    method: "POST",
    data,
  });
           
  • 元件調用
import { Login } from "../../api/account";
onFinish = (values) => {
    Login(values)
      .then((res) => {
        message.success("登入成功");
        console.log(res);
      })
      .catch((err) => {
        console.log(err);
      });
    console.log("Received values of form: ", values);
  };
           

總結:如果您有前端跨域的需求,請移步

預處理器Less

npm install less less-loader --save-dev
           
  • 按需調用 
// 單檔案使用
<style scoped >
   @import "../../../style/config.less";//引入公共樣式
   @import "../../../style/styles.less";
  .upload-file-container {
    display: flex;
    align-items: center;

    .upload-bt {
      width: 80px;
      height: 30px;
      border-radius: 6px;
      border: 1px solid @defaultBlueClick;//使用公共樣式
      .flexCenter();
      color: @defaultBlueClick;
      cursor: pointer;

      i {
        font-size: 20px;
        margin-right: 4px;
        position: relative;
        top: 1px;
      }
    }
}

</style>
           
// 公共樣式庫
@leftNavBarWidth: 210px; // 側邊導航欄寬度
@leftCollapseBarWidth: 70px; // 側邊欄收起後高度
@leftCollapseBarHoverColor: rgba(55, 71, 96, 1); // 側邊欄一級按鈕hover顔色
@leftNavBarBgColor: rgba(44, 59, 81, 1); // 側邊導航欄顔色
@logoHeight: 210px; // 左上角logo欄的高度
@navActiveBgColor: rgba(55, 71, 96, 1); // 側邊導航欄打開後的背景色

//使用
 border: 1px solid @defaultBlueClick;//使用公共樣式

========================================================

//公共樣式庫
.flexCenter() {
  display: flex;
  justify-content: center;
  align-items: center;
}

.oneLineWord() {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

//使用
.el-tabs__nav-scroll {
   .flexCenter()
}
           
  • 全局變量

1.首先需要安裝style-resources-loader插件

npm install sass-resources-loader --save-dev
           

2.在vue.config.js中配置

// 第三方插件配置
    pluginOptions: {
        'style-resources-loader': {
            preProcessor: 'less',
            patterns: [
                // 全局變量路徑,不能使用路徑别名
                path.resolve(__dirname, './src/assets/css/rainbow-variables.less')
            ]
        }
    },
           

使用class

  • 在utils檔案下建立data.js用于存放方法,index.js檔案用于分子產品導出
//data.js

class Activity {
  // 性别
  sexOptions() {
    return [
      { label: "男", value: "male" },
      { label: "女", value: "female" },
    ];
  }

  getSexLabelByValue(value) {
    let row = this.sexOptions().filter((d) => d.value === value);
    if (row.length !== 1) return false;
    return row[0].label;
  }
}

class system {}

const Data = {
  activity: new Activity(),
  system: new system(),
};

export default Data;
           
//index.js

import data from "./data";

export default {
  data,
};
           
// 全局引用 main.js

import $utils from "./utils";

Vue.prototype.$utils = $utils;
           
//元件中使用

this.$utils.data.activity.getSexLabelByValue("male")
           

配置vue-config.js

module.exports = {
  publicPath:
    process.env.NODE_ENV === "production" ? "/production-sub-path/" : "/", //部署應用包時的基本 URL
  outputDir: "dist", //當運作 vue-cli-service build 時生成的生産環境建構檔案的目錄
  assetsDir: "", //放置生成的靜态資源 (js、css、img、fonts) 的 (相對于 outputDir 的) 目錄。
  indexPath: "index.html", //指定生成的 index.html 的輸出路徑 (相對于 outputDir)。也可以是一個絕對路徑。
  filenameHashing: true, //預設情況下,生成的靜态資源在它們的檔案名中包含了 hash 以便更好的控制緩存。然而,這也要求 index 的 HTML 是被 Vue CLI 自動生成的。如果你無法使用 Vue CLI 生成的 index HTML,你可以通過将這個選項設為 false 來關閉檔案名哈希。
  pages: {
    index: {
      //page入口檔案
      entry: "src/main.js",
      //模闆檔案
      template: "public/index.html",
      //在dist/index.html的輸出
      filename: "index.html",
      // 當使用 title 選項時,
      // template 中的 title 标簽需要是 <title><%= htmlWebpackPlugin.options.title %></title>
      title: "Index Page",
      // 在這個頁面中包含的塊,預設情況下會包含
      // 提取出來的通用 chunk 和 vendor chunk。
      chunks: ["chunk-vendors", "chunk-common", "index"],
      // 簡寫格式
      // 模闆檔案預設是 `public/subpage.html`
      // 如果不存在,就是 `public/index.html`.
      // 輸出檔案預設是 `subpage.html`.
      subpage: "src/main.js" /*注意這個是*/,
    },
  },
  // 是否在儲存的時候使用 `eslint-loader` 進行檢查。
  // 有效的值:`ture` | `false` | `"error"`
  // 當設定為 `"error"` 時,檢查出的錯誤會觸發編譯失敗。
  lintOnSave: process.env.NODE_ENV !== "production", //false
  //使用帶有浏覽器内編譯器的完整建構版本
  runtimeCompiler: false,
  //預設情況下 babel-loader 會忽略所有 node_modules 中的檔案。如果你想要通過 Babel 顯式轉譯一個依賴,可以在這個選項中列出來。
  transpileDependencies: [],
  //如果你不需要生産環境的 source map,可以将其設定為 false 以加速生産環境建構。
  productionSourceMap: false,
  // 調整内部的 webpack 配置。
  // 查閱 https://github.com/vuejs/vue-docs-zh-cn/blob/master/vue-cli/webpack.md
  chainWebpack: () => {},
  configureWebpack: () => {},
  css: {
    //是否将元件中的 CSS 提取至一個獨立的 CSS 檔案中 (而不是動态注入到 JavaScript 中的 inline 代碼)。
    //生産環境下是 true,開發環境下是 false
    extract: false,
    //是否為 CSS 開啟 source map。設定為 true 之後可能會影響建構的性能。
    sourceMap: false,
    // 為預處理器的 loader 傳遞自定義選項。比如傳遞給
    // sass-loader 時,使用 `{ sass: { ... } }`。
    loaderOptions: {},
    // 為所有的 CSS 及其預處理檔案開啟 CSS Modules。
    // 這個選項不會影響 `*.vue` 檔案。
    modules: false,
  },
  // 配置 webpack-dev-server 行為。
  devServer: {
    open: process.platform === "darwin",//配置後自動啟動浏覽器
    host: "0.0.0.0",
    port: 8080,
    https: false,
    hotOnly: false,//熱更新
    // 查閱 https://github.com/vuejs/vue-docs-zh-cn/blob/master/vue-cli/cli-service.md#配置代理
    proxy: {
      "/admin": {
        target: "http://huangshan.jsxhfh.com/admin",
        changeOrigin: true,
        pathRewrite: {
          "^/admin": "",
        },
      },
    },
    // 三方插件的選項
    pluginOptions: {
      // ...
    },
  },
};
           

github位址 望批評指教!!!

繼續閱讀