luffy--03 首頁和登錄註冊(跨域問題的解決)

5. 搭建前端項目

5.1 建立項目目錄

cd 項目目錄
vue init webpack lufei_pc

例如,我要把項目保存在~/Desktop桌面目錄下,能夠以下操做:
cd ~/Desktop
vue init webpack lufei_pc

根據須要在生成項目時,咱們選擇對應的選項, 效果:css

 

根據上面的提示,咱們已經把vue項目構建好了,運行測試服務器。前端

打開項目已經,在pycharm的終端下運行vue項目,查看效果。vue

npm run devnode

 

5.2 初始化前端項目

清除默認的HelloWorld組件和APP.vue中的默認樣式webpack

5.3 安裝路由vue-router

5.3.1 下載路由組件

npm i vue-router -Sios

5.3.2 配置路由

5.3.2.1 初始化路由對象

在src目錄下建立routers路由目錄,在routers目錄下建立index.js路由文件nginx

index.js路由文件中,編寫初始化路由對象的代碼 .git

import Vue from "vue"
import Router from "vue-router"

// 這裏導入可讓讓用戶訪問的組件

Vue.use(Router);

export default new Router({
  // 設置路由模式爲‘history’,去掉默認的#
  mode: "history",
  routes:[
    // 路由列表

  ]
})

5.3.2.2 註冊路由信息

打開main.js文件,把router對象註冊到vue中.代碼:github

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './routers/index';

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
});

5.3.2.3 在視圖中顯示路由對應的內容

在App.vue組件中,添加顯示路由對應的內容。web

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

<script>
export default {
  name: 'App',
  components: {

  }
}
</script>

<style>

</style>

5.3.2.4 建立並提供前端首頁的組件

在components/Home.vue中建立主頁組件

<template>
  <div id="home">
    前端首頁
  </div>
</template>
<script>
  export default {
      name:"Home",
      data(){
          return {
              
          }
      }
  }
</script>

<style scoped>

</style>

註冊相關的路由在routers/index.js中

// import Vue from "vue"
// import Router from "vue-router"
//
//
// // 這裏導入可讓讓用戶訪問的組件
import Home from "../components/Home"
// Vue.use(Router);
//
// export default new Router({
//   // 設置路由模式爲‘history’,去掉默認的#
//   mode: "history",
//   routes:[
//     // 路由列表
     {
       name:"Home",
       path:"/",
       component:Home,
     },
      {
       name:"Home",
       path:"/home",
       component:Home,
     },
   ]
// })

5.4 前端初始化全局變量和全局方法

在src目錄下建立settings.js站點開發配置文件:

export default {
  Host:"http://127.0.0.1",
}

咱們須要在main.js中引用這個配置

// // The Vue build version to load with the `import` command
// // (runtime-only or standalone) has been set in webpack.base.conf with an alias.
// import Vue from 'vue'
// import App from './App'
// import router from './routers/index';
import settings from "./settings"
// Vue.config.productionTip = false;
Vue.prototype.$settings = settings;
//
// /* eslint-disable no-new */
// new Vue({
//   el: '#app',
//   router,
//   components: { App },
//   template: '<App/>'
// });

5.5 引入ElementUI  

npm i element-ui -S

上面的命令等同於 
npm install element-ui --save

5.5.1 配置ElementUI到項目中

在main.js中導入ElementUI,並調用。

代碼:

。。。

// elementUI 導入
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
// 調用插件
Vue.use(ElementUI);

。。。

成功引入了ElementUI之後,接下來咱們就能夠開始進入前端頁面開發,首先是首頁。

接下來咱們把以前完成的首頁,直接拿過來使用[注意除了組件之外,還有靜態文件也須要拿過來,包括App.vue裏面的公共樣式],並運行項目。

 

App.vue,全局css初始化代碼(通常位全局的公共樣式)

