vue基礎知識總結

github github.com/guxiansheng…javascript

1、web前端技術基礎

1. 最基礎的html, css, javascript

html, css, javascript關係 相似於人體: html爲骨架 css爲血肉和外貌 javascript是人的行爲css

html搭建起整個頁面的文檔結構,css爲文檔結構設置樣式,javascript作交互行爲.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>demo</title>
  <style>
    .box {
      width: 200px;
      height: 200px;
      border: 1px solid #ccc;
    }
    .box1 {
      font-size: 12px;
      color: red;
    }
    .box2 .p1 {
      font-size: 20px;
      color: blue;
    }
  </style>
</head>
<body>
  <div class="box box1">
    <h1>一念起天涯咫尺</h1>
    <h1>一念滅咫尺天涯</h1>
  </div>
  <div class="box box2">
    <button onclick="changeText(event)">點擊修改dom元素</button>
    <p class="p1" id="p1"></p>
  </div>
</body>
<script>
  function changeText(e) {
    var p1 = document.getElementById('p1');
    p1.innerText = Math.random();
  }
</script>
</html>
複製代碼

2. 框架介紹

前端目前主要存在如下幾個方向,每一個方向存在着不一樣的框架前端

  • web:

(1) Vue.jsvue

(2) React.jsjava

(3) Angularnode

  • PWA:

PWA(Progressive Web Apps),谷歌提出的一種基於瀏覽器的技術,使用web前端技術開發的,可是能夠將應用添加到桌面,能夠離線使用,能夠有推送通知等更加相似於APP的功能.webpack

  • 小程序

微信小程序,QQ小程序,百度小程序等等ios

  • 混合APP開發

(1) React Native(Facebook)git

(2) Flutter(谷歌)

(3) Hbuilder(國內企業作的)

  • 桌面應用開發

Electron

  • 服務端開發

Node.js

Any application that can be written in JavaScript, will eventually be written in JavaScript.

任何可以用 JavaScript 實現的應用,最終都必將用 JavaScript 實現。

3. node.js介紹

Node.js 是一個基於 Chrome V8 引擎的 JavaScript 運行環境。Node.js 使用了一個事件驅動、非阻塞式 I/O 的模型,使其輕量又高效。 官網: nodejs.cn

Node.js主要應用場景以下:

  1. 作服務端開發
  2. 製做先後端分離開發中web前端的開發工具,如webpack等
  3. 作命令行工具
  4. 開發桌面應用,如 Visual Studio Code

4. web前端開發環境

先後端分離開發:

  1. Node.js提供開發工具
    (1)Node.js開發工具能夠直接下載 nodejs.cn/download/, 目前使用v10.16.0
    (2)可使用NVM版本管理工具,能夠下載多個版本,各個版本之間自由切換(www.jianshu.com/p/d0e0935b1…)
  2. npm包依賴工具 npm會隨着Node.js一塊兒安裝,因此不用單獨安裝,連接中有詳細的使用教程(www.jianshu.com/p/dee4a84e5…).
  3. webpack打包工具 能夠通過打包,將各類web前端資源打包成一個個js文件,css文件,html文件,圖片等 先後端分離項目通常運行步驟:
  4. npm install (安裝項目全部的依賴包)
  5. npm run dev (本地運行開發環境代碼,同時Node.js啓動一個本地web服務器)
  6. npm run build (本地打包線上環境代碼,能夠部署)

以上打包命令都會被定義在項目根目錄下的package.json中的scripts中,不然沒法使用

2、Vue.js基礎

1. Vue.js基礎

(1) 模板語法

  • 文本
  • v-bind(能夠縮寫爲符號: ':' )
  • v-on(能夠縮寫爲符號: '@')

Demo1.vue中 data中定義的 text屬性被綁定到h1標籤的內容上了.
srcText是一個圖片連接,被綁定到img標籤的src屬性中
v-on指令綁定了methods中的點擊事件clickMethod

(2) 條件

  • v-if
  • v-else
  • v-show

