Vue學習總結(Vue基礎,VueCli3,VueRouter,Vuex)

Vue學習總結(Vue基礎,VueCli3,VueRouter,Vuex)

目錄

  • vue基礎知識(1-13)
    • vue 引入,實例化
    • vue 數據 & 方法
    • vue 綁定(:)
    • vue 事件(@)
    • vue 事件修飾符(.once.prevent.stop等)
    • vue 按鍵修飾符(@keyup.alt.enter)
    • vue 數據雙向綁定(ref,v-model)
    • vue 計算屬性computed
    • vue 動態綁定css樣式
    • vue v-if & v-show
    • vue v-for
    • vue 實例化多個Vue對象
    • vue 初識組件的應用
  • 運用腳手架及組件知識(14-21)
    • 腳手架初識
    • SRC文件
    • 組件嵌套
    • 組件CSS作用域
    • 屬性傳值Props(父組件向子組件傳值)
    • 傳值和傳引用
    • 事件傳值(子組件to父組件)
    • Vue生命周期(鉤子函數)
  • vue路由知識點(22-32)
    • Vue 路由和HTTP
    • Vue 只用 Bootstrap4 中的樣式
    • 路由跳轉
    • 路由小細節(redirect和tag)
    • 路由name屬性及跳轉方法
    • 路由嵌套
    • 導航守衛(全局守衛)
    • 導航守衛(路由獨享-組件內守衛)
    • 復用router-view
    • 路由控制滾動行為
    • 跨域
  • vue-cli3新特性(33-37)
    • 項目搭建及介紹
    • 新出的添加插件方法
    • 全局環境變量的使用
    • 獨立運行.vue文件
    • 圖形頁面構建項目
  • vuex基礎知識(38-43)
    • State
    • Getter
    • Mutation
    • Action
    • mapMutations & mapActions
    • Module

basics

1.vue引入,實例化

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
let vue-app = new Vue({
  ...
})

2.vue數據 & 方法

// 數據
data(){
  data1:'xxx'
},
// 方法
methods: {
  methodName(){
    return this.data1;
  }
}
<button @click='methodName'>點擊</button>
<!-- 或者 -->
<div>{{ methodName() }}</div>

方法中用data中的屬性,直接使用this.*,不用this.data.*

3.vue綁定(v-bind:, :, v-html:)

(1)屬性綁定(用 v-bind:: )

website: 'https://github.com/'
<a v-bind:href="website">websit</a>
<!-- 或者簡寫 -->
<a :href="website">websit</a>

(2)標簽綁定(用v-html:)

websiteTag: "<a 
<!-- 正確 -->
<p v-html="websiteTag">websit</a>
<!-- 錯誤 -->
{{ websiteTag }}
<!-- 顯示如下 -->
<!-- <a >websit</a> -->

4.vue事件(用 v-on:@)

? 綁定事件里方法不傳參可以不加括號仍然識別為方法,但在{{}}里一定要寫括號才會識別為方法

eg: 傳參單擊雙擊事件

methods: {
  add: function(val){
    this.age += val;
  },
  dec: function(val){
    this.age -= val;
  },
}
<button v-on:click='add(1)'>加一歲</button>
<button @click='dec(1)'>減一歲</button>
<button v-on:dblclick='add(10)'>加十歲</button>
<button @dblclick='dec(10)'>減十歲</button>

5.vue事件修飾符(.once.prevent.stop等)

在事件處理程序中調用 event.preventDefault()event.stopPropagation() 是非常常見的需求。盡管我們可以在方法中輕松實現這點,但更好的方式是:方法只有純粹的數據邏輯,而不是去處理 DOM 事件細節。

為了解決這個問題,Vue.js 為 v-on 提供了事件修飾符。之前提過,修飾符是由點開頭的指令后綴來表示的。

  • .stop
  • .prevent
  • .capture
  • .self
  • .once
  • .passive
<!-- 阻止單擊事件繼續傳播 -->
<a v-on:click.stop="doThis"></a>

<!-- 提交事件不再重載頁面 -->
<form v-on:submit.prevent="onSubmit"></form>

<!-- 修飾符可以串聯 -->
<a v-on:click.stop.prevent="doThat"></a>

<!-- 只有修飾符 -->
<form v-on:submit.prevent></form>

