VUE建立項目


Vue Cli項目搭建

vue項目須要自建服務器:nodejavascript

什麼是node:html

  • 用C++語言編寫,用來運行JavaScript語言
  • node能夠爲前端項目提供server (包含了socket)

1、環境搭建

一、官網下載安裝包,傻瓜式安裝:https://nodejs.org/zh-cn/前端

二、裝完了後在cmd輸入node便可啓動一個命令行交互環境,運行javascript代碼vue

       

三、能夠更換國內源,加速下載:npm install -g cnpm --registry=https://registry.npm.taobao.orgjava

      在更換源後,全部的npm命令均可以替換爲cnpm。node

      改完後npm的源仍是國外的源,cnpm的源是淘寶的源。python

四、安裝vue cli環境:腳手架,命令行快速建立項目webpack

      cnpm install -g @vue/cliios

五、安裝腳手架報錯的時候,須要清空緩存處理es6

      npm cache clean --force

2、項目建立

以管理員的身份運行cmd ,不然可能出現一些沒必要要的麻煩

  1. 首先cd切換到目標目錄
  2. 執行:vue create 項目名
  3. 選擇自定義方式建立項目,選取Router, Vuex插件
  4. 選擇第二個進入自定義配置:

          

    5. 執行時,會提示下載源,選擇淘寶鏡像便可。(有大寫的選大寫,大寫是建議的選項)

          

    6. 具體配置:上下鍵切換,空格鍵選擇,回車鍵進入下一步

        勾選Babel、Router、Vuex、Formatter

        Babel :jsES6語法轉換ES5

        Router:路由

        Vuex:組件數據交互

        Formatter:格式化代碼

       

       下一步選Y,接下來的配置都是提示選項有大寫選大寫,沒有默認選第一個配置就行

    

安裝完後的目錄以下:

 

 3、終端啓動項目

  1. cd到你的項目:cd vue_proj
  2. npm run serve
  3. 訪問:http://localhost:8080/ 

4、pycharm配置

  • 在使用pycharm開發時,打開後,vue文件會有提示須要安裝插件,直接點擊下載便可。
  • 若是沒有提示,那麼就要在settings的plugins裏面搜索vue.js插件,而後安裝。
  • 安裝完後須要重啓ide。
  • 若是命令行啓動的,在你更改一些代碼後,頁面沒有刷新,這時候在命令行按ctrl+c就能夠刷新。可是連續在命令行按兩次ctrl+c就會提示你是否退出,選擇退出或不退就行。
  • 須要在pycharm配置npm啓動項:先點擊下拉菜單的Edit,而後點擊小+號,選擇npm

接着須要指定json文件,運行的腳本等。項目名能夠起也能夠不起。

 

 上面配置完成後,便可在pycharm啓動項目。 

咱們把上面的項目能夠看成一個模板,之後有須要,直接就把除了node_modules的其餘文件夾及文件所有複製到新項目

而後再到相應的目錄下執行:cnpm install

這樣,就會根據電腦環境,項目需求從新下載依賴(node_modules)了。

5、項目目錄

來看一下main.js主腳本文件:

import Vue from 'vue'
//./表明的是相對路徑
 import App from './App.vue'
//我能夠把它改爲下面的形式,@就表明src的絕對路徑
//@後就能夠採用相對於src的相對路徑
import App from '@/App.vue'
import router from './router'
import store from './store'
//這個是禁用提示,好比你第一次下載某個app,剛進去會有操做指南
Vue.config.productionTip = false;
//下面是ES6的寫法
// new Vue({
// router,
// store,
// render: h => h(App)
// }).$mount('#app');
//改爲ES5的看看
new Vue({
el: '#app',
router: router,
store: store,
render: function (h) {
return h(App)
}
});

 

 

.vue文件

