后端小白的VUE入門筆記, 進階篇


使用 vue-cli( 腳手架) 搭建項目

基於vue-cli 創建一個模板項目
通過 npm root -g 可以查看vue全局安裝目錄,進而知道自己有沒有安裝vue-cli

如果沒有安裝的話,使用如下命令全局安裝
cnpm install -g vue-cli

創建一個基於webpack的新項目,在這過程中, 會安裝依賴
vue init webpack 項目名

啟動
cd vue-router-demo
npm start

常用的目錄結構

如果我們的項目是通過腳手架搭建的,這已經是一個比較完善的種子項目了

|-- build : webpack 相關的配置文件夾(基本不需要修改)
|-- config: webpack 相關的配置文件夾(基本不需要修改)
|-- index.js: 指定的后台服務的端口號和靜態資源文件夾
|-- node_modules: 在上面安裝的依賴,都存放在這個文件夾下
|-- src : 源碼文件夾,我們后續開發的組件和js分門別類的放在這里面
|-- main.js: 應用入口 js
|-- static: 靜態資源文件夾
|-- .babelrc: babel 的配置文件
|-- .editorconfig: 通過編輯器的編碼/格式進行一定的配置
|-- .eslintignore: eslint 檢查忽略的配置
|-- .eslintrc.js: eslint 檢查的配置
|-- .gitignore: git 版本管制忽略的配置
|-- index.html: 主頁面文件
|-- package.json: 他就相當於maven的pom.xml, 里面存放着相關的依賴信息和項目的版本信息
|-- README.md: 應用描述說明的 readme 文件

配置config/index.js

可以在config/index.js中做一下的常用配置

  • 添加跨域的配置
  • 配置項目的主機名,端口號
  • 配置是否打開瀏覽器
  • 代碼檢查工具eslint

在開發的時候我們主要還是關注src文件, 后來需要的路由,store,ajaxApi,以及其他組件全部在創建在這個文件夾下