Demo1.vue中根據data中show屬性是true/false,顯示或者隱藏標籤
經過toggle方法切換show的值,從而完成標籤的顯示和隱藏
v-show只會隱藏元素(修改元素的display屬性),可是不會從html文檔中刪除標籤,只是切換顯示或者隱藏,因此性能高,適合頻繁切換的場景
v-if false時會從html文檔中刪除標籤, 因此性能消耗大,不適合頻繁切換的場景

(3) 循環

  • v-for

Demo1.vue中 data裏面的arr數組,經過v-for指令完成循環

(4) 事件處理

  • 原生實踐綁定

Demo1.vue中 經過v-on綁定html標籤原生的相關事件,好比click,mouseover等等, 綁定的方法聲明在methods中.

(5) 組件

  • 組件新建

component1.vue組件代碼段是一個.vue文件,跟一個普通組件同樣的.

  • 組件使用

Demo1.vue中, (1)引入component1.vue, (2)components中引用組件, (3)頁面中使用小寫使用組件,兩個大寫則小寫後用短橫槓分開

  • 組件間傳值

父組件向子組件傳遞數據, Demo1.vue中, text是傳入子組件的屬性,在子組件component1.vue中經過props接收.

子組件向父組件傳遞數據, component1.vue組件代碼段中經過emitMethod方法emit出去一個data1事件,並傳值爲 '嘿嘿嘿'; Demo1.vue中,在組件使用的地方接收 v-on:data1="accept",在accept的參數中就是接收到的 '嘿嘿嘿'.

Demo1.vue

<template>
// Demo1.vue
  <div>
    <h1>{{text}}</h1>
    <img class="image1" v-bind:src="srcText" alt="">
    <button v-on:click="clickMethod">點擊</button>
    <!-- computed -->
    <hr>
    <button @click="changeRandowNumber">點擊生成隨機數</button>
    <p>randomNumber:{{randomNumber}}</p>
    <p>test1:{{test1}}</p>
    <!-- watch -->
    <hr>
    <button @click="changeWatchParam">點擊生成watchParam</button>
    <!-- 條件 -->
    <hr>
    <button @click="toggle">切換隱藏和顯示</button>
    <p v-if="show">顯示{{show}}</p>
    <p v-else>隱藏{{show}}</p>
    <p v-show="show">v-show切換{{show}}</p>

    <!-- 循環 -->
    <hr>
    <div v-for="(item, index) in arr" :key="index">{{item}}</div>

    <!-- 組件 -->
    <component1 :text="component1Text" v-on:data1="accept"></component1>
    
    <!-- 子路由 -->
    <router-view></router-view>
  </div>
</template>

<script>
import Component1 from './component1'

export default {
  data () {
    return {
      text: '驢媽媽',
      srcText: 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1561442417122&di=e6fa319459f0ea95645b2bde6d2591a3&imgtype=0&src=http%3A%2F%2Ff.hiphotos.baidu.com%2Fimage%2Fpic%2Fitem%2F8d5494eef01f3a29f863534d9725bc315d607c8e.jpg',
      randomNumber: 0,
      watchParam: 0,
      show: false,
      arr: [1, 2, 3, 4, 5, 6],
      component1Text: 234
    }
  },
  components: {
    Component1
  },
  // 計算屬性
  computed: {
    test1 () {
      let res = 0
      res = this.randomNumber * 1000
      return res
    }
  },
  //
  watch: {
    watchParam (newVal, oldVal) {
      console.log('newVal', newVal)
      console.log('oldVal', oldVal)
    }
  },
  // 組件內路由守衛
  beforeRouteEnter (to, from, next) {
    next(vm => {
      console.log('beforeRouteEnter');
    });
  },
  // 此處不能獲取dom,還沒有掛載dom
  created () {

  },
  // 此處自由使用
  mounted () {
    this.init();
    console.log('demo1 this.$route', this.$route);
  },
  methods: {
    clickMethod () {
      alert('點擊事件')
    },
    init () {
      console.log('init method run')
    },
    changeRandowNumber () {
      this.randomNumber = Math.random()
    },
    changeWatchParam () {
      this.watchParam = Math.random()
    },
    toggle () {
      this.show = !this.show
    },
    accept (data1) {
      console.log('data1', data1)
    }
  }
}
</script>