router.js的路由配置部分:

 
{
path: '/',
name: 'home',
// 路由的重定向
redirect: '/home'
}
{
// 一級路由, 在根組件中被渲染, 替換根組件的<router-view/>標籤
path: '/one-view',
name: 'one',
component: () => import('./views/OneView.vue')
}
{
// 多級路由, 在根組件中被渲染, 替換根組件的<router-view/>標籤
path: '/one-view/one-detail',
component: () => import('./views/OneDetail.vue'),
// 子路由, 在所屬路由指向的組件中被渲染, 替換該組件(OneDetail)的<router-view/>標籤
children: [{
path: 'show',
component: () => import('./components/OneShow.vue')
}]
}

 

<router-link to="/">Home</router-link>        router-link渲染爲a標籤

store.js:vuex

 

// 在任何一個組件中,都可以經過this.$store.state.msg訪問msg的數據

// state永遠只能擁有一種狀態值
state: {
msg: "狀態管理器"
},
// 讓state擁有多個狀態值
mutations: {
// 在一個一個組件中,都可以經過this.$store.commit('setMsg', new_msg)來修改state中的msg
setMsg(state, new_msg) {
state.msg = new_msg
}
},
// 讓mutations擁有多個狀態值
actions: {
}

 

 

 6、案例

6.一、在根組件中渲染頁面組件

咱們要在views中建立一個Main.vue,用來做爲主頁:

<template>
<div class="main">
<h1>{{ title }}</h1>
</div>
</template>
<script>
export default {
name: "Main",
data:function () {
return{
title:'主頁'
}
}
}
</script>
<!-- 局部的要寫scoped-->
<style scoped>
.main {
/*vh:相對於視窗的高度,那麼vw:則是相對於視窗的寬度*/
height: 100vh; /*100vh表明網頁撐滿一個屏*/
background-color: orange;
}
h1 {
margin: 0; /*去除h1標籤自帶的margin邊距*/
color: red;
}
</style>

 

接下來咱們要考慮的就是如何在頁面中顯示它,怎麼現實呢?這時候就要到App.vue文件中去註冊渲染。

 

 
<template>
<div id="app">
<!--3:註冊完的組件就能夠在這裏用了-->
<Main></Main>
</div>
</template>
<script>
// 1:要渲染主頁的內容,首先要在邏輯中導入
import Main from '@/views/Main'
export default {
//2:導入的是局部組件,須要註冊
components:{
Main:Main
}
}
</script>
<!-- 根組件這裏不用寫scoped-->
<style>
html, body {
margin: 0;
}
</style>

 

 

 

 

 

  1. 6.二、路由:單頁面實現頁面之間轉跳

先來準備三個文件(局部組件):

Main.vue

 
<template>
<div class="main">
<h1>{{ title }}</h1>
</div>
</template>
<script>
export default {
name: "Main",
data:function () {
return{
title:'主頁'
}
}
}
</script>
<!-- 局部組件要寫scoped-->
<style scoped>
.main {
/*vh:相對於視窗的高度,那麼vw:則是相對於視窗的寬度*/
height: 100vh; /*100vh表明網頁撐滿一個屏*/
background-color: orange;
}
h1 {
margin: 0; /*去除h1標籤自帶的margin邊距*/
color: red;
}
</style>

 

 

User.vue

 
<template>
<!--類名通常就是文件名小寫-->
<div class="user">
<h1>我的頁</h1>
</div>
</template>
<script>
export default {
name: "User"
}
</script>
<style scoped>
</style>

 

 

Goods.vue

 

 
<template>
<div class="goods">
<h1>商品頁</h1>
</div>
</template>
<script>
export default {
name: "Goods"
}
</script>
<style scoped>
.goods {
height: 100vh;
background-color: blue;
}
</style>

 

 

 

 

 

 

接下來要到router.js中註冊

 

 
import Vue from 'vue'
import Router from 'vue-router'
//導入
import Goods from './views/Goods'
import User from './views/User'
import Main from './views/Main'
Vue.use(Router);
export default new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
//註冊
{
path: '/',
name: 'main',
component: Main
},
{
path: '/goods',
name: 'goods',
component: Goods
},
{
path: '/user',
name: 'user',
component: User
},
]
})

 

 

 

 

 

 