<style>
  body,h1,h2,h3,h4,h5,ul,p{
    padding: 0;
    margin:0;
    font-weight: normal;
  }
  body{
    margin-top: 80px;
  }
  a{
    text-decoration: none;
    color: #4a4a4a;
  }
  a:hover{
    color: #000;
  }

  ul{
    list-style: none;
  }

  img{
    width: 100%;
  }

  .header .el-menu li .el-submenu__title{
    height: 26px!important;
    line-height: 26px!important;
  }
  .el-menu--popup{
    min-width: 140px;
  }
  .el-checkbox__inner{
    width:16px;
    height: 16px;
    border: 1px solid #999;
  }
  .el-checkbox__inner:after{
    width: 6px;
    height: 8px;
  }
  .el-form-item__content{
    margin-left:0px!important;
    width: 120px;
  }
</style>

Home.vue中添加代碼:

<template>
  <div id="home">
    <Header/>
    <Banner/>
    <Footer/>
  </div>
</template>

<script>
import Header from "./common/Header"
import Banner from "./common/Banner"
import Footer from "./common/Footer"

export default {
  name:"Home",
  data(){
    return {

    }
  },
  components:{
    Header,
    Banner,
    Footer,
  }
}
</script>

<style scoped>

</style>

 

建立頭部頁面

建立在components/common/Header.vue中,代碼

<template>
  <div class="header">
    <el-container>
      <el-header>
        <el-row>
          <el-col class="logo" :span="3">
            <a href="/">
              <img src="@/assets/head-logo.svg" alt="">
            </a>
          </el-col>
          <el-col class="nav" :span="16">
              <el-row>
                <el-col :span="3"><router-link class="current" to="/course">免費課</router-link></el-col>
                <el-col :span="3"><router-link to="/">輕課</router-link></el-col>
                <el-col :span="3"><router-link to="/">學位課</router-link></el-col>
                <el-col :span="3"><router-link to="/">題庫</router-link></el-col>
                <el-col :span="3"><router-link to="/">教育</router-link></el-col>
              </el-row>
          </el-col>
          <el-col class="login-bar" :span="5">
            <el-row v-if="token">
              <el-col class="cart-ico" :span="9">
                <router-link to="">
                  <b class="goods-number">0</b>
                  <img class="cart-icon" src="@/assets/cart.svg" alt="">
                  <span><router-link to="/cart">購物車</router-link></span>
                </router-link>
              </el-col>
              <el-col class="study" :span="8" :offset="2"><router-link to="">學習中心</router-link></el-col>
              <el-col class="member" :span="5">
                <el-menu class="el-menu-demo" mode="horizontal">
                  <el-submenu index="2">
                    <template slot="title"><router-link to=""><img src="@/assets/logo@2x.png" alt=""></router-link></template>
                    <el-menu-item index="2-1">個人帳戶</el-menu-item>
                    <el-menu-item index="2-2">個人訂單</el-menu-item>
                    <el-menu-item index="2-3">個人優惠卷</el-menu-item>
                    <el-menu-item index="2-3">退出登陸</el-menu-item>
                  </el-submenu>
                </el-menu>
              </el-col>
            </el-row>
            <el-row v-else>
              <el-col class="cart-ico" :span="9">
                <router-link to="">
                  <img class="cart-icon" src="@/assets/cart.svg" alt="">
                  <span><router-link to="/cart">購物車</router-link></span>
                </router-link>
              </el-col>
              <el-col :span="10" :offset="5">
                <span class="register">
                  <router-link to="/login">登陸</router-link>
                  &nbsp;&nbsp;|&nbsp;&nbsp;
                  <router-link to="/register">註冊</router-link>
                </span>
              </el-col>
            </el-row>
          </el-col>
        </el-row>
      </el-header>
    </el-container>
  </div>
</template>

<script>
  export default {
    name: "Header",
    data(){
      return {
        // 設置一個登陸標識,表示是否登陸
        token: false,
      };
    }
  }
</script>