<!-- 添加事件監聽器時使用事件捕獲模式 -->
<!-- 即元素自身觸發的事件先在此處理,然后才交由內部元素進行處理 -->
<div v-on:click.capture="doThis">...</div>

<!-- 只當在 event.target 是當前元素自身時觸發處理函數 -->
<!-- 即事件不是從內部元素觸發的 -->
<div v-on:click.self="doThat">...</div>

? 使用修飾符時,順序很重要;相應的代碼會以同樣的順序產生。因此,用 v-on:click.prevent.self 會阻止所有的點擊,而 v-on:click.self.prevent 只會阻止對元素自身的點擊。

6.vue按鍵修飾符(@keyup.alt.enter)

在監聽鍵盤事件時,我們經常需要檢查詳細的按鍵。Vue 允許為 v-on 在監聽鍵盤事件時添加按鍵修飾符:

<!-- 只有在 `key` 是 `Enter` 時調用 `vm.submit()` -->
<input v-on:keyup.enter="submit">

你可以直接將 KeyboardEvent.key 暴露的任意有效按鍵名轉換為 kebab-case 來作為修飾符。

<input v-on:keyup.page-down="onPageDown">

在上述示例中,處理函數只會在 $event.key 等于 PageDown 時被調用。

? 按鍵碼 keyCode 的事件用法已經被廢棄了并可能不會被最新的瀏覽器支持。

使用 keyCode 特性也是允許的:

<input v-on:keyup.13="submit">

為了在必要的情況下支持舊瀏覽器,Vue 提供了絕大多數常用的按鍵碼的別名:

  • .enter
  • .tab
  • .delete (捕獲“刪除”和“退格”鍵)
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right

7.vue數據雙向綁定(ref,v-model)

方法一

  <input ref='name' type="text" @keyup='logName'>
  this.name = this.$refs.name.value;

方法二

  <input v-model='age' type="text">

8.vue計算屬性computed

methods 中的每個方法每次渲染dom都會執行 調用 {{xxx()}}

computed 中的每個方法只會在自己觸發時執行 調用 {{xxx}},案例中拷貝的值與虛擬dom不同,就執行。

9.vue動態綁定css樣式

<!-- active類名,isActive類值 -->
<div v-bind:class="{ active: isActive }"></div>

10.v-if & v-show

條件不成立時:v-if在dom中直接刪除元素;v-show改變class為display:none

eg:

  <button @click='err=!err'>err</button>
  <button @click='success=!success'>success</button>
  <p v-if='err'>err</p>
  <p v-else-if='success'>200</p>
  <p v-show='err'>err</p>
  <p v-show='success'>200</p>

11.v-for

? 記得綁定key值

  data: {
    users:[
      {name:'hurry',age:20},
      {name:'luccy',age:25},
      {name:'zero',age:18},
    ]
  },
  <ul v-for='(item,index) in users' :key='index'>
    <li>{{index+1}} - {{item.name}} - {{item.age}}</li>
  </ul>
  <!-- 會多出3個div -->
  <div v-for='(item,index) in users' :key='index'>
    <h2>{{item.name}}</h2>
    <p>{{index+1}} - {{item.age}}</p>
  </div>
  <!-- 不會多出3個template -->
  <template v-for='(item,index) in users' :key='index'>
    <h2>{{item.name}}</h2>
    <p>{{index+1}} - {{item.age}}</p>
  </template>

12.實例化多個Vue對象

多個vue對象實例化

var one = new Vue({...})

var two = new Vue({...})

不同對象使用其他對象數據

one.data

eg:

var one = new Vue({
  el: '#vue-app-one',
  data: {
    title: 'one 的內容'
  },
  methods: {
    
  },
  computed: {
    greet:function(){
      return 'hello app one';
    }
  },
});

var two = new Vue({
  el: '#vue-app-two',
  data: {
    title: 'two 的內容'
  },
  methods: {
    changeTitle:function(){
      one.title = 'title one changed by app two!!!';
    }
  },
  computed: {
    greet:function(){
      return 'hello app one';
    }
  },
});

13.vue初識組件的應用

js中:

// greeting 是組件名,可在 #vue-app-one,#vue-app-two 中使用
Vue.component("greeting",{
  // 所有標簽必須在一個大標簽下
  template:`
  <div>
    <p> {{name}}:大家好,給大家介紹一下我的朋友@關曉彤</p>
    <button @click='changeName'>點我</button> 
  </div>
  `,
  // return一個對象則在組件內是私有的,不會暴露出去
  data:function(){
    return {
      name:'鹿晗'
    }
  },
  methods:{
    changeName:function(){
      this.name = this.name == '鹿晗'?'Hery':'鹿晗'
    }
  }
})