最後到App.vue中調用:<router-view /> <!--至關於每一個頁面要渲染的內容-->

 
<template>
<div id="app">
<!--註冊完的組件就能夠在這裏用了-->
<ul class="nav">
<li>
<router-link to="/">主頁</router-link>
</li>
<li>
<router-link to="/goods">商品頁</router-link>
</li>
<li>
<router-link to="/user">我的頁</router-link>
</li>
</ul>
<router-view />
</div>
</template>
<script>
export default {
}
</script>
<!-- 根組件這裏不用寫scoped-->
<style>
html, body,ul,h1 {
margin: 0;
}
.nav {
height: 60px;
background-color: #d2a1ab;
}
.nav li{
list-style: none;
float: left;
/*垂直居中*/
line-height: 60px;
width: 120px;
/*水平居中*/
text-align: center;
}
.nav li:hover{
background-color: aqua;
}
.nav li a{
/*去掉a標籤的下劃線*/
text-decoration: none;
/*字體大小及樣式*/
font: bold 20px/60px 'STSong';
}
ul {
list-style: none;
}
</style>

 

 

至此就實現了單頁面的局部組件切換了。

  1. 6.三、先後臺交互(基於6.2的頁面Goods)

 上面咱們已經實現了單頁面的切換,那麼咱們確定每一個頁面都要到後臺拿數據,好比我點擊商品頁後就要動態從數據庫獲取信息,而後展現到前端頁面,這就涉及到了先後臺的交互問題。 

咱們以Goods爲例來看一下生命週期鉤子

  1. 鉤子表示一個vue實例從建立到銷燬的這個過程,將這個過程的一些時間節點賦予了對應的鉤子函數
  2. 鉤子函數: 知足特色條件被回調的方法

咱們在Goods.vue的script中加入鉤子

 當點擊商品頁時,會觸發鉤子:

 瞭解了這個,下面咱們以django做爲後臺,來實現如下交互

由於交互是vue本身完成的,咱們拿不到csrf的認證字符串,因此直接去配置文件中把這個中間件註釋掉。

而後咱們經過axios向後臺發請求。

注意,在先後臺交互的時候,會產生跨域的問題

  1. 什麼是跨域問題?

一般狀況下,A網頁訪問B服務器資源時,不知足如下三個條件其一就是跨域訪問
1. 協議不一樣
2. 端口不一樣
3. 主機不一樣

  1. django解決跨域問題: 

安裝django-cors-headers模塊

在settings.py中配置
# 註冊app
INSTALLED_APPS = [
    ...
    'corsheaders'
]
# 添加中間件
MIDDLEWARE = [
    ...
    'corsheaders.middleware.CorsMiddleware'
]
# 容許跨域源
CORS_ORIGIN_ALLOW_ALL = True

 而後前端vue這邊須要安裝axios(ajax):

cnpm install axios --save

接着要去main.js裏對axios進行全局配置:

import Axios from 'axios'

Vue.prototype.$ajax = Axios;
//配置完後在任何地方都能經過this.$ajax拿到它

 

 具體的Goods的代碼以下:

 
<template>
<div class="goods">
<h1>商品頁</h1>
<h2>{{ msg }}</h2>
</div>
</template>
<script>
export default {
name: "Goods",
data:function(){
return {
msg: '123'
}
},
beforeCreate () {
window.console.log("開始建立Goods組件");
},
created () {
window.console.log("Goods組件建立成功, data, methods已擁有");
},
mounted () {
window.console.log("頁面已被vue實例渲染, data, methods已更新");
//咱們選擇渲染完成後拿數據
//請求後臺
let _this = this;
this.$ajax({
url:'http://127.0.0.1:8000/goods/',
method:'post',
params:{
info:'前臺數據'
}
}).then(function (result) { //then就是回調函數,至關於ajax的success
// this表明的是回調then這個方法的調用者(axios插件),也就是發生了this的重指向
// 要更新頁面的title變量,title屬於vue實例
// res爲回調的對象,該對象的data屬性就是後臺返回的數據
let data = result.data;
//this指向的是then的function,咱們前面定義的_this纔是全局
_this.msg = data;
})
}
}
</script>
<style scoped>
.goods {
height: 100vh;
background-color: blue;
}
</style>

 

 