<style scoped>
  .header{
    top:0;
    left:0;
    right:0;
    margin: auto;
    background-color: #fff;
    height: 80px;
    z-index: 1000;
    position: fixed;
    box-shadow: 0 0.5px 0.5px 0 #c9c9c9;
  }
  .header .el-container{
    width: 1200px;
    margin: 0 auto;
  }
  .el-header{
    height: 80px!important;
    padding:0;
  }
  .logo{

  }
  .logo img{
    padding-top: 22px;
  }

  .nav{
    margin-top: 22px;
  }

  .nav .el-col a{
    display: inline-block;
    text-align: center;
    padding-bottom: 16px;
    padding-left: 5px;
    padding-right: 5px;
    position: relative;
    font-size: 16px;
    margin-left: 20px;
  }

  .nav .el-col .current{
    color: #4a4a4a;
    border-bottom: 4px solid #ffc210;
  }

  .login-bar{
    margin-top: 22px;
  }
  .cart-ico{
    position: relative;
    border-radius: 17px;
  }
  .cart-ico:hover{
    background: #f0f0f0;
  }
  .goods-number{
    width: 16px;
    height: 16px;
    line-height: 17px;
    font-size: 12px;
    color: #fff;
    text-align: center;
    background: #fa6240;
    border-radius: 50%;
    transform: scale(.8);
    position: absolute;
    left: 16px;
    top: -1px;
  }
  .cart-icon{
    width: 15px;
    height: auto;
    margin-left: 6px;
  }
  .cart-ico span{
    margin-left: 12px;
  }
  .member img{
    width: 26px;
    height: 26px;
    border-radius: 50%;
    display: inline-block;
  }
  .member img:hover{
    border: 1px solid yellow;
  }

</style>
View Code

建立輪播圖

components/common/Bannner.vue

<template>
  <div class="banner">
      <el-carousel trigger="click" height="473px">
        <el-carousel-item v-for="banner in banner_list">
          <a :href="banner.link"><img width="100%" :src="banner.img" alt=""></a>
        </el-carousel-item>
      </el-carousel>
  </div>
</template>

<script>
  export default {
    name:"Banner",
    data(){
      return {
        banner_list:[
          {link:"http://www.baidu.com",img:"/static/banner/1.png"},
          {link:"http://www.baidu.com",img:"/static/banner/2.png"},
          {link:"http://www.baidu.com",img:"/static/banner/3.png"},
        ]
      };
    }
  }
</script>

<style>
.el-carousel__arrow{
  width: 100px!important;
  height: 100px!important;
}
.el-icon-arrow-left{
  font-size: 35px;
  margin-left: 50px;
}
.el-carousel__arrow--left{
  left: -50px;
}
</style>
View Code

建立腳步頁面

<template>
  <div class="footer">
    <el-container>
      <el-row>
        <el-col :span="4"><router-link to="">關於咱們</router-link></el-col>
        <el-col :span="4"><router-link to="">聯繫咱們</router-link></el-col>
        <el-col :span="4"><router-link to="">商務合做</router-link></el-col>
        <el-col :span="4"><router-link to="">幫助中心</router-link></el-col>
        <el-col :span="4"><router-link to="">意見反饋</router-link></el-col>
        <el-col :span="4"><router-link to="">新手指南</router-link></el-col>
        <el-col :span="24"><p class="copyright">Copyright © luffycity.com版權全部 | 京ICP備17072161號-1</p></el-col>
      </el-row>
    </el-container>
  </div>
</template>

<script>
  export default {
    name:"Footer",
    data(){
      return {}
    }
  }
</script>


<style scoped>
.footer{
  width: 100%;
  height: 128px;
  background: #25292e;
}
.footer .el-container{
  width: 1200px;
  margin: auto;
}
.footer .el-row {
  align-items: center;
  padding: 0 200px;
  padding-bottom: 15px;
  width: 100%;
  margin-top: 38px;
}
.footer .el-row a{
  color: #fff;
  font-size: 14px;
}
.footer .el-row .copyright{
  text-align: center;
  color: #fff;
  font-size: 14px;
}
</style>
View Code

爲了讓代碼不會過於關聯,也能夠把App.vue中的style標籤的css代碼放在statics外部目錄下引用過來

statics/css/reset.css中