new Vue({
  el: '#vue-app-one'
});

new Vue({
  el: '#vue-app-two'
});

HTML中:

<greeting></greeting>

vue-cli

14.vue腳手架初識

部分特點

  • 腳手架是通過webpack搭建的開發環境
  • 使用es6語法
  • 打包和壓縮js為一個文件
  • 項目在環境中編譯,而不是瀏覽器
  • 實現頁面自動刷新
  • ...

vue-cli的使用

  • 安裝 nodejs ,一般選擇安裝LTS(長期穩定版)版本。官網:https://nodejs.org/en/
    # 在terminal、cmd、powershell 中
    # 輸入 `node -v` 查看 node 版本號
    node -v
    
    # 輸入 `npm -v` 查看 npm 版本號
    npm -v
    
  • 安裝 cnpm
    npm install -g cnpm --registry=https://registry.npm.taobao.org
    
  • 安裝 Vue CLI 3.x
    npm install -g @vue/cli
    # OR
    yarn global add @vue/cli
    
    # 輸入 `vue --version` 查看 npm 版本號
    vue --version
    # OR
    vue -V
    
  • 創建一個 Vue 項目
    vue create projectName
    
    cd projectName
    
    npm run serve
    
    # 創建項目相關幫助
    vue create --help
    
  • 運行相關
    # Project setup
    npm install
    # Compiles and hot-reloads for development
    npm run serve
    # Compiles and minifies for production
    npm run build
    # Run your tests
    npm run test
    # Lints and fixes files
    npm run lint
    
  • (PS)舊版本 Vue CLI 2.x
    npm install -g @vue/cli-init
    # `vue init` 的運行效果將會跟 `vue-cli@2.x` 相同
    vue init webpack my-project
    

15.介紹腳手架搭建的項目中SRC文件流程及根組件App

client
│  .gitignore
│  babel.config.js
│  package.json
│  README.md
│
├─public
│    favicon.ico
│    index.html
│
└─src
    │  App.vue
    │  main.js
    │  router.js
    │
    ├─assets
    │      bg.jpg
    │
    └─components
           Component1.vue
           Component2.vue

index.html -> main.js -> App.vue ()

<!-- 模板 -->
<template></template>
<!-- 邏輯 -->
<script></script>
<!-- 樣式 -->
<style></style>

16.組件嵌套

可以在main.js中注冊全局組件

import Users from './component/Users'

Vue.component('users',Users);

也可以在某些組件中調用

<template>
  <div id="app">
    <Users></Users>
  </div>
</template>

<script>
import Users from './components/Users'
export default {
  components:{
    'Users':Users
  }
}
</script>

17.組件CSS作用域

<style scoped>
/* `scoped`該組件作用域內有效 */
/* 否則子組件相同選項樣式會覆蓋根組件的 */
</style>

18.屬性傳值Props(父組件向子組件傳值)

父組件:

在調用子組件的位置,綁定自己的屬性,第一個是子組件中的名稱第二個是父組件中的名稱

eg:

<Users :usersSon='users'></Users>

子組件:

子組件屬性 props:['usersSon'], 接收傳值。或者用標準寫法

props:{
  users:{
    type:Array;
    requied:true;
  },
  position:{
    type:Array;
    requied:true;
  },
},

eg:

<template>
  <div class="users">
    <ul>
      <li v-for="(user,index) in usersSon" :key="index" @click="user.show = !user.show">
        <h2>{{user.name}}</h2>
        <h3 v-show="user.show">{{user.position}}</h3>
      </li>
    </ul>
  </div>
</template>

<script>
  export default {
    name:'users',
    props:['usersSon'],
  }
</script>

19.傳值和傳引用

傳值:string number boolean,一處變,全部變

引用:array object,一處變,局部變

20.事件傳值(子組件to父組件)

子組件

<h1 @click="tofather">{{title1}} {{title}}</h1>
<script>
export default {
  methods: {
    tofather: function(){
      this.$emit('changed','son to father') //第1個參數是事件名,第2個參數是傳遞的值
    }
  },
}
</script>

父組件