後臺的視圖函數:

 
def goods(request):
print(request.method)
# axios的請求,原生Django都在GET字典中拿前臺數據
print(request.GET)
print(request.POST)
return HttpResponse('後臺數據')

 

 

 

閱讀目錄

Vue項目開發:

先後端徹底分離

後端:提供接口數據

前端:頁面轉跳、頁面佈局、頁面數據渲染所有由前端作

中間交互:請求

搭建Vue項目環境:

Vue項目須要自建服務器:node

node介紹:

1.用C++語言編寫,用來運行JavaScript語言
2.node能夠爲前端項目提供server (包含了socket)

node下載安裝:https://nodejs.org/zh-cn/

一路點擊下一步就能夠。

npm:包管理器 - 爲node拓展功能的

# 換國內源,加速下載,經過命令行換源:
# 管理員命令行:npm install -g cnpm --registry=https://registry.npm.taobao.org
# MacOS: sudo npm install -g cnpm --registry=https://registry.npm.taobao.org

# 索引npm的指令均可以換成cnpm
# npm install vuex => cnpm install vuex

vue cli環境:腳手架 - 命令行快速建立項目

# cnpm install -g @vue/cli

# 若是報錯:npm cache clean --force

建立Vue項目

起步
1.cd 到目標目錄
2.建立項目:vue create 目錄名

建立項目的過程
提示下載原:選擇淘寶鏡像

具體配置:上下鍵切換,空格鍵選擇,回車鍵進入下一步
1.第二個選項進入自定義配置

2.Babel jsES6語法轉換ES5,Router路由 Vuex組件數據交互 Formatter格式化代碼

3...有提示選擇大寫,沒提示默認第一個便可
選y

開始下載:

啓動項目

兩種啓動方式:

①終端啓動
1.進入項目:cd到項目目錄
2.啓動項目:npm run serve

 ②pycharm配置啓動
1.安裝vue.js插件,重啓
2.配置項目的npm啓動項
3.啓動node搭建的socket

若是項目環境搭建失敗,能夠將搭建成功的項目中的相關文件及文件夾:

而後打開管理員打開cmd命令

cd e:\vue-proj進入項目文件目錄下

cnpm install  對本身電腦的當前環境進行從新安裝依賴,重構項目環境,這樣就能夠用了,使用pycharm打開該文件夾就好了

該方法能夠用於快速建立和搭建項目環境使用,這樣就不用每次vue create進行下一步下一步了

項目目錄

打開main.js

 修改後按ctrl+s保存後頁面會實時刷新,且文件後綴均可以省略不寫

 

頁面組件開發

組件建立:

 建立新組件以後的基本頁面狀況:

複製代碼
<template>
    <!-- 只能有一個根標籤 -->
</template>

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

<style scoped>
    /* scoped  可讓樣式實現局部化*/
    /* 若是讓樣式實現全局化,則應該寫在根組件樣式中*/
</style>
複製代碼

 組件渲染

複製代碼
<!-- Main.vue 主頁組件 -->
<template>
    <div class="main">
        <h1>{{ title }}</h1>
    </div>
</template>

<script>
    export default {
        name: "Main",
        data:function () {
            return {
                title:'主頁'
            }
        }
    }
</script>

<style scoped>
    .main {
        height: 100vh;
        background-color: beige;
    }
    h1 {
        margin: 0;
        color: darkred;
    }
</style>
複製代碼
複製代碼
<!-- App.vue根組件 -->
<template>
  <div id="app">
    <Main></Main>

  </div>
</template>

<script>
  import Main from '@/views/Main'
  export default {
      components:{
        Main:Main
      }
  }
</script>

<style>
  html, body {
      margin: 0;
  }
</style>
複製代碼

說明:

路由:router.js