body,h1,h2,h3,h4,h5,ul,p{
    padding: 0;
    margin:0;
    font-weight: normal;
  }
  body{
    margin-top: 80px;
  }
  a{
    text-decoration: none;
    color: #4a4a4a;
  }
  a:hover{
    color: #000;
  }

  ul{
    list-style: none;
  }

  img{
    width: 100%;
  }

  .header .el-menu li .el-submenu__title{
    height: 26px!important;
    line-height: 26px!important;
  }
  .el-menu--popup{
    min-width: 140px;
  }
  .el-checkbox__inner{
    width:16px;
    height: 16px;
    border: 1px solid #999;
  }
  .el-checkbox__inner:after{
    width: 6px;
    height: 8px;
  }
  .el-form-item__content{
    margin-left:0px!important;
    width: 120px;
  }
View Code

在main.js中調用這個文件

import "../static/css/reset.css";

6. 跨域CORS

咱們在作不少的項目時,咱們的前端和後端項目是分開的,因此咱們須要解決兩個項目之間的隔絕關係,讓兩個項目的數據實現互通,這就是跨域

咱們如今爲前端和後端分別設置兩個不一樣的域名:

位置 域名
前端 www.luffycity.cn
後端 api.luffycity.cn

   

這個在命令行中代開/etc/hosts文件,能夠設置本地域名

sudo vim /etc/hosts
在文件中增長兩條信息
127.0.0.1   localhost
127.0.0.1   api.luffycity.cn
127.0.0.1   www.luffycity.cn

經過瀏覽器訪問前端vue項目,會出現nginx的歡迎頁面,主要由於咱們當前項目已經有一個nginx監聽了80端口,因此訪問www.luffycity.cn網址時,會自動被轉發到127.0.0.1本機,由於沒有網址默認端口是80端口,因此被nginx進行處理了當前請求,所以咱們暫時先把nginx關閉先。

# 查找nginx的進程
ps -ef|grep nginx
# 關閉進程
sudo kill -9 nginx進程號

關閉了nginx之後,訪問www.luffycity.cn網址,效果:

 

 

上面並非錯誤,而是沒人監聽了這個地址和端口了,解決方法:

暫停運行前端項目,並修改配置文件config/index.js

保存修改信息,並重啓項目

    host: 'www.luffycity.cn', // can be overwritten by process.env.HOST
    port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
    autoOpenBrowser: true,

經過瀏覽器訪問drf項目,會出現如下錯誤信息

 

這是須要在後端的項目中修改配置文件

能夠經過settings/dev.py的ALLOWED_HOSTS,設置容許訪問

# 設置哪些客戶端能夠經過地址訪問到後端
ALLOWED_HOSTS = [
    'api.luffycity.cn',
]

讓用戶訪問的時候,使用api.luffycity.cn:8000

1. 修改pycharm的manage.py的配置參數


如今,前端與後端分處不一樣的域名,咱們須要爲後端添加跨域訪問的支持

不然前端沒法使用axios沒法請求後端提供的api數據,咱們使用CORS來解決後端對跨域訪問的支持。

使用django-cors-headers擴展

文檔:https://github.com/ottoyiu/django-cors-headers/

安裝

pip install django-cors-headers

添加應用  在dev.py文件中

INSTALLED_APPS = (
    ...
    'corsheaders',
    ...
)

中間層設置【必須寫在第一個位置】

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    ...
]

添加白名單

# CORS組的配置信息
CORS_ORIGIN_WHITELIST = (
    'www.luffycity.cn:8080'
)
CORS_ALLOW_CREDENTIALS = True  # 容許ajax跨域請求時攜帶cookie

完成了上面的步驟,咱們就能夠經過後端提供數據給前端使用ajax訪問了。

前端使用 axios就能夠訪問到後端提供給的數據接口,可是若是要附帶cookie信息,前端還要設置一下。

前端引入axios插件並配置容許axios發送cookie信息[axios自己也不容許ajax發送cookie到後端

npm i axios -S

在main.js中引用 axios插件

import axios from 'axios'; // 從node_modules目錄中導入包
// 容許ajax發送請求時附帶cookie
axios.defaults.withCredentials = true;

Vue.prototype.$axios = axios; // 把對象掛載vue中

 

 

 

 

 

 

相關文章
相關標籤/搜索