<Header @changed='update($event)' :title="title"></Header>
<!-- $event不能改 -->

<script>
export default {
  methods: {
    update:function(title){
      this.title = title;
    }
  },
}
</script>

21.Vue生命周期(鉤子函數)

作用:可以找錯誤,可以解決需求

生命周期圖示(紅色為生命周期函數):

生命周期圖示

// 8個鉤子函數與 methods 并列。

// 創建對象之前(比如加載動畫)
beforeCreate(){}

// 創建vue對象
new Vue()

// 組件創建成功,屬性已經綁定,dom還未生成(比如獲取數據,待會兒展示到dom,結束加載)
created(){}

// 檢查 el 或者 new({...}).$mount('#app) ,都沒有則生命周期結束

// 檢查有沒 template 或者 outerHTML ,都沒有則生命周期結束

// 開始編譯模板 template 里的內容,掛載前,虛擬dom中執行,看不到
beforeMount(){}

// el 中已經放入 template ,編譯結束,此方法執行后,頁面顯示
mounted(){}

// 組件更新之前
beforeUpdate(){}

// 組件更新之后
updated(){}

// 組件銷毀之前
beforeDestroy(){}

// 組件銷毀之后
destroyed(){}

router

22.Vue路由和HTTP

(1) 安裝路由模塊及引入

npm install vue-router --save

router.js中

import Vue from 'vue'
import Router from 'vue-router'
import Home from './components/Home.vue'
import HelloWorld from './components/HelloWorld.vue'

Vue.use(Router);

export default new Router({
  mode: 'history', // 沒有#符號
  base: process.env.BASE_URL,
  routes: [
    {
      path: '/',
      name: 'home',
      component: Home
    },
    {
      path: '/helloworld',
      name: '',
      component: HelloWorld
    }
  ]
})

main.js中

import router from './router';

new Vue({
  router,
  ...
});

App.vue

    <ul>
      <li><a href="/">Home</a></li>
      <li><a href="/helloworld">Hello</a></li>
      <!-- 或者 -->
      <li><router-link to="/">Home</router-link></li>
      <li><router-link to="/helloworld">Hello</router-link></li>
    </ul>
    <router-view></router-view>

(2) HTTP

安裝依賴:

npm i vue-resource --save

使用:

main.js中

import VueResource from 'vue-resource';
Vue.use(VueResource);

Home.vue中

  created(){
    this.$http.get('http://jsonplaceholder.typicode.com/users')
    .then((data)=>{
      // console.log(data);
      this.users = data.body;
    })
  },

23.vue中只用 Bootstrap4 中的樣式

index.html中引入

<link rel="stylesheet"  integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">

24.路由跳轉

router.js

import Vue from 'vue'
import Router from 'vue-router'
import Home from './components/Home'
import About from './components/about/About'

Vue.use(Router)

export default new Router({
  mode: 'history',
  base: process.env.BASE_URL,
  routes: [
    {path:'/',component:Home},
    {path:'/about',component:About},
  ]
})

Header.vue

<router-link to="/about"></router-link>

App.vue

<router-view></router-view>

25.路由小細節(redirect和tag)

Header.vue

<!-- 默認a標簽 -->
<router-link to="/about"></router-link>

<!-- 修改為div標簽 -->
<router-link tag='div' to="/about"></router-link>

<!-- 動態綁定屬性路由 -->
<router-link tag='div' :to="router"></router-link>
<script>
  export default {
    data(){
      return{
        router:'/'
      }
    }
  }
</script>

router.js

export default new Router({
  mode: 'history',
  base: process.env.BASE_URL,
  routes: [
    {path:'/',component:Home},
    {path:'/about',component:About},
    {path:'*',redirect:'/'}, //錯誤輸入重定向
  ]
})

26.路由name屬性及跳轉方法

name

{path:'/',name:'homelink',component:Home},
<!-- 注意這幾個符號 : {} " '' " -->
<li><router-link :to="{name:'homelink'}" class="nav-link">主頁</router-link></li>

跳轉

  <button @click="goOlder" class='btn btn-success'>goOlder</button>
  <button @click="goMenu" class='btn btn-success'>goMenu</button>
  <button @click="goAdmin" class='btn btn-success'>goAdmin</button>