const path = require('path')
module.exports = {
  dev: {

    // Paths
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',
    proxyTable: {}, //添加跨域的配置

    // Various Dev Server settings
    host: 'localhost', // can be overwritten by process.env.HOST
    port: 9528, // 配置是否打開瀏覽器
    autoOpenBrowser: true,  //配置是否打開瀏覽器
    errorOverlay: true,
    notifyOnErrors: false,
    poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-

    // Use Eslint Loader?
    // If true, your code will be linted during bundling and
    // linting errors and warnings will be shown in the console.
    useEslint: false,
    // If true, eslint errors and warnings will also be shown in the error overlay
    // in the browser.
    showEslintErrorsInOverlay: false,

入口js文件 main.js的主要作用

  • 創建vue實例, 關聯index.html中id為app的div代碼塊
  • 添加項目中的路由模塊 router
  • 添加store模塊---vuex

一般做好這不配置之后main就不用再改動了

import App from './App'
import router from './router'
import store from './store'

Vue.use(ElementUI, { locale })

new Vue({
  el: '#app',
  router,
  store,
  template: '<App/>',
  components: { App }
})

根組件App.vue

其實每一個組件都可以完整的擁有下面三部分, 當然如果哪個組件中不需要添加css樣式,可以把最后一個style或者script標簽去掉

<template>
  <div>
   <!-- 這里存放 -->
  </div>
</template>

<//script>
export default {
  name: 'app'
}
<///script>

<style>
</style>

組件間的相互調用

比如根組件想使用hello.vue組件,怎么做呢?

像下面這樣,三步走

  • 第一步:引入組件
  • 第二步:將組件映射成target標簽
  • 第三步使用標簽
<template>
<div>
    <!--第三步使用標簽-->
    <hello/>  
<div/>
<template/>

<script>
 
import hello form './XXX/hello.vue'

export default{
    // 將組件映射成標簽
    components:{
        hello
    }
}

<style>
</style>

第二步中引入標簽時也可以去掉.vue后綴

或者直接這樣寫,是從@/ 代表的是 src/

import hello form '@/XXX/hello'

打包與發布

打包

  • 打包的命令:
npm run build

項目經過打包,產出是一個dist文件,里面分別是index.html 和 靜態資源文件夾, 這也是前后端分離開發的特色,后端想控制view層,也難了,只有一張index.html

發布方法1-靜態服務器工具包

命令:

npm install -g serve  // 安裝工具
serve dist 

發布方法2-使用tomcat服務器

注意點,使用tomcat當服務器,要求文件夾的名字和項目的名字要一樣,修改的步驟如下:

  • 修改/build/webpack_prod.conf.js文件
    output:{
        ...
        pathPath:'項目名稱'
    }
  • 編譯重新打包
npm run build
  • 把打包得到的dist文件夾改名,改成項目名
  • 將改名完事后的文件拷貝到tomcat的webapps目錄下,運行tomcat

eslint的編碼規范檢查

好的習慣就是使用它,規范自己的代碼風格, 但是也得說一下怎么禁用eslint'

  • 方法一: 通過如果是webstorm編譯器的話,點擊file/settings/ , 搜索eslint,可以去掉enable
  • 方法二: 編輯.eslintignore文件,添加自己想被忽略的文件
*.js
*.vue
一般我們就寫這兩部分,這一下子全忽略了

因為eslint有個莫名其妙的要求,代碼最后一行要求是空行,可以通過下面的方法三取消掉

  • 方法三: 編輯.eslintrc.js
rules:{
    ...
    // 添加
    'indent':0
}

父子組件之間數據交互

在差分組件的時候,本着多個組件共享的數據放在根組件的原則, 於是我們把共用的數據放在根組件,於此同時操作這些數據的方法也被我們定義在根組件,子組件想要使用這些數據,想要操作這些數組怎么辦呢? 像下面那樣,進行組件之間的數據傳遞

  • 在父組件中給子組件傳遞方法或數據

使用:強制數據綁定的方法, ChildTarget是我們在components模塊將子組件映射得來的子組件標簽, name可以是vue中data的方法,也可以是屬性

<template>
   <ChildTarget  :name="name"/>
</template>

  • 子組件取出父組件傳遞過來的值
export default{
    props:['name','name2']
}

數據的交互@click

最常用的就是使用@click="方法名", 或者@click="value = !value" 或者@click="value = true

如果我們向上面那樣, 把公共的數據放在父組件中, 那么事件的觸發一定是發生在子組件中, 子組件一般通過@click給模板中的元素綁定上指定的動作,進而調用父組件的傳遞進來的方法,操作父組件傳遞進來的值

此外,在所有的組件中,vue的data部分都向下面這樣寫,是規定

data(){
    return{
        name:''
    }
}
  • 常用的監視watch模塊
watch:{
    監視的data中的對象
    name:{
        deep:true, // 深度監視
        handler: function(value){ // value就是變化后的新的值
            // todo
        }
    }
}
  • 緩存模塊

從緩存中把去出來的字符串轉換成json串

JSON.parse(window.localStorage.getItem('')||'默認值');

把對象,存儲進瀏覽器的緩存

window.localStorage.setItem('自定義的key',JSON.stringfy(value))

消息訂閱,打破父子組件信息傳遞的約束

像上面那樣,如果不存在父子組件的關系,父組件不引入子組件,也就沒辦法把他映射成標簽, 既然映射不成標簽也就沒法像上面那樣,通過 : 冒號 強制進行數據的綁定達到傳遞值的效果,於是有了消息訂閱

組件之間的通信方式: 發布/訂閱

綁定監聽: 訂閱事件

觸發事件: 發布事件

借助插件-pubsub.js

安裝命令:

npm install --save pubsub-js

場景: 我們給模板上的按鈕綁定點擊事件,一旦被點解他就發布事件

  • 在使用前需要導入PubSub對象
import PubSub from 'pubsub-js'

使用:消息的發布

<button @click="search">Search</botton>

export default{
    methods:{
        search(name){
            // search是方法名
            // name 是攜帶的參數,沒參數就不用寫
            Publish.publish('search',name)
        }
    }
}

消息的訂閱:

  • 依然是第一步:引入PubSub對象
  • 編碼實現:
mounted: {
    PubSub.subscribe("search",(name)=>{
      // todo with name
});

異步請求

安裝插件axios

npm install axios --save
  • 在使用之間同樣是需要引入:
import axios from 'axios'

發送一個get請求

axios.get(url)
     .then(res=>{ 
         // todo with res
     })
     .catch(error){
         // todo
     }

路由:

vue是如何做到使后端乖乖交出view層的控制權的?,難道是直接使用window.location.href = url嗎?

其實學過路由才知道, 使用的是vue-router,一個官方提供的路由框架,可以使用我通過組合組件來組成應用程序,仰仗它的路由插件vue-router,我們輕松控制頁面的切換

我們要做的就是將組件components映射到routers,然后告訴vue-router到哪里去渲染他們

定義路由器

安裝插件

npm install vue-router --save

編碼,其實大家都會把關於路由的編碼單獨放到一個叫router的文件夾中,而且,它的編碼基本上是機械化的編碼,分為如下幾步

  • 引入Vue,VueRouter
  • 聲明Vue.use(VueRouter)
  • 引入路由組件
  • 對外暴露路由器對象,並且把路由組件配置進路由器對象

注意點 下面的配置部分, routes 不寫亂寫!!!

import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)

import Home from './Home.vue'
import About from './About.vue'
import Me from './Me.vue'


export default new VueRouter({
// 添加路由
routes:[
{
   path:'/home',
   component:Home,
   meta:{
       // 添加自定義的字段,可以當成flag,也可以文本
   }
},
{
   path:'/about',
   component:About,
   meta:{
       // 添加自定義的字段,可以當成flag,也可以文本
   },
   childred:[ // 嵌套路由
        { 
            path:'/about',
            component:About,
            meta:{
                  // 添加自定義的字段,可以當成flag,也可以文本
                 }
        }
   ]
   }
},
{
    path:'', // 默認訪問空的話,重定向到/home
    redirect:'/home'
}
]
})

使用路由進行頁面的跳轉

原來進行頁面的跳轉我們通常使用a標簽,(一般把a標簽設計成按鈕,或者導航欄的樣子,點擊發送請求,進而跳轉頁面了), 而vue的路由其實和a標簽差不多,我們使用vue的 router-link標簽替換a標簽

<router-link to:'/about' class="可以讓我看起來像按鈕的css樣式"> </router-link>
<router-link to:'/home' class="可以讓我看起來像按鈕的css樣式"> </router-link>

<router-view ></router-view>

這樣用戶點擊 router-link,就會把相應的子組件移植到 標簽塊中

補充:

屬性 類型 含義
to string | Location 表示目標路由的鏈接。當被點擊后,內部會立刻把 to 的值傳到 router.push(),所以這個值可以是一個字符串或者是描述目標位置的對象。
replace boolean 設置 replace 屬性的話,當點擊時,會調用 router.replace() 而不是 router.push(),於是導航后不會留下 history 記錄。
append boolean 設置 append 屬性后,則在當前(相對)路徑前添加基路徑。例如,我們從 /a 導航到一個相對路徑 b,如果沒有配置 append,則路徑為 /b,如果配了,則為 /a/b

回退到上一個路由

我們可以在按鈕上添加下面的動作,是路由回退一級

<button @click="$router.back()"></button>

緩存路由組件

使用如下標簽包裹我們的router-view,這樣當我們再回退到上一個路由時,用戶加進去的狀態依然存在

<keep-alive>
 <router-view ></router-view>
</keep-alive>

$router與$route

$router是路由器對象,說白了就是用它去跳轉頁面,美其名曰:編程式路由導航

$route是路由對象,說白了就是某一個路由對象,既然是某一個,就不能進行頁面的跳轉,相反是可以獲取出當前路由組件的屬性,它的結構圖如下:

$route的組成圖

$route的組成圖

向路由組件傳遞值 一

需求: 我們想發送這樣的請求 http:localhost:8080/home/1/羊肉串,在路徑上攜帶着參數1

路由怎么接收參數呢?--> 使用:占位


export default new VueRouter({
// 添加路由
routes:[
{
   path:'/home/:id/:type', // 如果想在路徑上傳遞值進來,就使用:占位
   component:Home,
   meta:{
       // 添加自定義的字段,可以當成flag,也可以文本
       flag:true
   }
},

當我們添加了/:之后,它的組成結構就變成了這個樣子

像下面這樣傳遞值進去,發起請求

<router-link to:`/home/${id}/${type}` class="可以讓我看起來像按鈕的css樣式"> </router-link>

同時,我們也可以向下面這樣使用$route. 在對應不同的路由組件中,把里面的屬性取出來, 注意啊,這樣取值,前提是我們前面使用 /:id占位,並且也整整傳遞值進去了

 <h1>id= {{$route.params.id}}</h1>

向路由組件傳遞值 二

使用<router-view >標簽傳遞值

 <router-view msg='abc'></router-view>

在路由組件中通過props取出值,然后可以直接使用

export default{
    props:[
      msg:String
    ]
}

編程式的路由導航

編程式的路由導航說白了就是,不用router-link標簽轉而使用代碼路由的跳轉唄, 舉個例子,我們使用手機qq,最下面有幾個導航欄,點擊不同的按鈕轉換到不同的頁面去,如果用編程式的路由導航就很好做

  • 第一步就是將需要的路由組件配置進路由器
  • 給按鈕綁定上點擊事件
  • 點擊事件觸發我們所謂的編程式路由導航

vue提供了兩種編程式的路由導航實現

  • 第一種:
    這種常用的一種
this.$router.replace(`/home/${id}`)
  • 第二種:
    這種具有棧的特性,也就是說,用戶點擊返回鍵,會返回到上一級路由
this.$router.push(`/home/${id}`)

slot標簽

它是個和 rout-view 和像的標簽,都是用來占位的,它可以接受父組件傳遞給他的一段html

舉個例子: 有四張路由組件,他們共用一個叫header的組件當作自己的頭部, 但是他們需要傳遞進去屬於自己的不同的值, 下面使用slot實現

在 MyHeader.vue中

<!--首頁頭部-->
  <header class="header">

    <!-- 這里使用插槽占位-->
    <slot name="left"></slot>

    <span">
            <span >我是header</span>
    </span>

    <!-- 這里使用插槽占位-->
    <slot name="right"></slot>

  </header>

在父組件中使用:注意啊,下面的組件想往MyHeader.vue中的插槽中,傳遞進去代碼片段,前提是他要把MyHeader.vue映射成標簽,成為他的父組件


<div>
<MyHeader>
    <span class="header_search" slot="left">
        <i class="iconfont icon-sousuo"></i>  /*在插槽的左邊植入一個icon*/
    </span>

    <!-- 給右邊的插槽傳遞模板 -->
    <span class="header_login" slot="right">
        <a href="" >登錄|注冊</a>   /* 在插槽的右邊植入一個鏈接 */
   </span>
</MyHeader>
</div>

Vuex

官方的解釋: vuex是專門為Vue.js應用程序開發的狀態管理模式,它采用集中式的儲存應用中所有組件的狀態,並以相應的規則保證狀態以一種可預期的方式發生變化

說白了: 當我們划分組件之后,每一個組件都有自己的屬性,但是不同的組件的數據是不能共享的,於是我們可以使用從父組件往子組件傳播數據的模式, 而且完全不相干的兩個組件可能需要對方data里的數據,又怎么傳遞呢? vuex 就應對 迎戰這個問題

vuex就是一個單獨存儲的區域,用於存放公共的屬性

安裝命令:

npm install --save vuex

創建vuex的四個組件對象,如上圖

vuex的組件對象一: state.js

狀態對象,存放一系列的狀態,其實就是把子組件中data里面的字段賦復制過來

state.js文件
export default {
  arr: []
}

vuex的組件對象二: actions.js

超級重要的組件, 在這個組件中我們可以提交異步事件, 最常用的就是用戶直接通過$store.dispatch('action中的方法名'), action會觸發 mutation的調用, 間接更新狀態

action.js
// add方法的方法第一個參數是不變的{commit}, 其實他就是 $store 對象
// 通過這個commit方法,  把數據包裝成對象傳遞給 mutations
// 第二個參數的可選的,可以是調用者傳遞進來的參數,也可以是state對象
export default {
  add({commit},item){
    // 提交mutation請求
     commit(ADD_TODO,{item}); // 把數據包裝成對象傳遞給 mutations
  },

vuex的組件對象三: mutations.js

真正的去執行action傳進來,更新state中數據的操作

mutations.js
export default {

add(state,{item}){ 
   state.arr.unshift(item);
} 
}

vuex的組件對象四: getters.js

包含了所有的基於state的 get計算屬性, 這一點也很好用,他是一種雙向的數據綁定

getters.js 
export default {
  // 計算屬性
  totalCount (state) {
    return state.arr.length
  },
}

把四個組件拼裝成store對象

  1. 在src下創建store文件夾,在改文件夾下創建store.js
  2. 導入Vue , Vuex
  3. 聲明Vue使用Vuex
  4. 將上面的四個組件注冊進來store.js
    state: 狀態對象,存放的是需要共享數據的字段
    actions: 包含多個事件回調函數的對象
    mutations: 包含真正去更新state中字段的函數
    getter: 計算屬性的方法
  5. 對外暴露匿名store對象
  6. 將store配置進main.js vue的入口js中

編碼實現: store.js

store.js

import Vue from 'vue'
import Vuex from  'vuex'

import state from './state'
import actions from './actions'
import mutations from  './mutations'
import getters from './getter2'

Vue.use(Vuex)

// 對外暴露你匿名 store對象
export  default new Vuex.Store({
  state,
  actions,
  mutations,
  getters
})

把store對象,注冊進main.js

更全面的數據處理流程圖

獲取state中的值

做好了上面的配置,在任何地方都能用下面的方式獲取出store里面的數據

this.$store.state.屬性

使用vuex,改變狀態值

添加上前綴,再使用

this.$store.commit('matations中的方法名','可選的參數')

// 注意哦, action中是可以提交異步函數的
this.$store.dispach('action中的方法名','可選的參數')

也可以像下面這樣,先進行映射就可以不再添加任何前綴,直接使用他們

// 從vuex中引入映射
import {mapState,mapGetters,mapActions} from 'vuex'

export default {
    computed:{
        ...mapState(['state中的屬性值'])
        ...mapGetters(['getters.js中的方法名'])
    },
    methods:{
        ...mapActions(['actions.js中的方法名'])
    }
}


免責聲明!

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



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