<style scoped>
.image1 {
  width: 100px;
  height: 100px;
}
</style>
複製代碼

component1.vue

// component1.vue組件
<template>
  <div>
    <h1>{{text}}</h1>
    <button @click="emitMethod">子組件傳遞數據到父組件</button>
  </div>
</template>

<script>
export default {
  data () {
    return {
    }
  },
  props: {
    text: {
      type: Number,
      default: 1
    }
  },
  methods: {
    emitMethod () {
      this.$emit('data1', '嘿嘿嘿')
    }
  }
}
</script>

<style scoped>
</style>
複製代碼

2. vue-router

router.vuejs.org/zh/installa…

(1) 單頁面開發

單頁面開發依賴前端路由,分如下2種實現方式:

  • 哈希模式(默認)
  • history模式

(2) 路由基本使用

  • 路由和子路由

首先, Demo1.vue的template中,應該聲明用來匹配子路由
青蔥,router/index.js, /Demo1匹配Demo1組件; /Demo1/Demo1Child匹配到Demo1Child組件,此時Demo1Child會顯示在Demo1.vue的router-view中

router/index.js

import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import Demo1 from '@/views/demo1/Demo1'
import Demo1Child from '@/views/demo1/Demo1Child'
import Demo2 from '@/views/demo2/Demo2'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'HelloWorld',
      component: HelloWorld
    },
    {
      path: '/Demo1',
      name: 'Demo1',
      component: Demo1,
      children: [
        {
          path: 'Demo1Child',
          name: 'Demo1Child',
          component: Demo1Child
        }
      ]
    },
    {
      path: '/Demo2/:id',
      name: 'Demo2',
      component: Demo2
    }
  ]
})
複製代碼
  • 路由鉤子

路由鉤子存在如下三種:

  1. 全局路由鉤子
  2. 組件內部路由鉤子
  3. 路由中的鉤子

Demo1.vue中beforeRouteEnter爲組件內部路由守衛,即進入路由以前觸發的鉤子函數

  • 路由傳參

路由傳參數通常採用如下兩種(HelloWorld.vue中turn1和turn2方法分別對應2中不一樣的方式):

  1. query,即查詢字符串
  2. params, 即路由參數

HelloWorld.vue

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <h2>Essential Links</h2>
    <button @click="turn1">頁面跳轉query</button>
    <button @click="turn2">頁面跳轉params</button>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data () {
    return {
      msg: 'Welcome to Your Vue.js App'
    }
  },
  methods: {
    turn1 () {
      // 能夠到Demo1Child.vue的mounted中打印查看this.$route中接收到的參數
      this.$router.push({path: '/Demo1/Demo1Child', query: {param1: 123, param2: '哈哈哈'}});
    },
    turn2 () {
      // 能夠到Demo2.vue的mounted中打印查看this.$route中接收到的參數
      this.$router.push({path: '/Demo2/123'});
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>

複製代碼

3. vuex

vuex.vuejs.org/zh/

vuex是vue提供的狀態管理工具.主要包含如下幾項:
(1) state (狀態)
(2) getters (暴露狀態的訪問)
(3) mutations (提交同步修改state)
(4) actions (異步行爲)

模塊化使用方式

能夠將一個項目的狀態樹,根據項目功能模塊,分模塊管理狀態樹,使得狀態管理結構清晰,使用方便. 具體使用能夠看項目代碼.

vuex目錄以下:

(1) src/store/index.js將store下的modules模塊和root模塊合併管理並導出
(2) src/main.js須要將src/store/index.js引入,並掛載到vue實例上 (3) Demo2.vue中使用如代碼所示,mapGetters應寫在computed下,並聲明模塊home,便可在頁面使用isLogin了; mapMutations和mapActions則應該在methods中聲明,使用如代碼所示,便可在組件內部使用.

src/store/index.js

import Vue from 'vue';
import Vuex from 'vuex';
import root from './root';
import home from './modules/home';

Vue.use(Vuex);

const store = new Vuex.Store({
  modules: {
    root,
    home
  }
});

export default store;
複製代碼

src/store/root.js

const state = {};
const getters = {};
const mutations = {};
const actions = {};

export default {
  namespaced: true,
  state,
  getters,
  mutations,
  actions
}
複製代碼

src/modules/home.js

import api from '../../api/index';

const state = {
  isLogin: false
};
const getters = {
  isLogin: state => state.isLogin
};
const mutations = {
  changeLoginState (state, data) {
    state.isLogin = data;
  }
};
const actions = {
  login (context, params) {
    // 可作異步請求
    // setTimeout(() => {
    //   // context.state.isLogin = true;
    //   context.commit('changeLoginState', true);
    // }, 2000);

    return new Promise((resolve, reject) => {
      api.ajaxGetMethod(params).then(res => {
        if (true) {
          resolve(res);
        } else {
          reject(res);
        }
      });
    });
  }
};

export default {
  namespaced: true,
  state,
  getters,
  mutations,
  actions
}
複製代碼

src/main.js

import store from './store'
/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  store,
  components: { App },
  template: '<App/>'
})
複製代碼