<script>
export default {
  methods:{
    goOlder(){
      this.$router.go(-1); // 到前一個頁面
    },
    goMenu(){
      // this.$router.replace('/menu');  // replace到指定路由頁面
      this.$router.push('/menu');  // push到指定路由頁面
    },
    goAdmin(){
      // this.$router.replace({name:'adminLink'});  // 到指定 name 頁面
      this.$router.push({name:'adminLink'});  // 到指定 name 頁面
    },
  }
}
</script>

27.路由嵌套

router.js

    {path:'/about',name:'aboutLink',redirect:'/about/histoey',component:About,
    // 二級路由
    children:[
      {path:'/about/histoey',name:'historyLink',component:History},
      {path:'/about/contact',name:'contactLink',redirect:'/phone',component:Contact,children:[
        // 三級路由
        {path:'/phone',name:'phoneNum',component:Phone},
        {path:'/personname',name:'personName',component:Personname},
      ]},
      {path:'/about/orderingguide',name:'orderingGuideLink',component:OrderingGuide},
      {path:'/about/delivery',name:'deliveryLink',component:Delivery},
    ]},

about.vue

<!-- 導航的內容 -->
<router-view></router-view>

28.導航守衛(全局守衛)

學習地址(https://router.vuejs.org/zh/guide/advanced/navigation-guards.html)

main.js中

// 全局守衛
router.beforeEach((to,from,next) => {
  if(to.path == '/login' || to.path == '/register'){
    next()
  }else{
    alert("還沒有登錄,請先登錄!");
    next('/login');
  }
})

29.導航守衛(路由獨享-組件內守衛)

后置鉤子(不常用)

router.afterEach((to,from) => {
  alert("after each")
})

路由獨享的守衛

const router = new VueRouter({
  routes: [
    {
      path: '/foo',
      component: Foo,
      beforeEnter: (to, from, next) => {
        // ...
      }
    }
  ]
})

組件內的守衛

  • beforeRouteEnter
  • beforeRouteUpdate (2.2 新增)
  • beforeRouteLeave
const Foo = {
  template: `...`,
  beforeRouteEnter (to, from, next) {
    // 在渲染該組件的對應路由被 confirm 前調用
    // 不!能!獲取組件實例 `this`
    // 因為當守衛執行前,組件實例還沒被創建
  },
  beforeRouteUpdate (to, from, next) {
    // 在當前路由改變,但是該組件被復用時調用
    // 舉例來說,對于一個帶有動態參數的路徑 /foo/:id,在 /foo/1 和 /foo/2 之間跳轉的時候,
    // 由于會渲染同樣的 Foo 組件,因此組件實例會被復用。而這個鉤子就會在這個情況下被調用。
    // 可以訪問組件實例 `this`
  },
  beforeRouteLeave (to, from, next) {
    // 導航離開該組件的對應路由時調用
    // 可以訪問組件實例 `this`
  }
}

beforeRouteEnter 守衛 不能 訪問 this,因為守衛在導航確認前被調用,因此即將登場的新組件還沒被創建。

不過,你可以通過傳一個回調給 next來訪問組件實例。在導航被確認的時候執行回調,并且把組件實例作為回調方法的參數。

beforeRouteEnter (to, from, next) {
  next(vm => {
    // 通過 `vm` 訪問組件實例
  })
}

注意 beforeRouteEnter 是支持給 next 傳遞回調的唯一守衛。對于 beforeRouteUpdate 和 beforeRouteLeave 來說,this 已經可用了,所以不支持傳遞回調,因為沒有必要了。

beforeRouteUpdate (to, from, next) {
  // just use `this`
  this.name = to.params.name
  next()
}

這個離開守衛通常用來禁止用戶在還未保存修改前突然離開。該導航可以通過 next(false) 來取消。

beforeRouteLeave (to, from , next) {
  const answer = window.confirm('Do you really want to leave? you have unsaved changes!')
  if (answer) {
    next()
  } else {
    next(false)
  }
}
beforeRouteLeave(to,from,next){
  if(confirm('確認離開嗎?') == true){
    next()
  }else{
    next(false)
  }
}

30.復用router-view

router.js修改

{path:'/',name:'homeLink',component:Home,},

// 注意 components 的 s
{path:'/',name:'homeLink',components:{
  default:Home,
  'history':History,
  'orderingGuide':OrderingGuide,
  'delivery':Delivery
}},

App.vue添加

<div class="container">
  <div class="row">
    <div class="col-sm-12 col-md-4">
      <router-view name="history"></router-view>
    </div>
    <div class="col-sm-12 col-md-4">
      <router-view name="orderingGuide"></router-view>
    </div>
    <div class="col-sm-12 col-md-4">
      <router-view name="delivery"></router-view>
    </div>
  </div>
</div>

31.路由控制滾動行為

router.js中

const router = new VueRouter({
  routes: [...],
  scrollBehavior (to, from, savedPosition) {
    // return 期望滾動到哪個的位置
  }
})

eg:


  scrollBehavior (to, from, savedPosition) {
    // return {x:0,y:100};  // 滾動到(0,100)
    // return {selector:'.btn'}; // 滾動到 第一個.btn
    // 瀏覽器返回上一頁面時,回到上次瀏覽的位置
    if(savedPosition){
      return savedPosition
    }else{
      return {x:0,y:0}
    }
  }

32.跨域

(0)預設

通過vue-cli3.x版本構建的項目使用proxy和以前的項目不同,而且3.x版本構建的時候可以選用typescript了。下面記錄一下如何使用proxy跨域。
首先在根目錄創建vue.config.js文件,這個配置文件在運行項目的時候自動加載。

// vue.config.js
module.exports = {
  devServer: {
    proxy: {
      '/api': {
        target: 'http://xxxx/device/', //對應自己的接口
        changeOrigin: true,
        ws: true,
        pathRewrite: {
          '^/api': ''
        }
      }
    }
  }
}

這個文件還可以配置其它信息,比如修改端口號,默認是8080等等。
最后在頁面發送請求的時候:

axios.get('/api/getDataPoint').then(res => {
  console.log(res)
})

示例如下:

(1)預設

proxyTable:{
  ' /apis': {
      //測試環境
      target:'http://www.thenewstep.cn/', //接口域名
      change0rigin:true, //是否跨域
      pathRewrite: {
        '^/apis':'' //需要rewrite重寫的,
      }
  }
},

(2)fetch

created(){
  // fetch
  fetch("/apis/test/testToken. php", {
    method:"post",
    headers: {
      "Content-type" :"application/json",
      "token" : "f4c902c9ae5a2a9d8f84868ad064e706"
    },
    body: JSON.stringify({username: "henry" , password :"321321"})
  })
  . then( result =>{
    // console. log( result)
    return result. json()
  })
  . then(data => {
    console. log ( data)
  })
}

(3)axios

main.js

import axios from 'axios'

axios.defaults.headers.common[ 'token '] = "f4c902c9ae5a2a9d8f84868ad064e706"
axios.defaults.headers.post ["Content-type"] = "application/j son"

Vue.prototype.$axios = axios

App.vue

this.$axios.post("/apis/test/testToken.php" , {username :"hello",password :"123456"})
  .then(data => {
    console. log(data)
  })

(4) 示例二加載美團外賣數據json

將包含 goods.json,ratings.json,seller.json 三個文件的 data 文件夾放到根目錄下

還是vue.config.js文件

const goods = require(' ./data/goods.json');
const ratings = require(' ./data/ratings.json');
const seller = require(' ./data/seller.json');

module.exports = {
  //baseUrl: './', //根路徑 //"baseUrl" option in vue.config.js is deprecated now, please use "publicPath" instead.
  publicPath: './', //根路徑
  outputDir: 'dist2', //構建輸出目錄
  assetsDir: 'assets', //靜態資源目錄(js, css, img, fonts )
  lintOnSave: false, //是否開啟eslint保存檢測,有效值: true || false || ' error'

  devServer: {
    open: true, // 瀏覽器自動開啟
    host: 'localhost', // 主機地址'127.0.0.0','0.0.0.0'也可以
    port: 8081, // 端口號
    https: false, // 是否啟動https,啟動會警告
    hot0nly: false, // 熱更新,默認false
    proxy: {
      //配置跨域
      '/api': {
        target: 'http//localhost:5000/api/',
        ws: true,
        chang0rigin: true,
        pathRewrite: {
          '^/api': ''
        }
      }
    }
  },

  before(app) {
    // http: //loca lhost: 8081/api/goods
    app.get('/api/goods', (req, res) => {
      res. json(goods) ;
    });
    app.get( '/api/ratings', (req, res) => {
      res. json(ratings);
    });
    app.get( '/api/seller', (req, res) => {
      res. json(seller);
    });
  }

};

vuecli3

33.Vue-Cli3.0-項目搭建及介紹

找到腳手架的github倉庫:https://github.com/vuejs/vue-cli

打開docs文件夾,拉到最后,按照步驟安裝

Install:

npm install -g @vue/cli
# OR
yarn global add @vue/cli

Create a project:

vue create my-project
# OR
vue ui

Run a project

cd my-project
npm run serve

34.Vue-Cli3.0-新出的添加插件方法

  • 原來的插件安裝方法
    npm install <plugin> --save
    
  • 新方法
    vue add <plugin>
    
    會有一些文件替換的插件(比如vuetify)會有提示,建議用該方法

35.Vue-Cli3.0-全局環境變量的使用

全局環境

根路徑下創建.env文件,設置全局環境變量,比如:

VUE_APP_XXX = XXX

在需要的組件內

<script>
export default{
  data(){
    return{
      url: process.env.VUE_APP_XXX
    }
  }
}
</script>

.env數據變化要重新啟動項目

開發環境

根路徑下創建.env.development文件,設置開發環境變量,比如:

VUE_APP_XXX = XXX

npm run serve時用該文件的值。

生產環境

根路徑下創建.env.production文件,設置開發環境變量,比如:

VUE_APP_XXX = XXX

npm run build時用該文件的值。

36.Vue-Cli3.0-獨立運行.vue文件

npm install -g @vue/cli-service-global

vue serve XXX.vue

37.Vue-Cli3.0-圖形頁面構建項目

vue ui

打開GUI地址,進入圖形頁面,開始構建項目。

創建新項目:詳情->預設->功能->配置

創建時 terminal 窗口會繼續運行

創建好后gui界面會有:插件,依賴,配置,任務(serve,build,inspect) 4個菜單。

vuex

38.State(Vuex-搭建Vuex中央狀態管理 & Vuex-使用computed獲取store數據)

Vuex

Centralized State Management for Vue.js.

src 目錄下新建 store 文件夾,下面新建 index.js 文件

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

Vue.use(Vuex)

export const store = new Vuex.Store({
  state:{
    products:[
      {name:'馬云',price:'200'},
      {name:'馬化騰',price:'140'},
      {name:'馬冬梅',price:'20'},
      {name:'馬蓉',price:'10'},
    ]
  }
}) 

main.js 中引入

import {store} from './store'
new Vue({
  store,
  ...
}

組建中使用,computed 屬性獲取 store 中數據

<li v-for="product in products" :key='product'>
  <span class="name">{{product.name}}</span>
  <span class="price">${{product.price}}</span>
</li>

<script>
export default{
  computed: {
    products(){
      return this.$store.state.products
    }
  },
}
</script>

39.Getter

index.js 文件中,新增 getters 屬性,里面放其他組件可以調用的方法

export const store = new Vuex.Store({
  state:{
    products:[
      {name:'馬云',price:'200'},
      {name:'馬化騰',price:'140'},
      {name:'馬冬梅',price:'20'},
      {name:'馬蓉',price:'10'},
    ]
  },
  getters:{
    saleProducts:(state)=>{
      var saleProducts = state.products.map(product =>{
        return{
          name: "**" + product.name + "**" ,
          price: product.price / 2
        }
      });
      return saleProducts;
    }
  }
}) 

組件對 store 中方法的調用

<li v-for="product in saleProducts" :key='product'>
  <span class="name">{{product.name}}</span>
  <span class="price">${{product.price}}</span>
</li>

<script>
export default{
  computed: {
    saleProducts(){
      return this.$store.getters.saleProducts;
    }
  },
}
</script>

40.Mutation

谷歌瀏覽器添加插件Vue.js devtools可以跟蹤vuex狀態

更改 Vuex 的 store 中的狀態的唯一方法是提交 mutation。Vuex 中的 mutation 非常類似于事件:每個 mutation 都有一個字符串的 事件類型 (type) 和 一個 回調函數 (handler)。這個回調函數就是我們實際進行狀態更改的地方,并且它會接受 state 作為第一個參數。

store/index.js 中添加 mutations 屬性

  mutations:{
    reducePriceV:state=>{
      state.products.forEach(product =>{
        product.price -= 1;
      })
    }
  }

組建中調用方法 reducePriceV

<button @click="reducePrice">降價</button>
<script>
export default {
  methods: {
    reducePrice(){
      this.$store.commit('reducePriceM') // mutations中的方法
    }
  },
}
</script>

41.Action

Action 類似于 mutation,不同在于:

  • Action 提交的是 mutation,而不是直接變更狀態。
  • Action 可以包含任意異步操作。(vuex調試器中方法和變化同時出來)

注冊action

Action 函數接受一個與 store 實例具有相同方法和屬性的 context 對象,因此你可以調用 context.commit 提交一個 mutation,或者通過 context.statecontext.getters 來獲取 state 和 getters。

組件觸發action

Action 通過 store.dispatch 方法觸發

接收第二個參數 payload

eg:

store/index.js 中添加 actions 屬性

  actions:{
    reducePriceA:context=>{
      setTimeout(function(){
        context.commit('reducePriceM')
      },2000)
    }
  }

組建中調用方法 reducePriceM

<button @click="reducePrice">降價</button>
<script>
export default {
  methods: {
    reducePrice(){
      this.$store.dispatch('reducePriceA') // actions中的方法
    }
  },
}
</script>

42.Vuex-mapMutations & mapActions

在組件中提交 Mutation

你可以在組件中使用 this.$store.commit('xxx') 提交 mutation,或者使用 mapMutations 輔助函數將組件中的 methods 映射為 store.commit 調用(需要在根節點注入 store)。

import { mapMutations } from 'vuex'

export default {
  // ...
  methods: {
    ...mapMutations([
      'increment', // 將 `this.increment()` 映射為 `this.$store.commit('increment')`

      // `mapMutations` 也支持載荷:
      'incrementBy' // 將 `this.incrementBy(amount)` 映射為 `this.$store.commit('incrementBy', amount)`
    ]),
    ...mapMutations({
      add: 'increment' // 將 `this.add()` 映射為 `this.$store.commit('increment')`
    })
  }
}

在組件中分發 Action

你在組件中使用 this.$store.dispatch('xxx') 分發 action,或者使用 mapActions 輔助函數將組件的 methods 映射為 store.dispatch 調用(需要先在根節點注入 store):

import { mapActions } from 'vuex'

export default {
  // ...
  methods: {
    ...mapActions([
      'increment', // 將 `this.increment()` 映射為 `this.$store.dispatch('increment')`

      // `mapActions` 也支持載荷:
      'incrementBy' // 將 `this.incrementBy(amount)` 映射為 `this.$store.dispatch('incrementBy', amount)`
    ]),
    ...mapActions({
      add: 'increment' // 將 `this.add()` 映射為 `this.$store.dispatch('increment')`
    })
  }
}

43.Module

由于使用單一狀態樹,應用的所有狀態會集中到一個比較大的對象。當應用變得非常復雜時,store 對象就有可能變得相當臃腫。

為了解決以上問題,Vuex 允許我們將 store 分割成模塊(module)。每個模塊擁有自己的 state、mutation、action、getter、甚至是嵌套子模塊——從上至下進行同樣方式的分割:

const moduleA = {
  state: { ... },
  mutations: { ... },
  actions: { ... },
  getters: { ... }
}

const moduleB = {
  state: { ... },
  mutations: { ... },
  actions: { ... }
}

const store = new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB
  }
})

store.state.a // -> moduleA 的狀態
store.state.b // -> moduleB 的狀態
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Vue知識點的總結 Vue中的指令及其基本語法: 第一步:從官網上下載vue開發版本的js文件 引入js文件 ...
    往前走莫回頭_2cd6閱讀 1,490評論 0 1
  • ## 框架和庫的區別?> 框架(framework):一套完整的軟件設計架構和**解決方案**。> > 庫(lib...
    Rui_bdad閱讀 2,979評論 1 4
  • 基于Vue的一些資料 內容 UI組件 開發框架 實用庫 服務端 輔助工具 應用實例 Demo示例 element★...
    嘗了又嘗閱讀 1,187評論 0 1
  • vue-cli搭建項目 確保安裝了node與npm 再目標文件夾下打開終端 執行cnpm i vue-cli -g...
    Akiko_秋子閱讀 3,281評論 1 22
  • 鍵盤高度是不一樣的所以不能寫死 需要根據彈出的鍵盤動態獲取 第一步 在需要的地方注冊監聽 第二步 實現監聽的方法
    野生塔塔醬閱讀 2,747評論 0 4