VUE創建項目



Vue Cli項目搭建

vue項目需要自建服務器:node

什么是node:

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

一、環境搭建

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

2、裝完了后在cmd輸入node即可啟動一個命令行交互環境,運行javascript代碼

       

3、可以更換國內源,加速下載:npm install -g cnpm --registry=https://registry.npm.taobao.org

      在更換源后,所有的npm命令都可以替換為cnpm。

      改完后npm的源還是國外的源,cnpm的源是淘寶的源。

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

      cnpm install -g @vue/cli

5、安裝腳手架報錯的時候,需要清空緩存處理

      npm cache clean --force

二、項目創建

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

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

          

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

          

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

        勾選Babel、Router、Vuex、Formatter

        Babel :jsES6語法轉換ES5

        Router:路由

        Vuex:組件數據交互

        Formatter:格式化代碼

       

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

    

安裝完后的目錄如下:

 

 三、終端啟動項目

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

四、pycharm配置

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

接着需要指定json文件,運行的腳本等。項目名可以起也可以不起。

 

 上面配置完成后,即可在pycharm啟動項目。 

我們把上面的項目可以當作一個模板,以后有需要,直接就把除了node_modules的其他文件夾及文件全部復制到新項目

然后再到相應的目錄下執行:cnpm install

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

五、項目目錄

來看一下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.1、在根組件中渲染頁面組件

我們要在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.2、路由:單頁面實現頁面之間轉跳

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

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.3、前后台交互(基於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')


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM