<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          vue-axios-vuex-全家桶

          共 59281字,需瀏覽 119分鐘

           ·

          2021-09-03 02:17

          Github來(lái)源: | 求星星 ? | 給個(gè)??關(guān)注,??點(diǎn)贊,??鼓勵(lì)一下作者

          https://1024bibi.com/2021/09/01/vue-axios-vuex-%E5%85%A8%E5%AE%B6%E6%A1%B6/


          axios

          Axios 是一個(gè)基于 promise 的 HTTP 庫(kù),可以用在瀏覽器和 node.js 中。簡(jiǎn)單來(lái)說(shuō)就是前端最火最簡(jiǎn)單的一個(gè)http請(qǐng)求解決方案。

          功能

          • 從瀏覽器中創(chuàng)建 XMLHttpRequests
          • 從 node.js 創(chuàng)建 http 請(qǐng)求
          • 支持 Promise API
          • 攔截請(qǐng)求和響應(yīng)
          • 轉(zhuǎn)換請(qǐng)求數(shù)據(jù)和響應(yīng)數(shù)據(jù)
          • 取消請(qǐng)求
          • 自動(dòng)轉(zhuǎn)換 JSON 數(shù)據(jù)
          • 客戶端支持防御 XSRF

          代碼封裝

          工具類封裝

          // 引入axios
          import axios from 'axios';

          // 創(chuàng)建axios實(shí)例
          const httpService = axios.create({
              // url前綴-'https://some-domain.com/api/'
              baseURL: process.env.BASE_API, // 需自定義
              // 請(qǐng)求超時(shí)時(shí)間
              timeout: 3000 // 需自定義
          });

          // request攔截器
          httpService.interceptors.request.use(
              config => {
                  // 根據(jù)條件加入token-安全攜帶
                  if (true) { // 需自定義
                      // 讓每個(gè)請(qǐng)求攜帶token
                      config.headers['User-Token'] = '';
                  }
                  return config;
              }, 
              error => {
                  // 請(qǐng)求錯(cuò)誤處理
                  Promise.reject(error);
              }
          )

          // respone攔截器
          httpService.interceptors.response.use(
              response => {
                  // 統(tǒng)一處理狀態(tài)
                  const res = response.data;
                  if (res.statuscode != 1) { // 需自定義
                      // 返回異常
                      return Promise.reject({
                          status: res.statuscode,
                          message: res.message
                      });
                  } else {
                      return response.data;
                  }
              },
              // 處理處理
              error => {
                   if (error && error.response) {
                      switch (error.response.status) {
                          case 400:
                              error.message = '錯(cuò)誤請(qǐng)求';
                              break;
                          case 401:
                              error.message = '未授權(quán),請(qǐng)重新登錄';
                              break;
                          case 403:
                              error.message = '拒絕訪問(wèn)';
                              break;
                          case 404:
                              error.message = '請(qǐng)求錯(cuò)誤,未找到該資源';
                              break;
                          case 405:
                              error.message = '請(qǐng)求方法未允許';
                              break;
                          case 408:
                              error.message = '請(qǐng)求超時(shí)';
                              break;
                          case 500:
                              error.message = '服務(wù)器端出錯(cuò)';
                              break;
                          case 501:
                              error.message = '網(wǎng)絡(luò)未實(shí)現(xiàn)';
                              break;
                          case 502:
                              error.message = '網(wǎng)絡(luò)錯(cuò)誤';
                              break;
                          case 503:
                              error.message = '服務(wù)不可用';
                              break;
                          case 504:
                              error.message = '網(wǎng)絡(luò)超時(shí)';
                              break;
                          case 505:
                              error.message = 'http版本不支持該請(qǐng)求';
                              break;
                          default:
                              error.message = `未知錯(cuò)誤${error.response.status}`;
                      }
                  } else {
                      error.message = "連接到服務(wù)器失敗";
                  }
                  return Promise.reject(error);
              }
          )

          /*網(wǎng)絡(luò)請(qǐng)求部分*/

          /*
           *  get請(qǐng)求
           *  url:請(qǐng)求地址
           *  params:參數(shù)
           * */
          export function get(url, params = {}) {
              return new Promise((resolve, reject) => {
                  httpService({
                      url: url,
                      method: 'get',
                      params: params
                  }).then(response => {
                      resolve(response);
                  }).catch(error => {
                      reject(error);
                  });
              });
          }

          /*
           *  post請(qǐng)求
           *  url:請(qǐng)求地址
           *  params:參數(shù)
           * */
          export function post(url, params = {}) {
              return new Promise((resolve, reject) => {
                  httpService({
                      url: url,
                      method: 'post',
                      data: params
                  }).then(response => {
                      resolve(response);
                  }).catch(error => {
                      reject(error);
                  });
              });
          }

          /*
           *  文件上傳
           *  url:請(qǐng)求地址
           *  params:參數(shù)
           * */
          export function fileUpload(url, params = {}) {
              return new Promise((resolve, reject) => {
                  httpService({
                      url: url,
                      method: 'post',
                      data: params,
                      headers: { 'Content-Type''multipart/form-data' }
                  }).then(response => {
                      resolve(response);
                  }).catch(error => {
                      reject(error);
                  });
              });
          }

          export default {
              get,
              post,
              fileUpload
          }

          使用

          // 引入工具類-目錄自定義
          import fetch from '@/util/fetch'

          // 使用
          const TMPURL = ''; // url地址
          const params = {}; // 參數(shù)
          fetch.post(TMPURL + '/login/login', params);

          vuex是什么?

          vuex是一個(gè)專為 Vue.js 應(yīng)用程序開(kāi)發(fā)的狀態(tài)管理模式。它采用集中式存儲(chǔ)管理應(yīng)用的所有組件的狀態(tài),并以相應(yīng)的規(guī)則保證狀態(tài)以一種可預(yù)測(cè)的方式發(fā)生變化。chrome安裝調(diào)試工具 devtools extension

          單向數(shù)據(jù)流

          image.png

          示意圖說(shuō)明:

          • State:驅(qū)動(dòng)應(yīng)用的數(shù)據(jù)源(單向數(shù)據(jù)流)
          • View:以聲明方式將 state 映射到視圖(靜態(tài)顯示出來(lái)的數(shù)據(jù)源)
          • Actions:處理用戶在view上面操作而導(dǎo)致的狀態(tài)變化(數(shù)據(jù)源變化追蹤)

          一個(gè)簡(jiǎn)單的demo案例:

          <template>
              <div>
                  <!-- view -->
                  <div>{{ count }}</div>
                  <button @click="increment">increment</button>
              </div>
          </template>
          <script>
          export default {
              // state
              data () {
                  return {
                      count: 0
                  }
              },
              // actions
              methods: {
                  increment () {
                      this.count++
                  }
              }
          }
          </script>
          <style>

          </style>

          vuex解決的問(wèn)題

          • 多個(gè)視圖組件,包括父子組件,兄弟組件之間的狀態(tài)共享
          • 不同視圖組件的行為需要變更同一個(gè)狀態(tài)

          vuex使用場(chǎng)景

          中大型單頁(yè)應(yīng)用,需要考慮如何更好地在組件外部管理狀態(tài),簡(jiǎn)單應(yīng)用不建議使用

          vuex與全局變量的區(qū)別

          • 響應(yīng)式:vuex的狀態(tài)存儲(chǔ)是響應(yīng)式的,當(dāng)Vue組件從store中讀取狀態(tài)的時(shí)候,若store中的狀態(tài)發(fā)生變化,那么相應(yīng)的組件也會(huì)得到高效更新
          • 不能直接改變store:不能直接改變store的變化,改變store中狀態(tài)的唯一途徑是commit mutation,方便于跟蹤每一個(gè)狀態(tài)的變化

          vuex核心流程

          image.png

          示意圖說(shuō)明:

          1. Vue Components:Vue組件。HTML頁(yè)面上,負(fù)責(zé)接收用戶操作等交互行為,執(zhí)行dispatch方法觸發(fā)對(duì)應(yīng)action進(jìn)行回應(yīng)
          2. Dispatch:操作行為觸發(fā)方法,是唯一能執(zhí)行action的方法
          3. Actions:操作行為處理模塊。負(fù)責(zé)處理Vue Components接收到的所有交互行為。包含同步/異步操作,支持多個(gè)同名方法,按照注冊(cè)的順序依次觸發(fā)。向后臺(tái)API請(qǐng)求的操作就在這個(gè)模塊中進(jìn)行,包括觸發(fā)其他action以及提交mutation的操作。該模塊提供了Promise的封裝,以支持action的鏈?zhǔn)接|發(fā)
          4. Commit:狀態(tài)改變提交操作方法。對(duì)mutation進(jìn)行提交,是唯一能執(zhí)行mutation的方法
          5. Mutations:狀態(tài)改變操作方法。是Vuex修改state的唯一推薦方法,其他修改方式在嚴(yán)格模式下將會(huì)報(bào)錯(cuò)。該方法只能進(jìn)行同步操作,且方法名只能全局唯一。操作之中會(huì)有一些hook暴露出來(lái),以進(jìn)行state的監(jiān)控等
          6. State:頁(yè)面狀態(tài)管理容器對(duì)象。集中存儲(chǔ)Vue components中data對(duì)象的零散數(shù)據(jù),全局唯一,以進(jìn)行統(tǒng)一的狀態(tài)管理。頁(yè)面顯示所需的數(shù)據(jù)從該對(duì)象中進(jìn)行讀取,利用Vue的細(xì)粒度數(shù)據(jù)響應(yīng)機(jī)制來(lái)進(jìn)行高效的狀態(tài)更新
          7. Getters:state對(duì)象讀取方法。圖中沒(méi)有單獨(dú)列出該模塊,應(yīng)該被包含在了render中,Vue Components通過(guò)該方法讀取全局state對(duì)象

          總結(jié)說(shuō)明:
          Vue組件接收交互行為,調(diào)用dispatch方法觸發(fā)action相關(guān)處理,若頁(yè)面狀態(tài)需要改變,則調(diào)用commit方法提交mutation修改state,通過(guò)getters獲取到state新值,重新渲染Vue Components,界面隨之更新

          安裝

          npm install vuex --save

          簡(jiǎn)單示例

          (1)src/vuex/store.js中寫(xiě)入以下代碼:

          // 引入vue
          import Vue from 'vue'
          // 引入vuex
          import Vuex from 'vuex'

          // 使用vuex
          Vue.use(Vuex)

          // 1、state:創(chuàng)建初始化狀態(tài)
          const state = {
              // 放置初始狀態(tài)
              count: 1
          }

          // 2、mutations:創(chuàng)建改變狀態(tài)的方法
          const mutations = {
              // 狀態(tài)變更函數(shù)-一般大寫(xiě)
              ADD (state, n) {
                  state.count += n;
              }
          }

          // 3、getters:提供外部獲取state
          const getters = {
              count: function(state){
                  return state.count;
              }
          }

          // 4、actions:創(chuàng)建驅(qū)動(dòng)方法改變mutations
          const actions ={
              // 觸發(fā)mutations中相應(yīng)的方法-一般小寫(xiě)
              add ({commit}, data) {
                  commit('ADD', data)
              }
          }

          // 5、全部注入Store中
          const store = new Vuex.Store({
              state,
              mutations,
              getters,
              actions
          });

          // 6、輸出store
          export default store;

          代碼說(shuō)明:

          • state - mutations - getters - actions - store,以上寫(xiě)法基本固定。
          • 小型項(xiàng)目用上面的簡(jiǎn)單管理狀態(tài)即可。

          (2)src/main.js代碼中

          import Vue from 'vue'
          import App from './App'
          import router from './router'
          // 引入store
          import store from './vuex/store'

          Vue.config.productionTip = false

          /* eslint-disable no-new */
          new Vue({
            el: '#app',
            router,
            store, // 全局注入
            components: { App },
            template: '<App/>'
          })

          (3)src/compontent/Count.vue頁(yè)面組件中代碼如下:

          <template>
              <div class="hello">
                  <h1>{{ msg }}</h1>
                  <h2>{{count}}</h2>
                  <button @click="clickAdd">新增</button>
              </div>
          </template>
          <script>
          export default {
              data () {
                  return {
                      msg: 'Vuex test!'
                  }
              },
              computed: {
                  // 獲取state值
                  count() {
                      return this.$store.state.count;
                  }
              },
              methods: {
                  clickAdd() {
                      //分發(fā)action中的add方法
                      this.$store.dispatch('add', 1);
                  }
              }
          }
          </script>
          <style scoped>

          </style>

          狀態(tài)對(duì)象的獲取方法

          在組件的template中直接使用

          <h2>{{ $store.state.count }}</h2>

          在計(jì)算屬性computed中直接賦值

          // 方式1:直接獲取
          computed: {
              count() {
                  // this指的是main.js中的vue實(shí)例對(duì)象
                  return this.$store.state.count;
              }
          }

          通過(guò)mapState的對(duì)象來(lái)賦值

          // 方式2:利用mapState
          computed: mapState({
              // es5寫(xiě)法
              count: function (state) {
                   return state.count;
               },
              // es6寫(xiě)法
              count: state => state.count
          })

          通過(guò)mapState的數(shù)組來(lái)賦值

          // 方式3:數(shù)組獲取
          computed: mapState(['count'])

          通過(guò)mapState的JSON來(lái)賦值

          // 方式4:JSON獲取
          computed: mapState({
              count: 'count'
          })

          mutations-getters-actions異步

          mutations(修改狀態(tài))

          (1)template中直接使用$store.commit( )觸發(fā)

          // template
          <button @click="$store.commit('ADD')">+</button>

          // src/vuex/store.js
          const mutations = {
              // 狀態(tài)變更函數(shù)
              ADD (state) {
                  state.count++;
              }
          }

          (2)利用mapMutations引入觸發(fā)

          <template>
              <div class="hello">
                  <h1>{{ msg }}</h1>
                  <h2>{{count}}</h2>
                  <!-- 3、、直接調(diào)用相應(yīng)的方法 -->
                  <button @click="ADD">+</button>
              </div>
          </template>
          <script>
          // 1、引入mapMutations
          import {mapState, mapMutations} from 'vuex'
          export default {
              data () {
                  return {
                      msg: 'Vuex test!'
                  }
              },
              // 通過(guò)mapState的JSON來(lái)賦值
              computed: mapState({
                  count: 'count'
              }),
              // 2、methods中加入mapMutations
              methods: mapMutations([
                  'ADD'
              ])
          }
          </script>
          <style scoped>

          </style>

          getters(獲取state和過(guò)濾)

          (1)基本用法

          // src/vuex/store.js
          const getters = {
              count: function(state){
                  // 返回加上100
                  return state.count + 100;
              }
          }

          (2)常規(guī)獲取值

          computed: {
              // 獲取getters
              count(){
                  return this.$store.getters.count;
              }
          }

          (3)mapGetters獲取值

          // 1、引入mapMutations
          import {mapState, mapMutations, mapGetters} from 'vuex'

          // 2、使用
          computed: {
              // 獲取getters
              ...mapGetters(["count"])
          }

          actions(異步狀態(tài)修改)

          actions和mutations功能基本一樣,不同點(diǎn)是,actions是異步的改變state狀態(tài),而mutations是同步改變狀態(tài)。不過(guò)實(shí)際項(xiàng)目中一般都是通過(guò)actions改變mutations中的值。
          (1)store.js中增加異步代碼

          // src/vuex/store.js
          const actions ={
              // 觸發(fā)mutations中相應(yīng)的方法
              add ({commit}) {
                  // 增加異步
                  setTimeout(()=>{
                      commit('ADD')
                  },3000);
                  console.log('我比reduce提前執(zhí)行');
              }
          }

          (2)常規(guī)使用

          // template
          <button @click="add">+</button>

          // script
          methods: {
              add() {
                  //分發(fā)action
                  this.$store.dispatch('add');
              }
          }

          (3)mapActions的使用

          // template
          <button @click="add">+</button>

          // script
          // 引入mapActions
          import {mapState, mapActions} from 'vuex'

          // 使用mapActions
          methods: {
              ...mapActions(['add'])
          }

          傳遞參數(shù)

          只需要在mutations和actions相應(yīng)的地方加上參數(shù),然后調(diào)用的時(shí)候傳入即可。

          (1)src/vuex/store.js中

          // actions中傳遞參數(shù)
          const mutations = {
              ADD (state, n) {
                  state.count += n;
              }
          }

          // actions中傳遞參數(shù)
          const actions ={
              // 觸發(fā)mutations中相應(yīng)的方法
              add ({commit}, n) {
                  // 增加異步
                  setTimeout(()=>{
                      commit('ADD', n);
                  },3000);
                  console.log('我比reduce提前執(zhí)行');
              }
          }

          (2)頁(yè)面組件常規(guī)調(diào)用傳遞

          // template
          <button @click="add">+</button>

          // script
          methods: {
              add() {
                  // 分發(fā)action
                  this.$store.dispatch('add', 99);
               }
          }

          (3)頁(yè)面組件使用mapActions調(diào)用傳遞

          // template
          <button @click="add(99)">+</button>

          // script
          methods: {
              ...mapActions(['add'])
          }

          module-模塊組

          當(dāng)應(yīng)用非常復(fù)雜,狀態(tài)非常多的時(shí)候,需要將store 分割成模塊(module)。每個(gè)模塊擁有自己的 state、mutation、action、getter、甚至是嵌套子模塊,從上至下進(jìn)行同樣方式的分割。

          大致的結(jié)構(gòu)

          // 模塊A
          const moduleA = {
            state: { ... },
            mutations: { ... },
            actions: { ... },
            getters: { ... }
          }

          // 模塊B
          const moduleB = {
            state: { ... },
            mutations: { ... },
            actions: { ... }
          }

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

          // 取值
          store.state.a // -> moduleA 的狀態(tài)
          store.state.b // -> moduleB 的狀態(tài)

          實(shí)際開(kāi)發(fā)中建議把module分開(kāi)編寫(xiě)。
          (1)src/vuex/module1.js

          // 模塊1
          const module1 = {
              // 初始化狀態(tài)
              state: {
                  module1: {
                      name: '模塊1'
                  }
              },
              // 編寫(xiě)動(dòng)作
              mutations: {
                  CHANGE1 (state, data) {
                      state.module1 = data;
                  }
              },
              // 取值
              getters: {
                  module1: function(state){
                      return state.module1;
                  }
              },
              // 創(chuàng)建驅(qū)動(dòng),可異步
              actions: {
                  change1 ({commit}, data) {
                      commit('CHANGE1', data)
                  }
              }
          }

          export default module1;

          (2)src/vuex/module2.js

          // 模塊1
          const module2 = {
              // 初始化狀態(tài)
              state: {
                  module2: {
                      name: '模塊2'
                  }
              },
              // 編寫(xiě)動(dòng)作
              mutations: {
                  CHANGE2 (state, data) {
                      state.module2 = data;
                  }
              },
              // 取值
              getters: {
                  module2: function(state){
                      return state.module2;
                  }
              },
              // 創(chuàng)建驅(qū)動(dòng),可異步
              actions: {
                  change2 ({commit}, data) {
                      commit('CHANGE2', data)
                  }
              }
          }

          export default module2;

          (3)src/vuex/store.js

          // 引入vue
          import Vue from 'vue'
          // 引入vuex
          import Vuex from 'vuex'
          // 引入module1
          import module1 from '@/vuex/module1'
          // 引入module2
          import module2 from '@/vuex/module2'

          // 使用vuex
          Vue.use(Vuex)

          // 模塊注入
          const store = new Vuex.Store({
              modules: {
                  a: module1,
                  b: module2
              }
          })

          // 輸出store
          export default store;

          (4)組件中使用,src/compontent/one.vue

          <template>
              <div id="app">
                  <!-- module1 -->
                  <h2>{{ module1.name }}</h2>
                  <button @click="change1({'name': 'change1'})">module1改變</button>

                  <!-- module2 -->
                  <h2>{{ module2.name }}</h2>
                  <button @click="change2({'name': 'change2'})">module2改變</button>
              </div>
          </template>

          <script>
          // 引入快捷方法
          import {mapState, mapGetters, mapActions} from 'vuex'

          export default {
              name: 'app',
              data () {
                  return {
                  }
              },
              computed:{
                  // mapState取值
                  // ...mapState({
                  //     module1: state => state.a.module1.name,
                  //     module2: state => state.b.module2.name
                  // })

                  // mapGetter取值
                  ...mapGetters(['module1''module2'])
              },
              methods: {
                  // mapAction取方法
                  ...mapActions([
                      'change1',
                      'change2'
                  ])
              }
          }
          </script>
          <style>

          </style>

          PS:module中命名要唯一,不然獲取值和改變值的時(shí)候會(huì)沖突,目前親測(cè)mapGetters只能獲取對(duì)象。

          vue-router

          Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,讓構(gòu)建單頁(yè)面應(yīng)用變得易如反掌。
          包含的功能有:

          • 嵌套的路由/視圖表
          • 模塊化的、基于組件的路由配置
          • 路由參數(shù)、查詢、通配符
          • 基于 Vue.js 過(guò)渡系統(tǒng)的視圖過(guò)渡效果
          • 細(xì)粒度的導(dǎo)航控制
          • 帶有自動(dòng)激活的 CSS class 的鏈接
          • HTML5 歷史模式或 hash 模式,在 IE9 中自動(dòng)降級(jí)
          • 自定義的滾動(dòng)條行為

          安裝

          使用命令安裝:

          npm install vue-router --save

          在src/router/index.js文件中

          // 引入vue框架
          import Vue from 'vue'
          // 引入vue-router路由依賴
          import Router from 'vue-router'
          // 引入頁(yè)面組件,命名為HelloWorld
          import HelloWorld from '@/components/HelloWorld'

          // Vue全局使用Router
          Vue.use(Router)

          // 定義路由配置
          export default new Router({
            routes: [                //配置路由,這里是個(gè)數(shù)組
              {                        //每一個(gè)鏈接都是一個(gè)對(duì)象
                path: '/',            //鏈接路徑
                name: 'HelloWorld',        //路由名稱,
                component: HelloWorld     //對(duì)應(yīng)的組件模板
              }
            ]
          })

          在系統(tǒng)入口文件main.js中注入router,代碼如下:

          // 引入vue框架
          import Vue from 'vue'
          // 引入根組件
          import App from './App'
          // 引入路由配置
          import router from './router'

          // 關(guān)閉生產(chǎn)模式下給出的提示
          Vue.config.productionTip = false

          // 定義實(shí)例
          new Vue({
            el: '#app',
            router, // 注入框架中
            components: { App },
            template: '<App/>'
          })

          頁(yè)面跳轉(zhuǎn)

          router-link標(biāo)簽跳轉(zhuǎn)

          在html標(biāo)簽內(nèi)使用router-link跳轉(zhuǎn),相應(yīng)于超鏈接a標(biāo)簽,使用方式如下:

          <router-link to="/">[顯示字段]</router-link>

          to:導(dǎo)航路徑
          使用示例如下:

          <p>導(dǎo)航 :
             <router-link to="/">首頁(yè)</router-link>
             <router-link to="/hello">hello</router-link>
          </p>

          編程式導(dǎo)航-JS代碼內(nèi)部跳轉(zhuǎn)

          實(shí)際項(xiàng)目中,很多時(shí)候都是通過(guò)在JS代碼內(nèi)部進(jìn)行導(dǎo)航的跳轉(zhuǎn),使用方式如下:

          this.$router.push('/xxx')

          具體的簡(jiǎn)單用法:
          (1)先編寫(xiě)一個(gè)按鈕,在按鈕上綁定goHome( )方法。

          <button @click="goHome">回到首頁(yè)</button>

          (2)在<script>模塊里加入goHome方法,并用this.$router.push(‘/’)導(dǎo)航到首頁(yè)

          export default {
              name: 'app',
              methods: {
                  goHome(){
                      this.$router.push('/home');
                  }
              }
          }

          其他常用方法

          //  后退一步記錄,等同于 history.back()
          this.$router.go(-1)
          // 在瀏覽器記錄中前進(jìn)一步,等同于 history.forward()
          this.$router.go(1)

          子路由-路由嵌套

          子路由,也叫路由嵌套,采用在children后跟路由數(shù)組來(lái)實(shí)現(xiàn),數(shù)組里和其他配置路由基本相同,需要配置path和component,然后在相應(yīng)部分添加來(lái)展現(xiàn)子頁(yè)面信息,相當(dāng)于嵌入iframe。具體看下面的示例:

          src/components/Home.vue(父頁(yè)面)

          <template>
              <div class="hello">
                  <h1>{{ msg }}</h1>
                  <!-- 添加子路由導(dǎo)航 -->
                  <p>導(dǎo)航 :
                      <router-link to="/home">首頁(yè)</router-link> | 
                      <router-link to="/home/one">-子頁(yè)面1</router-link> |
                      <router-link to="/home/two">-子頁(yè)面2</router-link>
                  </p>
                  <!-- 子頁(yè)面展示部分 -->
                  <router-view/>
              </div>
          </template>

          <script>
          export default {
              name: 'Home',
              data () {
                  return {
                      msg: 'Home Page!'
                  }
              }
          }
          </script>

          <style scoped>
          </style>

          src/components/One.vue(子頁(yè)面1)

          <template>
              <div class="hello">
                  <h1>{{ msg }}</h1>
              </div>
          </template>
          <script>
          export default {
              name: 'One',
              data () {
                  return {
                      msg: 'Hi, I am One Page!'
                  }
              }
          }
          </script>

          <style scoped>
          </style>

          src/components/Two.vue(子頁(yè)面2)

          <template>
              <div class="hello">
                  <h1>{{ msg }}</h1>
              </div>
          </template>
          <script>
          export default {
              name: 'Two',
              data () {
                  return {
                      msg: 'Hi, I am Two Page!'
                  }
              }
          }
          </script>

          <style scoped>
          </style>

          src/router/index.js(路由配置)

          import Vue from 'vue'
          import Router from 'vue-router'
          import Home from '@/components/Home'
          import One from '@/components/One' 
          import Two from '@/components/Two'

          Vue.use(Router)

          export default new Router({
              routes: [
              {
                  path: '/', // 默認(rèn)頁(yè)面重定向到主頁(yè)
                  redirect: '/home'
              },
              {
                  path: '/home', // 主頁(yè)路由
                  name: 'Home',
                  component: Home,
                  children:[ // 嵌套子路由
                      {
                          path:'one', // 子頁(yè)面1
                          component:One
                      },
                      {
                          path:'two', // 子頁(yè)面2
                          component:Two
                      },
                  ]
              }
              ]
          })

          路由傳遞參數(shù)

          通過(guò)<router-link> 標(biāo)簽中的to傳參

          基本語(yǔ)法:

          <router-link :to="{name:xxx, params: {key:value}}">valueString</router-link>

          PS:上面to前邊是帶冒號(hào),后邊跟的是一個(gè)對(duì)象形勢(shì)的字符串

          • name:在路由配置文件中起的name值。叫做命名路由。
          • params:要傳的參數(shù),它是對(duì)象形式,在對(duì)象里可以傳遞多個(gè)值。

          具體實(shí)例如下:
          (1)在src/components/Home.vue里面導(dǎo)航中添加如下代碼:

          <router-link :to="{name: 'one', params:{username:'test123'}}">子頁(yè)面1</router-link>

          (2)在src/router/indes.js中添加如下代碼,重點(diǎn)是name:

          {
              path:'one', // 子頁(yè)面1
              name: 'one', // 路由名稱-命名路由
              component:One
          }

          (3)在src/components/One.vue里面接受參數(shù),代碼如下:

          <h2>{{$route.params.username}}</h2>

          url中傳遞參數(shù)

          (1)在路由中以冒號(hào)傳遞,在src/router/index.js中加入如下代碼:

          {
              path:'/home/two/:id/:name', // 子頁(yè)面2
              component:Two
          },

          (2)接受參數(shù),在src/components/Two.vuez中加入如下代碼:

          <p>ID:{{ $route.params.id}}</p>
          <p>名稱:{{ $route.params.name}}</p>

          (3)路由跳轉(zhuǎn),在src/components/Home.vue中加入如下代碼:

          <router-link to="/home/two/1/張三">子頁(yè)面2</router-link>

          PS:to前沒(méi)有冒號(hào)為字符串路由,必須全部匹配。
          (4)如果路由參數(shù)需要有特定的規(guī)則,就需要加入正則表達(dá)式了,示例如下:

          {
              path:'/home/two/:id(\d+)/:name', // 子頁(yè)面2
              component:Two
          }

          編程式導(dǎo)航-params傳遞參數(shù)

          (1)在src/router/index.js頁(yè)面加入如下代碼:

          {
              path:'/home/three', // 子頁(yè)面3
              name: 'three',
              component:Three
          }

          (2)在src/components/Three.vue頁(yè)面加入如下代碼:

          <p>ID:{{ $route.params.id}}</p>
          <p>名稱:{{ $route.params.name}}</p>

          (3)在src/components/Home.vue中加入如下代碼:

          // template
          <button @click="toThreePage">頁(yè)面3-params傳參</button>

          // script
          methods: {
              toThreePage() {
                  this.$router.push({name: 'three', params: {id: 1, name: 'zhangsan'}})
              }
          }

          說(shuō)明:
          A、動(dòng)態(tài)路由使用params傳遞參數(shù),在this.$router.push() 方法中path不能和params一起使用,否則params將無(wú)效。需要用name來(lái)指定頁(yè)面。
          B、以上方式參數(shù)不會(huì)顯示到瀏覽器的地址欄中,如果刷新一次頁(yè)面,就獲取不到參數(shù)了,改進(jìn)方式將第一部中的代碼改成如下:

          {
              path:'/home/three/:id/:name', // 子頁(yè)面3
              name: 'three',
              component:Three
          }

          編程式導(dǎo)航-query傳遞參數(shù)

          (1)在src/router/index.js頁(yè)面加入如下代碼:

          {
              path:'/home/three', // 子頁(yè)面3
              name: 'three',
              component:Three
          }

          (2)在src/components/Three.vue頁(yè)面加入如下代碼:

          <p>ID:{{ $route.query.id}}</p>
          <p>名稱:{{ $route.query.name}}</p>

          (3)在src/components/Home.vue中加入如下代碼:

          // template
          <button @click="toThreePage">頁(yè)面3-params傳參</button>

          // script
          methods: {
              toThreePage() {
                  this.$router.push({path: '/home/three', query: {id: 1, name: 'zhangsan'}})
              }
          }

          PS:動(dòng)態(tài)路由使用query傳遞參數(shù),會(huì)顯示到瀏覽器地址欄中,以上鏈接為
          /home/three?id=1&name=zhangsan

          命名路由-命名視圖-重定向-別名

          命名路由

          給一個(gè)路由命一個(gè)唯一的名稱,然后跳轉(zhuǎn)調(diào)用這個(gè)名稱即可。
          (1)在src/router/index.js中加一個(gè)帶name的路由,代碼如下:

          {
              path: 'one', // 子頁(yè)面1
              name: 'one', // 路由名稱-命名路由
              component: One // 頁(yè)面組件
          }

          (2)在src/component/Home.vue頁(yè)面中調(diào)用,代碼如下:

          // template跳轉(zhuǎn)調(diào)用
          <router-link :to="{name: 'one'}">子頁(yè)面1</router-link>

          // router.push函數(shù)跳轉(zhuǎn)調(diào)用
          router.push({ name: 'user'}})

          命名視圖

          在同一個(gè)頁(yè)面展示多個(gè)視圖,如果不用嵌套,只能采用命名視圖來(lái)實(shí)現(xiàn)了,代碼如下:
          (1)在src/router/index.js中,代碼如下:

          import Vue from 'vue'
          import Router from 'vue-router'
          // 創(chuàng)建頁(yè)面組件
          const Header = { template: '<div>Header</div>' }
          const Left = { template: '<div>Left</div>' }
          const Right = { template: '<div>Right</div>' }

          Vue.use(Router)

          export default new Router({
              routes: [
              {
                  path: '/', // 主頁(yè)路由
                  components: {
                      default: Header,
                      a: Left,
                      b: Right
                  }
              }
              ]
          })

          (2)在src/App.vue中,代碼如下:

          <template>
              <div id="app">
                  <router-view />
                  <router-view name="a" class="left" />
                  <router-view name="b" class="right" />
              </div>
          </template>

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

          <style>
          #app {
              text-align: center;
              color: #2c3e50;
              width: 500px;
              border: 1px solid red;
              margin: 0 auto;
          }

          .left,.right{
              float: left;
              width:48%;
              text-align: center;
              border:1px solid red
          }
          </style>

          PS:經(jīng)過(guò)實(shí)踐,命名視圖只能放在最頂級(jí)的頁(yè)面中,即第一步中的代碼不能放在其他頁(yè)面中。

          重定向

          重定向是通過(guò)route的配置中關(guān)鍵詞redirect來(lái)實(shí)現(xiàn)的,具體代碼如下:
          (1)在src/router/index.js中,代碼如下:

          export default new Router({
              routes: [
              {
                  path: '/', // 默認(rèn)頁(yè)面重定向到主頁(yè)
                  redirect: '/home' // 重定向
              },
              {
                  path: '/home', // 主頁(yè)路由
                  component: Home,
                  children:[ // 嵌套子路由
                      {
                          path:'/home/two/:id/:name', // 子頁(yè)面2
                          component:Two
                      },
                      {
                          path:'/home/three/:id/:name', // 子頁(yè)面3
                          name: 'three', // 路由名稱-命名路由
                          redirect: '/home/two/:id/:name' // 重定向-傳遞參數(shù)
                      },
                  ]
              }
              ]
          })

          (2)在src/components/Home.vue中,代碼如下:

          <router-link to="/">首頁(yè)</router-link> | 
          <router-link to="/home/two/1/lisi">子頁(yè)面2</router-link>  |
          <router-link :to="{name: 'three', params: {id: 1, name: 'zhangsan'}}">子頁(yè)面3</router-link>

          說(shuō)明1-不帶參數(shù)的重定向:

          redirect: '/home' // 重定向-不帶參數(shù)

          說(shuō)明2-帶參數(shù)的重定向:

          redirect: '/home/two/:id/:name' // 重定向-傳遞參數(shù)

          別名

          重定向是通過(guò)route的配置中關(guān)鍵詞alias來(lái)實(shí)現(xiàn)的,具體代碼如下:
          (1)在src/router/index.js中,代碼如下:

          {
              path:'/one', // 子頁(yè)面1
              component:One,
              alias'/oneother'
          }

          (2)在src/components/Home.vue中,代碼如下:

          <router-link to="/oneother">子頁(yè)面1</router-link>

          說(shuō)明1:redirect和alias的區(qū)別

          • redirect:直接改變了url的值,把url變成了真實(shí)的path路徑。\
          • alias:url路徑?jīng)]有別改變,這種更友好,讓用戶知道自己訪問(wèn)的路徑,只是改變了<router-view>中的內(nèi)容。

          說(shuō)明2:
          別名請(qǐng)不要用在path為’/’中,如下代碼的別名是不起作用的。

          {
              path: '/',
              component: Hello,
              alias:'/home'
          }

          過(guò)渡動(dòng)畫(huà)

          代碼示例

          (1)在<router-view>標(biāo)簽的外部添加<transition>標(biāo)簽,標(biāo)簽還需要一個(gè)name屬性,代碼如下:

          <transition name="fade" mode="out-in">
              <router-view />
          </transition>

          (2)加入CSS,一共4個(gè)CSS類名,四個(gè)類名與transition的name屬性有關(guān),比如name=”fade”,相應(yīng)的css如下:

          /*頁(yè)面切換動(dòng)畫(huà)*/
          /*進(jìn)入過(guò)渡的結(jié)束狀態(tài),元素被插入時(shí)就生效,在過(guò)渡過(guò)程完成后移除*/
          .fade-enter-active {
              transition: opacity .5s;
          }
          /*進(jìn)入過(guò)渡的開(kāi)始狀態(tài),元素被插入時(shí)生效,只應(yīng)用一幀后立刻刪除*/
          .fade-enter {
              opacity: 0;
          }
          /*離開(kāi)過(guò)渡的開(kāi)始狀態(tài),元素被刪除時(shí)觸發(fā),只應(yīng)用一幀后立刻刪除*/
          .fade-leave {
              opacity: 1;
          }
          /*離開(kāi)過(guò)渡的結(jié)束狀態(tài),元素被刪除時(shí)生效,離開(kāi)過(guò)渡完成后被刪除*/
          .fade-leave-active {
              opacity:0;
              transition: opacity .5s;
          }

          過(guò)渡模式mode

          • in-out:新元素先進(jìn)入過(guò)渡,完成之后當(dāng)前元素過(guò)渡離開(kāi),默認(rèn)模式。
          • out-in:當(dāng)前元素先進(jìn)行過(guò)渡離開(kāi),離開(kāi)完成后新元素過(guò)渡進(jìn)入。

          mode與404

          mode模式

          代碼示例:

          export default new Router({
              mode: 'history', //mode模式
              routes: [...]
          })

          mode取值說(shuō)明:
          (1)histroy:URL就像正常的 url,示例:http://localhost:8080/home
          (2)hash:默認(rèn)值,會(huì)多一個(gè)“#”,示例:http://localhost:8080/#/home

          404頁(yè)面設(shè)置

          如果訪問(wèn)的路由不存在,或者用戶輸入錯(cuò)誤時(shí),會(huì)有一個(gè)404友好的提示頁(yè)面,配置如下:
          (1)在/src/router/index.js中加入如下代碼:

          // 404
          {
              path: '*',
              component: () => import('@/components/404')
          }

          (2)在src/components/404.vue中編寫(xiě)如下代碼:

          <template>
              <div class="hello">
                  <h1>404 not found</h1>
              </div>
          </template>
          <script>
          export default {
              data () {
                  return {

                  }
              }
          }
          </script>

          <style scoped>
          </style>

          路由鉤子

          路由鉤子,即導(dǎo)航鉤子,其實(shí)就是路由攔截器,vue-router一共有三類:

          1. 全局鉤子:最常用
          2. 路由單獨(dú)鉤子
          3. 組件內(nèi)鉤子

          全局鉤子

          在src/router/index.js中使用,代碼如下:

          // 定義路由配置
          const router = new VueRouter({ ... })

          // 全局路由攔截-進(jìn)入頁(yè)面前執(zhí)行
          router.beforeEach((to, from, next) => {
              // 這里可以加入全局登陸判斷
              // 繼續(xù)執(zhí)行
              next();
          });

          // 全局后置鉤子-常用于結(jié)束動(dòng)畫(huà)等
          router.afterEach(() => {
              //不接受next
          });

          export default router;

          每個(gè)鉤子方法接收三個(gè)參數(shù):
          to: Route : 即將要進(jìn)入的目標(biāo) [路由對(duì)象]
          from: Route : 當(dāng)前導(dǎo)航正要離開(kāi)的路由
          next: Function : 繼續(xù)執(zhí)行函數(shù)

          • next():繼續(xù)執(zhí)行
          • next(false):中斷當(dāng)前的導(dǎo)航。
          • next(‘/‘) 或 next({ path: ‘/‘ }):跳轉(zhuǎn)新頁(yè)面,常用于登陸失效跳轉(zhuǎn)登陸

          路由單獨(dú)鉤子

          使用:在路由配置中單獨(dú)加入鉤子,在src/router/index.js中使用,代碼如下:

          {
              path:'/home/one', // 子頁(yè)面1
                  component: One,
                  // 路由內(nèi)鉤子
                  beforeEnter: (to, from, next) => {
                  console.log('進(jìn)入前執(zhí)行');
                      next();
                  }
          }

          組件內(nèi)鉤子

          使用:在路由組件內(nèi)定義鉤子函數(shù):

          • beforeRouteEnter:進(jìn)入頁(yè)面前調(diào)用
          • beforeRouteUpdate (2.2 新增):頁(yè)面路由改變時(shí)調(diào)用,一般需要帶參數(shù)
          • beforeRouteLeave:離開(kāi)頁(yè)面調(diào)用

          任意找一頁(yè)面,編寫(xiě)如下代碼:

          <script>
          export default {
              name: 'Two',
              data () {
                  return {
                      msg: 'Hi, I am Two Page!'
                  }
              },
              // 進(jìn)入頁(yè)面前調(diào)用
              beforeRouteEnter(to, from, next) {
                  console.log('進(jìn)入enter路由鉤子')
                  next()
              },
              // 離開(kāi)頁(yè)面調(diào)用
              beforeRouteLeave(to,from, next){
                  console.log('進(jìn)入leave路由鉤子')
                  next()
              },
              // 頁(yè)面路由改變時(shí)調(diào)用
              beforeRouteUpdate(to, from, next) {
                  console.log('進(jìn)入update路由鉤子')
                  console.log(to.params.id)
                  next()
              }
          }
          </script>

          路由懶加載

          路由正常模式:

          // 1、先引入頁(yè)面組件
          import Home from '@/components/Home'

          // 2、使用組件
              {
                  path: '/home',
                  component: Home
          }

          懶加載模式

          大項(xiàng)目中,為了提高初始化頁(yè)面的效率,路由一般使用懶加載模式,一共三種實(shí)現(xiàn)方式。
          (1)第一種寫(xiě)法:

          component: (resolve) => require(['@/components/One'], resolve)

          (2)第二種寫(xiě)法:

          component: () => import('@/components/Two')

          (3)第三種寫(xiě)法:

          components: r => require.ensure([], () => r(require('@/components/Three')), 'group-home')

          PS:

          • 一般常用第二種簡(jiǎn)寫(xiě)
          • 第三種中,’group-home’是把組件按組分塊打包, 可以將多個(gè)組件放入這個(gè)組中,在打包的時(shí)候Webpack會(huì)將相同 chunk 下的所有異步模塊打包到一個(gè)異步塊里面。

          vue-cli

          vue-cli是vue官方出品的快速構(gòu)建單頁(yè)應(yīng)用的腳手架,里面集成了webpack,npm,nodejs,babel,vue,vue-router等.

          全局安裝vue-cli,命令行:

          npm install vue-cli -g

          初始化項(xiàng)目

          在實(shí)際開(kāi)發(fā)中,一般都會(huì)使用webpack這個(gè)模板,命令使用如下:

          vue init webpack my-vue-demo

          運(yùn)行項(xiàng)目

          npm run dev

          以上命令為開(kāi)發(fā)模式下運(yùn)行項(xiàng)目

          npm run build

          以上命令為項(xiàng)目發(fā)布打包

          image.png
          image.png

          main.js(入口文件)

          // 引入vue框架
          import Vue from 'vue'
          // 引入根組件
          import App from './App'
          // 引入路由配置
          import router from './router'

          // 關(guān)閉生產(chǎn)模式下給出的提示
          Vue.config.productionTip = false

          // 定義實(shí)例
          new Vue({
            el: '#app',
            router,
            components: { App },
            template: '<App/>'
          })

          router(路由配置)

          // 引入vue框架
          import Vue from 'vue'
          // 引入vue-router路由依賴
          import Router from 'vue-router'
          // 引入頁(yè)面組件,命名為HelloWorld
          import HelloWorld from '@/components/HelloWorld'

          // 使用路由依賴
          Vue.use(Router)

          // 定義路由配置
          export default new Router({
            routes: [
              {
                path: '/',
                name: 'HelloWorld',
                component: HelloWorld
              }
            ]
          })

          模板

          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>Vue入門(mén)之組件</title>
              <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
          </head>
          <body>
          <div id="app">
              <!-- template標(biāo)簽?zāi)0?nbsp;-->
              <template id="demo2">
                  <h2 style="color:red">我是template標(biāo)簽?zāi)0?lt;/h2>
              </template>
          </div>

          <!-- script標(biāo)簽?zāi)0?nbsp;-->
          <script type="x-template" id="demo3">
              <h2 style="color:red">我是script標(biāo)簽?zāi)0?lt;/h2>
          </script>

          <script type="text/javascript">
              // 實(shí)例化
              new Vue({
                  el: '#app',
                  data: {
                      message: 'hello'
                  },
                  // 選項(xiàng)模板
                  //template:`<h1 style="color:red">我是選項(xiàng)模板</h1>`
                  //template:'#demo2'
                  template:'#demo3'
              });
          </script>
          </body>
          </html>

          組件注冊(cè)

          (1)全局注冊(cè)

          // script
          Vue.component('button-counter', {
              data: function () {
                  return {
                      count: 0
                  }
              },
              template: '<button v-on:click="count++">全局組件顯示: {{ count }}</button>'
          });

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

          // html使用
          <button-counter></button-counter>

          (2)局部注冊(cè)

          // script
          new Vue({
              el: '#app',
              components:{
                  "button-inner":{
                      data: function() {
                          return {
                              inner: 0
                          }
                      },
                      template: '<button v-on:click="inner++">局部組件顯示: {{ inner }}</button>'
                  }
              }
          });

          // html使用
          <button-inner></button-inner>

          自定義指令

          vue中的自定義指令通過(guò)Vue.directive來(lái)實(shí)現(xiàn)

          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>Vue入門(mén)之自定義指令</title>
              <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
          </head>
          <body>
          <div id="app">
              <div v-test="color">
                  {{num}}
              </div>
          </div>
          <button onclick="unbindApp()">解綁</button>

          <script type="text/javascript">
          // 解綁
          function unbindApp() {
              app.$destroy();
          }

          // 自定義指令
          Vue.directive("test",{
              //1-被綁定
              bind:function (el, binding, vnode) {
                  console.log("1-bind 被綁定");
                  console.log("el:",el);
                  console.log("binding:",binding);
                  console.log("vnode:",vnode);
                  el.style.color = binding.value;
              },
              //2-被插入
              inserted:function (el, binding, vnode) {
                  console.log("2-inserted 被插入");
              },
              //3-更新
              update:function (el, binding, vnode) {
                  console.log("3-update 更新");
              },
              //4-更新完成
              componentUpdated:function (el, binding, vnode) {
                  console.log("4-componentUpdated 更新完成");
              },
              //5-解綁
              unbind:function (el, binding, vnode) {
                  console.log("5-unbind 解綁");
              }
          });

          var app = new Vue({
              el:'#app',
              data:{
                  num: 123,
                  color:'red'
              }
          })
          </script>
          </body>
          </html>

          參數(shù)說(shuō)明

          • el:指令所綁定的元素,可以用來(lái)直接操作DOM
          • binding:一個(gè)對(duì)象,包含指令的很多信息
          • vnode::Vue編譯生成的虛擬節(jié)點(diǎn)

          $on(在構(gòu)造器外部添加事件)

          $on接收兩個(gè)參數(shù),第一個(gè)參數(shù)是調(diào)用時(shí)的事件名稱,第二個(gè)參數(shù)是一個(gè)匿名方法

          app.$on('reduce',function(){
              console.log('執(zhí)行了reduce()');
              this.count--;
          });

          $once(執(zhí)行一次的事件)

          app.$once('reduceOnce',function(){
              console.log('只執(zhí)行一次的方法');
              this.count--;
          });

          $off(關(guān)閉事件)

          function off(){
              console.log('關(guān)閉事件');
              app.$off('reduce');
          }

          extends

          擴(kuò)展:對(duì)構(gòu)造器進(jìn)行擴(kuò)展

          // 擴(kuò)展
          var extendObj ={
              created: function(){
                  console.log("我是被擴(kuò)展出來(lái)的");
              }
          }

          // 實(shí)例化vue
          var app = new Vue({
              // 掛載實(shí)例
              el:'#app',
              // 頁(yè)面數(shù)據(jù)初始化,字符,對(duì)象、數(shù)組
              data:{
              },
              // 擴(kuò)展
              extends: extendObj
          })
          image.png

          ??掘金文章

          • 前端日??偨Y(jié)
          • 一份不可多得的TypeScript系統(tǒng)入門(mén)整理
          • JS葵花寶典秘籍筆記,為你保駕護(hù)航金三銀四
          • TypeScript趁早學(xué)習(xí)提高職場(chǎng)競(jìng)爭(zhēng)力
          • 前端模擬面試字?jǐn)?shù)過(guò)23477萬(wàn)內(nèi)容
          • JavaScript數(shù)據(jù)結(jié)構(gòu)之鏈表 | 技術(shù)點(diǎn)評(píng)
          • JavaScript的數(shù)據(jù)結(jié)構(gòu)-集合 |技術(shù)點(diǎn)評(píng)
          • 這是我的第一次JavaScript初級(jí)技巧
          • 一個(gè)合格的初級(jí)前端工程師需要掌握的模塊筆記
          • 【初級(jí)】個(gè)人分享Vue前端開(kāi)發(fā)教程筆記
          • localStorage和sessionStorage本地存儲(chǔ)
          • HTML5中的拖放功能
          • 挑戰(zhàn)前端知識(shí)點(diǎn)HTTP/ECMAScript
          • 前端170面試題+答案學(xué)習(xí)整理(良心制作)

          ??關(guān)注+點(diǎn)贊+收藏+評(píng)論+轉(zhuǎn)發(fā)??

          點(diǎn)贊、收藏和評(píng)論

          我是Jeskson(達(dá)達(dá)前端),感謝各位人才的:點(diǎn)贊、收藏和評(píng)論,我們下期見(jiàn)!(如本文內(nèi)容有地方講解有誤,歡迎指出?謝謝,一起學(xué)習(xí)了)

          我們下期見(jiàn)!

          文章持續(xù)更新,可以微信搜一搜「 程序員哆啦A夢(mèng) 」第一時(shí)間閱讀,回復(fù)【資料】有我準(zhǔn)備的一線大廠資料,本文 https://www.1024bibi.com 已經(jīng)收錄

          github收錄,歡迎Star:https://github.com/webVueBlog/WebFamily

          瀏覽 43
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  成人网站在线精品国产免费 | 欧美黄色电影在线观看 | 操b视频手机观看 | 中文字幕在线观看免费视频 | 精品艹逼 |