欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Vue實(shí)現(xiàn)JSON字符串格式化編輯器組件功能

 更新時(shí)間:2024年01月03日 11:37:04   作者:馬可家的菠蘿  
這篇文章主要介紹了Vue實(shí)現(xiàn)JSON字符串格式化編輯器組件,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧

相信很多同學(xué)都用過網(wǎng)上的在線JSON格式化工具來將雜亂的JSON數(shù)據(jù)轉(zhuǎn)換成易于我們閱讀和編輯的格式。那么,你有沒有想過自己動(dòng)手實(shí)現(xiàn)一個(gè)這樣的工具呢?今天,我將介紹如何使用Vue.js來構(gòu)建一個(gè)簡(jiǎn)單的JSON格式化工具。

功能簡(jiǎn)述

  • 支持格式化JSON字符串
  • 支持去除字符串中的空格
  • 支持全屏操作
  • 實(shí)時(shí)展示格式化狀態(tài)
  • 控制臺(tái)展示成功和失敗的詳情,支持錯(cuò)誤定位
  • 編輯器精準(zhǔn)計(jì)算字符串的行號(hào)

效果圖展示

默認(rèn)

全屏

功能介紹

按鈕

其他

1、自動(dòng)補(bǔ)全

輸入”(“、”{“、”[“將會(huì)自動(dòng)補(bǔ)全另一半

2、自動(dòng)刪除

刪除括號(hào)時(shí)也會(huì)自動(dòng)刪除另一半

3、括號(hào)匹配

點(diǎn)擊括號(hào)會(huì)高亮另一半括號(hào),方便定位

4、支持ctrl+z撤銷和ctrl+y重做功能

5、編輯器根據(jù)字符串的換行計(jì)算行號(hào)并展示

代碼

vue文件

<!--JsonEditor.vue-->
<template>
  <div ref="center" id="editor_body" :style="{ height: editorHeight, width: editorWidth }">
    <div style="height: 80%">
      <div class="tool_slider">
        <div style="display: flex; align-items: center">
          <img
            src="@/assets/icons/format.svg"
            class="icon_hover"
            @click="prettyFormat(viewJsonStr)"
            title="格式化"
          />
          <div style="height: 18px; border: 1px solid #858585; margin: 0 3px"></div>
          <img
            src="@/assets/icons/clearLine.svg"
            class="icon_hover"
            @click="viewJsonStr = viewJsonStr.replace(/\s+/g, '')"
            title="去除空格"
          />
          <div
            style="
              display: flex;
              align-items: center;
              border-left: 2px solid #858585;
              height: 18px;
              margin: 0 3px;
              padding: 0 3px;
            "
          >
            <img
              src="@/assets/icons/full.svg"
              v-if="!isFullScreen"
              class="icon_hover"
              @click="fullScreen"
              title="全屏"
            />
            <img
              src="@/assets/icons/closeFull.svg"
              v-else
              class="icon_hover"
              @click="fullScreen"
              title="退出"
            />
          </div>
        </div>
        <div style="display: flex; align-items: center">
          <img
            src="@/assets/icons/success.svg"
            title="格式正確"
            v-if="isPass"
            style="height: 20px; width: 20px"
          />
          <img
            src="@/assets/icons/error.svg"
            title="格式錯(cuò)誤"
            v-else
            style="height: 17px; width: 17px"
          />
        </div>
      </div>
      <div class="edit-container">
        <textarea
          wrap="off"
          cols="1"
          id="leftNum"
          disabled
          onscroll="document.getElementById('rightNum').scrollTop = this.scrollTop;"
        ></textarea>
        <textarea
          ref="myTextarea"
          id="rightNum"
          :key="isFullScreen"
          style="width: 100%"
          placeholder="請(qǐng)輸入JSON字符串"
          onscroll="document.getElementById('leftNum').scrollTop = this.scrollTop;"
          :value="viewJsonStr"
          @click="handleClick"
          @input="handleTextareaInput1"
        />
      </div>
    </div>
    <div id="console">{{ jsonObj }}</div>
  </div>
</template>
<script lang="ts" setup>
  import { computed, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue';
  import { cloneDeep } from 'lodash-es';
  import {
    handleBackspace,
    handleClick,
    handleClickEnter,
    handleTabKey,
    handleTextareaInput,
    setAutoKey,
  } from '@/components/JsonEditor';
  const emit = defineEmits(['update:value']);
  const props = defineProps({
    value: {
      type: String,
      default: '',
    },
    width: {
      type: String,
      default: '1000px',
    },
    height: {
      type: String,
      default: '400px',
    },
  });
  const viewJsonStr: any = ref(props.value);
  const editorWidth: any = ref(JSON.parse(JSON.stringify(props.width)));
  const editorHeight: any = ref(JSON.parse(JSON.stringify(props.height)));
  // 自動(dòng)補(bǔ)全
  function handleTextareaInput1(event) {
    handleTextareaInput(viewJsonStr, event);
  }
  const isPass = ref(true);
  watch(
    () => viewJsonStr.value,
    (newValue) => {
      calculateNum(newValue);
      emit('update:value', newValue);
    },
  );
  const num = ref('');
  function calculateNum(value) {
    let lineBbj: any = document.getElementById('leftNum');
    num.value = '';
    let str = value;
    if (str === null || str === undefined) {
      str = '';
    }
    str = str.replace(/\r/gi, '');
    str = str.split('\n');
    let n = str.length;
    if (n.toString().length > 3) {
      lineBbj.style.width = n.toString().length * 10 + 'px';
    } else {
      lineBbj.style.width = '30px';
    }
    for (let i = 1; i <= n; i++) {
      if (document.all) {
        num.value += i + '\r\n'; //判斷瀏覽器是否是IE
      } else {
        num.value += i + '\n';
      }
    }
    lineBbj.value = num.value;
  }
  // 預(yù)覽對(duì)象
  const jsonObj = computed(() => {
    const str = cloneDeep(viewJsonStr.value);
    // 如果輸入的全是數(shù)字,JSON.parse(str)不會(huì)報(bào)錯(cuò),需要手動(dòng)處理一下
    const onlyNumber = /^\d+$/.test(str);
    const dom = document.getElementById('console');
    function setColor(color) {
      if (dom) {
        dom.style.color = color;
      }
    }
    if (str) {
      try {
        if (onlyNumber) {
          setColor('red');
          isPass.value = false;
          return getCurrentTime() + str + ' is not valid JSON';
        }
        setColor('black');
        isPass.value = true;
        if (JSON.parse(str)) {
          setColor('green');
          return `${getCurrentTime()}校驗(yàn)通過`;
        }
      } catch (e: any) {
        isPass.value = false;
        setColor('red');
        if (e.message?.match(/position\s+(\d+)/)) {
          const location = e.message?.match(/position\s+(\d+)/)[1];
          const str1 = str.substring(0, location).trim();
          const str2 = str1.split('\n');
          const message = e.message.substring(0, e.message.indexOf('position'));
          // 如果當(dāng)前行或者前一行有'['
          if (str2[str2.length - 1]?.includes('[')) {
            const { line, column } = getLineAndColumn(str1, str1.length - 1);
            return `${message} at line ${line},column ${column}`;
          }
          const { line, column } = getLineAndColumn(str, location);
          return `${getCurrentTime()}${message} at line ${line},column ${column}`;
        } else {
          return getCurrentTime() + str + ' is not valid JSON';
        }
      }
    } else {
      return null;
    }
  });
  // 獲取當(dāng)前時(shí)間
  function getCurrentTime() {
    let now = new Date(); // 獲取當(dāng)前日期和時(shí)間
    let hours = now.getHours(); // 獲取小時(shí)
    let minutes: string | number = now.getMinutes(); // 獲取分鐘
    let seconds: string | number = now.getSeconds(); // 獲取秒
    let period = hours >= 12 ? '下午' : '上午'; // 判斷是上午還是下午
    // 將小時(shí)轉(zhuǎn)換為12小時(shí)制
    hours = hours % 12 || 12;
    // 格式化分鐘和秒,確保它們是兩位數(shù)
    minutes = minutes < 10 ? '0' + minutes : minutes;
    seconds = seconds < 10 ? '0' + seconds : seconds;
    // 構(gòu)造最終的時(shí)間字符串
    let currentTime = period + hours + ':' + minutes + ':' + seconds;
    return '【' + currentTime + '】 ';
  }
  //計(jì)算錯(cuò)誤信息所在行列
  function getLineAndColumn(str, index) {
    let line = 1;
    let column = 1;
    for (let i = 0; i < index; i++) {
      if (str[i] === '\n') {
        line++;
        column = 1;
      } else {
        column++;
      }
    }
    return { line, column };
  }
  //json格式美化
  function prettyFormat(str) {
    try {
      // 設(shè)置縮進(jìn)為2個(gè)空格
      str = JSON.stringify(JSON.parse(str), null, 4);
      str = str.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
      viewJsonStr.value = str.replace(
        /("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g,
        function (match) {
          return match;
        },
      );
    } catch (e) {
      console.log('異常信息:' + e);
    }
  }
  const center = ref();
  const isFullScreen = ref(false);
  // 添加或刪除全屏屬性
  function fullScreen() {
    if (center.value) {
      if (center.value.className.includes('fullScreen')) {
        editorHeight.value = JSON.parse(JSON.stringify(props.height));
        editorWidth.value = JSON.parse(JSON.stringify(props.width));
        center.value.className = center.value.className.replace(' fullScreen', '');
        isFullScreen.value = false;
      } else {
        editorHeight.value = '100vh';
        editorWidth.value = '100vw';
        center.value.className += ' fullScreen';
        isFullScreen.value = true;
      }
    }
  }
  const myTextarea: any = ref(null);
  function handleKeyDown(event) {
    if (myTextarea.value) {
      if (event.key === 'Backspace') {
        handleBackspace(viewJsonStr, event);
      } else if (event.key === 'Enter') {
        handleClickEnter(viewJsonStr, event);
      } else if (event.key === 'Tab') {
        handleTabKey(event);
      } else if (event.key === 'Escape') {
        if (isFullScreen.value) {
          fullScreen();
        }
      }
    }
  }
  // 符號(hào)自動(dòng)補(bǔ)全以及選中文本后輸入符號(hào)自動(dòng)包裹
  function getMouseCheck(event) {
    setAutoKey(viewJsonStr, event);
  }
  onMounted(() => {
    window.addEventListener('keydown', handleKeyDown);
    document.addEventListener('keydown', getMouseCheck);
    calculateNum(props.value);
  });
  onBeforeUnmount(() => {
    window.removeEventListener('keydown', handleKeyDown);
    document.removeEventListener('keydown', getMouseCheck);
  });
</script>
<style scoped lang="less">
  #editor_body {
    border: 1px solid #d9d9d9;
    border-radius: 4px;
    padding: 5px;
    box-sizing: border-box;
  }
  .tool_slider {
    padding-left: 5px;
    padding-right: 5px;
    display: flex;
    width: 100%;
    box-sizing: border-box;
    justify-content: space-between;
    align-items: center;
    height: 25px;
    border: 1px solid #d9d9d9;
    border-bottom: 0;
  }
  .icon_hover {
    height: 20px;
    width: 20px;
    cursor: pointer;
    &:hover {
      color: #5c82ff;
    }
  }
  #leftNum {
    overflow: hidden;
    padding: 3px 2px;
    height: 100%;
    width: 30px;
    line-height: 22px;
    font-size: 13px;
    color: rgba(0, 0, 0, 0.25);
    font-weight: bold;
    resize: none;
    text-align: center;
    outline: none;
    border: 0;
    background: #f5f7fa;
    box-sizing: border-box;
    border-right: 1px solid;
    font-family: 微軟雅黑;
  }
  #rightNum {
    white-space: nowrap;
    height: 100%;
    padding: 3px;
    line-height: 22px;
    box-sizing: border-box;
    resize: none;
    border: 0;
    font-family: 微軟雅黑;
    &::-webkit-scrollbar {
      width: 5px;
      height: 5px;
      background-color: #efeae6;
    }
    &:focus-visible {
      outline: none;
    }
    &:hover {
      border: 0;
    }
    &:focus {
      border: 0;
    }
  }
  .leftBox {
    height: 100%;
    text-align: left;
  }
  .edit-container {
    height: calc(100% - 25px);
    width: 100%;
    box-sizing: border-box;
    border: 1px solid #d9d9d9;
    display: flex;
  }
  .fullScreen {
    position: fixed;
    z-index: 9999;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    background-color: #f5f7fa;
  }
  #console {
    padding: 12px;
    box-sizing: border-box;
    height: calc(20% - 5px);
    margin-top: 5px;
    width: 100%;
    background-color: white;
    border: 1px solid #d9d9d9;
    overflow: auto;
    font-family: 微軟雅黑;
    text-align: left;
  }
</style>

配置文件

/*index.ts*/
import { nextTick } from 'vue';
// 獲取文本框的值
export const handleTextareaInput = (viewJsonStr, event) => {
  const textarea = event.target;
  const newValue = textarea.value;
  viewJsonStr.value = newValue;
};
// 設(shè)置自動(dòng)補(bǔ)全
export const setAutoKey = (viewJsonStr, event) => {
  const textarea: any = document.getElementById('rightNum');
  if (event.key === "'" || event.key === '"') {
    event.preventDefault(); // 阻止默認(rèn)行為
    const selectedText = textarea.value.substring(textarea.selectionStart, textarea.selectionEnd);
    const newText = `${event.key}` + selectedText + `${event.key}`;
    const cursorPosition = textarea.selectionStart + 1;
    textarea.value =
      textarea.value.substring(0, textarea.selectionStart) +
      newText +
      textarea.value.substring(textarea.selectionEnd);
    textarea.setSelectionRange(cursorPosition, cursorPosition);
  } else if (event.key === '(') {
    event.preventDefault(); // 阻止默認(rèn)行為
    const selectedText = textarea.value.substring(textarea.selectionStart, textarea.selectionEnd);
    const newText = '(' + selectedText + ')';
    const cursorPosition = textarea.selectionStart + 1;
    textarea.value =
      textarea.value.substring(0, textarea.selectionStart) +
      newText +
      textarea.value.substring(textarea.selectionEnd);
    textarea.setSelectionRange(cursorPosition, cursorPosition);
  } else if (event.key === '[') {
    event.preventDefault(); // 阻止默認(rèn)行為
    const selectedText = textarea.value.substring(textarea.selectionStart, textarea.selectionEnd);
    const newText = '[' + selectedText + ']';
    const cursorPosition = textarea.selectionStart + 1;
    textarea.value =
      textarea.value.substring(0, textarea.selectionStart) +
      newText +
      textarea.value.substring(textarea.selectionEnd);
    textarea.setSelectionRange(cursorPosition, cursorPosition);
  } else if (event.key === '{') {
    event.preventDefault(); // 阻止默認(rèn)行為
    const selectedText = textarea.value.substring(textarea.selectionStart, textarea.selectionEnd);
    const newText = '{' + selectedText + '}';
    const cursorPosition = textarea.selectionStart + 1;
    textarea.value =
      textarea.value.substring(0, textarea.selectionStart) +
      newText +
      textarea.value.substring(textarea.selectionEnd);
    textarea.setSelectionRange(cursorPosition, cursorPosition);
  }
  viewJsonStr.value = textarea.value;
};
/*------------------------------------------------括號(hào)高亮------------------------------------------------------------*/
const findOpeningBracketIndex = (text, startIndex, char) => {
  const openingBrackets = {
    ']': '[',
    '}': '{',
    ')': '(',
  };
  let count = 0;
  for (let i = startIndex; i >= 0; i--) {
    if (text.charAt(i) === char) {
      count++;
    } else if (text.charAt(i) === openingBrackets[char]) {
      count--;
      if (count === 0) {
        return i;
      }
    }
  }
  return -1;
};
const findClosingBracketIndex = (text, startIndex, char) => {
  const closingBrackets = {
    '[': ']',
    '{': '}',
    '(': ')',
  };
  let count = 0;
  for (let i = startIndex; i < text.length; i++) {
    if (text.charAt(i) === char) {
      count++;
    } else if (text.charAt(i) === closingBrackets[char]) {
      count--;
      if (count === 0) {
        return i;
      }
    }
  }
  return -1;
};
const isBracket = (char) => {
  return ['[', ']', '{', '}', '(', ')'].includes(char);
};
// 點(diǎn)擊括號(hào)尋找對(duì)應(yīng)另一半
export const handleClick = (event) => {
  const textarea: any = document.getElementById('rightNum');
  const { selectionStart, selectionEnd, value } = textarea;
  const clickedChar = value.charAt(selectionStart);
  if (isBracket(clickedChar)) {
    const openingBracketIndex = findOpeningBracketIndex(value, selectionStart, clickedChar);
    const closingBracketIndex = findClosingBracketIndex(value, selectionStart, clickedChar);
    if (openingBracketIndex !== -1) {
      textarea.setSelectionRange(openingBracketIndex, openingBracketIndex + 1);
    } else if (closingBracketIndex !== -1) {
      textarea.setSelectionRange(closingBracketIndex, closingBracketIndex + 1);
    }
  }
};
/*鍵盤事件*/
export function handleClickEnter(viewJsonStr, event) {
  if (event.key == 'Enter') {
    const textarea = event.target;
    const cursorPosition: any = textarea.selectionStart; // 獲取光標(biāo)位置
    const value = textarea.value;
    if (
      (value[cursorPosition - 1] === '{' && value[cursorPosition] == '}') ||
      (value[cursorPosition - 1] === '[' && value[cursorPosition] == ']')
    ) {
      textarea.value = value.slice(0, cursorPosition) + '\n' + value.slice(cursorPosition);
      textarea.setSelectionRange(cursorPosition, cursorPosition);
      viewJsonStr.value = textarea.value;
      // 將光標(biāo)移動(dòng)到插入的空格后面
      setTimeout(() => {
        handleTabKey(syntheticEvent);
      }, 30);
    }
  }
}
// 新建tab按鍵對(duì)象
const syntheticEvent = new KeyboardEvent('keydown', {
  key: 'Tab',
});
// 按下tab鍵時(shí)的操作
export const handleTabKey = (event) => {
  const textarea: any = document.getElementById('rightNum');
  const { selectionStart, selectionEnd } = textarea;
  const tabSpaces = '    '; // 4 spaces
  event.preventDefault();
  // 在當(dāng)前光標(biāo)位置插入4個(gè)空格
  textarea.value =
    textarea.value.substring(0, selectionStart) +
    tabSpaces +
    textarea.value.substring(selectionEnd);
  // 將光標(biāo)向右移動(dòng)4個(gè)空格
  textarea.selectionStart = selectionStart + tabSpaces.length;
  textarea.selectionEnd = selectionStart + tabSpaces.length;
};
// 按下Backspace按鍵時(shí)
export function handleBackspace(viewJsonStr, event) {
  const textarea = event.target;
  const cursorPosition = textarea.selectionStart;
  const textBeforeCursor = viewJsonStr.value.slice(0, cursorPosition);
  const textAfterCursor = viewJsonStr.value.slice(cursorPosition);
  if (
    (textBeforeCursor.endsWith('"') && textAfterCursor.startsWith('"')) ||
    (textBeforeCursor.endsWith("'") && textAfterCursor.startsWith("'")) ||
    (textBeforeCursor.endsWith('[') && textAfterCursor.startsWith(']')) ||
    (textBeforeCursor.endsWith('{') && textAfterCursor.startsWith('}')) ||
    (textBeforeCursor.endsWith('(') && textAfterCursor.startsWith(')'))
  ) {
    event.preventDefault(); // 阻止默認(rèn)的刪除行為
    viewJsonStr.value = textBeforeCursor.slice(0, -1) + textAfterCursor.slice(1);
    nextTick(() => {
      textarea.selectionStart = cursorPosition - 1;
      textarea.selectionEnd = cursorPosition - 1;
    }).then((r) => {});
  }
}

調(diào)用方式

 <JsonEditor  v-model:value="testStr" />
 const testStr = ref('123');

總結(jié)

這個(gè)JSON編輯器不僅能夠讓你方便地格式化JSON字符串,還能幫你去掉不必要的空格。而且,它的全屏功能讓編輯更加順暢。最酷的是,它還能實(shí)時(shí)告訴你格式化的進(jìn)度,如果遇到問題了,控制臺(tái)會(huì)詳細(xì)告訴你哪里出錯(cuò)了,這樣你就能快速找到問題并解決它。編輯器還能精確地計(jì)算行號(hào),這對(duì)于查找問題也是很有幫助的。而且,它還有自動(dòng)補(bǔ)全、自動(dòng)刪除和括號(hào)匹配這些貼心的功能,讓你的編輯工作變得更加輕松。如果你不小心做錯(cuò)了,也不用擔(dān)心,因?yàn)樗С殖蜂N和重做。希望它能幫助到大家,讓我們的工作更加愉快!