src/views/demo2/Demo2.vue

<template>
  <div>
    <h1>Demo2</h1>
    <p>{{isLogin}}</p>
    <button @click="login()">登錄</button>
  </div>
</template>

<script>
import { mapGetters, mapMutations, mapActions } from 'vuex';
export default {
  data () {
    return {}
  },
  computed: {
    ...mapGetters('home', ['isLogin'])
  },
  methods: {
    ...mapMutations('home', ['changeLoginState']),
    ...mapActions('home', ['login']),
    // async, await異步調用
    async loginMethod () {
      try {
        let res = await this.login({});
        console.log('res', res);
      } catch (error) {
        console.error('error', error);
      }
    }
  }
}
</script>

<style scoped>
</style>
複製代碼

4. axios

www.kancloud.cn/yunye/axios…

(1) 建議將請求統一管理,避免項目內部散亂的寫
(2) 建議結合vuex使用,固然也能夠不結合. src/store/modules/home.js中的actions 下的login方法就是結合vuex使用的,能夠在獲得異步請求結果後直接修改狀態
(3) 也能夠將src/api/index.js引入任何組件,調用方法便可發送ajax請求
(4) 使用async,await(完全解決回調地獄問題). 首先src/store/modules/home.js中actions下的login方法返回new Primise; 其次在src/views/demo2/Demo2.vue中loginMethod方法前應寫標緻 async ,調用login前應寫await;最後應使用try...catch捕獲異常

src/api/index.js

import axios from 'axios';

export default {
  ajaxGetMethod: params => axios.get('/xx', {params: params}).then(res => res.data),
  ajaxPostMethod: body => axios.get('/yy', body).then(res => res.data)
}
複製代碼

src/store/modules/home.js

import api from '../../api/index';

const state = {
  isLogin: false
};
const getters = {
  isLogin: state => state.isLogin
};
const mutations = {
  changeLoginState (state, data) {
    state.isLogin = data;
  }
};
const actions = {
  login (context, params) {
    // 可作異步請求
    // setTimeout(() => {
    //   // context.state.isLogin = true;
    //   context.commit('changeLoginState', true);
    // }, 2000);

    return new Promise((resolve, reject) => {
      api.ajaxGetMethod(params).then(res => {
        if (true) {
          resolve(res);
        } else {
          reject(res);
        }
      });
    });
  }
};

export default {
  namespaced: true,
  state,
  getters,
  mutations,
  actions
}
複製代碼

src/views/demo2/Demo2.vue

async loginMethod () {
      try {
        let res = await this.login({});
        console.log('res', res);
      } catch (error) {
        console.error('error', error);
      }
}
複製代碼

5. vue-cli

2.x 版本: github.com/vuejs/vue-c…
3.x 版本: cli.vuejs.org/zh/

2.x 新建項目: vue init template-name project-name

3.x 新建項目: vue create xxx

相關文章
相關標籤/搜索