在根組件中設計轉跳頁面的導航欄

複製代碼
<template>
  <div id="app">
    <ul class="nav">
      <li>主頁</li>
      <li>商品頁</li>
      <li>我的頁</li>
    </ul>
  </div>
</template>

<script>
  import Main from '@/views/Main'
  export default {
      components:{
        Main:Main
      }
  }
</script>

<style>
  .nav {
    height: 60px;
    background-color: silver;
  }
  .nav li {
    float: left;
    height: 60px;
    width: 123px;
    text-align: center;
    line-height: 60px;
  }
  .nav li:hover {
    background-color: aquamarine;
  }

  html, body, ul {
      margin: 0;
  }
  ul {
    list-style: none;
  }
</style>
複製代碼

建立三個頁面組件

複製代碼
<!--Main.vue-->
<template>
    <div class="main">
        <h1>{{ title }}</h1>
    </div>
</template>

<script>
    export default {
        name: "Main",
        data:function () {
            return {
                title:'主頁'
            }
        }
    }
</script>
<style scoped>
    .main {
        height: 100vh;
        background-color: beige;
    }
    h1 {
        margin: 0;
        color: darkred;
    }
</style>
複製代碼
複製代碼
<!--Goods.vue-->
<template>
    <div class="goods">
        <h1>商品頁</h1>
    </div>
</template>

<script>
    export default {
        name: "Goods"
    }
</script>

<style scoped>

</style>
複製代碼
複製代碼
<!--User.vue-->
<template>
    <div class="user">
        <h1>我的頁</h1>
    </div>
</template>

<script>
    export default {
        name: "User"
    }
</script>

<style scoped>

</style>
複製代碼

配置路由(router.js中)

複製代碼
import Vue from 'vue'
import Router from 'vue-router'
import Main from '@/views/Main.vue'
import Goods from '@/views/Goods.vue'
import User from '@/views/User.vue'

Vue.use(Router)

export default new Router({
    mode: 'history',
    base: process.env.BASE_URL,
    routes: [
        {
            path: '/',
            name: 'main',
            component: Main
        },
        {
            path: '/goods',
            name: 'goods',
            component: Goods
        },
        {
            path: '/user',
            name: 'user',
            component: User
        },
        //第二種方式
        // {
        //   path: '/about',
        //   name: 'about',
        //   // route level code-splitting
        //   // this generates a separate chunk (about.[hash].js) for this route
        //   // which is lazy-loaded when the route is visited.
        //   component: () => import(/* webpackChunkName: "about" */ './views/About.vue')
        // }
    ]
})
複製代碼

根組件中:

複製代碼
<template>
  <div id="app">
    <ul class="nav">
      <li>
        <router-link to="/">主頁</router-link>
      </li>
      <li>
        <router-link to="/goods">商品頁</router-link>
      </li>
      <li>
        <router-link to="/user">我的頁</router-link>
      </li>
    </ul>
    <!--<router-view></router-view>-->
    <router-view/>
  </div>
</template>

<script>
  import Main from '@/views/Main'
  export default {
      components:{
        Main:Main
      }
  }
</script>

<style>
  .nav {
    height: 60px;
    background-color: silver;
  }
  .nav li {
    float: left;
    height: 60px;
    width: 123px;
    text-align: center;
    line-height: 60px;
  }
  .nav li:hover {
    background-color: aquamarine;
  }

  html, body, ul, h1 {
      margin: 0;
  }
  ul {
    list-style: none;
  }
  a {
    text-decoration: none;
    font: bold 20px/60px 'STSong';
  }
</style>
複製代碼

先後臺交互

axios

// 安裝 axios(ajax)的命令
// npm install axios --save
// 爲項目配置全局axios(main.js中)
import Axios from 'axios'
Vue.prototype.$ajax = Axios

goods組件中設置ajax給後臺發送數據(在組件渲染完畢時候發送)

複製代碼
<!--Goods.vue-->
<template>
    <div class="goods">
        <h1>商品頁</h1>
    </div>