到此這篇關(guān)于Vue實(shí)現(xiàn)JSON字符串格式化編輯器組件的文章就介紹到這了,更多相關(guān)Vue JSON字符串格式化編輯器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Vue3中Composition的API用法詳解

    Vue3中Composition的API用法詳解

    這篇文章主要為大家詳細(xì)介紹了Vue3中Composition的一些常見API的用法,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-06-06
  • 詳解vue2.0 transition 多個(gè)元素嵌套使用過渡

    詳解vue2.0 transition 多個(gè)元素嵌套使用過渡

    這篇文章主要介紹了詳解vue2.0 transition 多個(gè)元素嵌套使用過渡,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • vue原生方法自定義右鍵菜單

    vue原生方法自定義右鍵菜單

    這篇文章主要為大家詳細(xì)介紹了vue原生方法自定義右鍵菜單,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • 在?Vue?中使用?dhtmlxGantt?組件時(shí)遇到的問題匯總(推薦)

    在?Vue?中使用?dhtmlxGantt?組件時(shí)遇到的問題匯總(推薦)

    dhtmlxGantt一個(gè)功能豐富的甘特圖插件,支持任務(wù)編輯,資源分配和多種視圖模式,這篇文章主要介紹了在?Vue?中使用?dhtmlxGantt?組件時(shí)遇到的問題匯總,需要的朋友可以參考下
    2023-03-03
  • vue pages 多入口項(xiàng)目 + chainWebpack 全局引用縮寫說明

    vue pages 多入口項(xiàng)目 + chainWebpack 全局引用縮寫說明

    這篇文章主要介紹了vue pages 多入口項(xiàng)目 + chainWebpack 全局引用縮寫說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • VUE2中的MVVM模式詳解

    VUE2中的MVVM模式詳解

    這篇文章主要為大家介紹了VUE2中的MVVM模式詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-05-05
  • Vue下載不同文件的幾種方式總結(jié)

    Vue下載不同文件的幾種方式總結(jié)

    在Vue項(xiàng)目中實(shí)現(xiàn)文件下載有多種方式,包括使用window.open、<a>標(biāo)簽、axios、FetchAPI、自定義$download方法以及創(chuàng)建a標(biāo)簽等,每種方法都有其適用場(chǎng)景,開發(fā)者可以根據(jù)項(xiàng)目需求選擇最合適的方式
    2025-01-01
  • Vue中this.$router.push參數(shù)獲取方法

    Vue中this.$router.push參數(shù)獲取方法

    下面小編就為大家分享一篇Vue中this.$router.push參數(shù)獲取方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-02-02
  • 詳解Vue爬坑之vuex初識(shí)

    詳解Vue爬坑之vuex初識(shí)

    本篇文章主要介紹了詳解Vue爬坑之vuex初識(shí) ,Vue 的狀態(tài)管理工具 Vuex可以解決大型項(xiàng)目中子組件之間傳遞數(shù)據(jù),有興趣的可以了解下
    2017-06-06
  • vue移動(dòng)端下拉刷新和上拉加載的實(shí)現(xiàn)代碼

    vue移動(dòng)端下拉刷新和上拉加載的實(shí)現(xiàn)代碼

    這篇文章主要介紹了vue移動(dòng)端下拉刷新和上拉加載的實(shí)現(xiàn)代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-09-09

最新評(píng)論