</template>
<script>
    export default {
        name: "Goods",
        beforeCreate() {
            window.console.log("開始建立Goods組件");
        },
        created() {
            window.console.log("建立Goods組件完畢");
        },
        mounted() {
            window.console.log("Goods組件渲染完畢");
            // 請求後臺
            this.$ajax({
                method:'post',
                url:'http://127.0.0.1:8000/goods/',
                params:{
                    info:'前臺數據'
                }

            }).then(function (res) {
                window.console.log(res)
            })
        }
    }

</script>
<style scoped>

</style>
複製代碼

 新建一個Django項目,做爲後臺接收、返回數據

 settings.py中手動將csrf中間件註釋掉(這裏須要注意真正項目中先後端分離時,Django的csrf中間件時經過代碼層面禁用並手寫安全認證,這裏註釋掉主要方便咱們測試)

路由配置:

複製代碼
from django.conf.urls import url
from django.contrib import admin
from app01 import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^goods/', views.goods),
]
複製代碼

 視圖函數

複製代碼
def goods(request):
    print(request.method)
    print(request.POST)
    print(request.GET)

    return HttpResponse('後臺數據')
複製代碼

 發現跨域問題:後臺能收到前臺發送的請求數據,可是因爲跨域問題,只要前臺端給後端發送數據,後端都會接收,來者不拒,可是因爲跨域問題,致使Django不認識它,因此

不給它返回數據。

複製代碼
## Django跨域問題

#### 什麼是跨域

```python
'''
一般狀況下,A網頁訪問B服務器資源時,不知足如下三個條件其一就是跨域訪問
1. 協議不一樣
2. 端口不一樣
3. 主機不一樣
'''
```

#### Django解決跨域

```python
'''
安裝django-cors-headers模塊

在settings.py中配置
# 註冊app
INSTALLED_APPS = [
    ...
    'corsheaders'
]
# 添加中間件
MIDDLEWARE = [
    ...
    'corsheaders.middleware.CorsMiddleware'
]
# 容許跨域源
CORS_ORIGIN_ALLOW_ALL = True
'''
```
複製代碼

 解決跨域:

①在pycharm中安裝django-cors-headers

②在Django配置文件中:

 

 而後前端進行處理數據:

這樣渲染msg後發現報錯:

發現msg沒有被定義,可是在data中明明已經定義了msg,因此錯誤不在data中,最後發如今then的回調函數中的this

問題解析:

① 在this.ajax上先聲明個變量_this=this將vue實例存起來,而後在then的回調函數中打印this和_this

從以上結果來看,在生命週期鉤子函數下的this指向的是當前建立的vue實例,而在這些函數內部使用例如axios與後臺交互後回調函數的內部的this並不是指向當前的vue實例;

若想拿到後臺回傳的數據更新data裏的數據,不能在回調函數中直接使用this,而要用在外部函數定義的變量存儲的this,也就是當前vue的實例。
以上是一種解決方式,這裏再補充另外一種解決方法:使用es6語法箭頭函數自動解決此類問題:

 

箭頭函數至關於匿名函數,而且簡化了函數定義。看上去是匿名函數的一種簡寫,但實際上,箭頭函數和匿名函數有個明顯的區別:箭頭函數內部的this是詞法做用域,由上下文肯定。此時this在箭頭函數中已經按照詞法做用域綁定了。很明顯,使用箭頭函數以後,箭頭函數指向的函數內部的this已經綁定了外部的vue實例了.

 vue-cookie

複製代碼
// 安裝cookie的命令
// npm install vue-cookie --save
// 爲項目配置全局vue-cookie(在main.js中)
import VueCookie from 'vue-cookie'
// 將插件設置給Vue原型,做爲全局的屬性,在任何地方均可以經過this.$cookie進行訪問
Vue.prototype.$cookie = VueCookie
複製代碼
// 持久化存儲val的值到cookie中
this.$cookie.set('val', this.val)
// 獲取cookie中val字段值
this.$cookie.get('val')
相關文章
相關標籤/搜索