最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue3如何實(shí)現(xiàn)內(nèi)嵌iframe文檔顯示功能

 更新時(shí)間:2025年05月15日 08:30:27   作者:九月TTS  
這篇文章主要為大家詳細(xì)介紹了如何在Vue3項(xiàng)目中優(yōu)雅地實(shí)現(xiàn)內(nèi)嵌iframe功能,用于加載外部文檔內(nèi)容,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

內(nèi)嵌iframe的應(yīng)用場(chǎng)景與價(jià)值

在現(xiàn)代Web應(yīng)用中,內(nèi)嵌iframe是集成外部?jī)?nèi)容的有效方式,特別適用于以下場(chǎng)景:

  • 展示項(xiàng)目文檔:直接嵌入項(xiàng)目文檔網(wǎng)站,避免用戶在多個(gè)標(biāo)簽頁(yè)切換
  • 整合第三方內(nèi)容:無(wú)需重新開(kāi)發(fā),直接復(fù)用已有的Web資源
  • 隔離運(yùn)行環(huán)境:為外部?jī)?nèi)容提供獨(dú)立的執(zhí)行環(huán)境,避免與主應(yīng)用沖突
  • 保持UI一致性:讓外部?jī)?nèi)容看起來(lái)像是應(yīng)用的一部分,提升用戶體驗(yàn)
  • 降低開(kāi)發(fā)成本:避免重復(fù)開(kāi)發(fā)相似功能,專注于核心業(yè)務(wù)邏輯

在TTS-Web-Vue項(xiàng)目中,我們使用內(nèi)嵌iframe來(lái)加載項(xiàng)目文檔,使用戶能夠在不離開(kāi)應(yīng)用的情況下查閱使用指南、API文檔和其他參考資料。

實(shí)現(xiàn)思路與技術(shù)選型

整體設(shè)計(jì)方案

我們的iframe嵌入方案采用了以下設(shè)計(jì)思路:

  • 響應(yīng)式狀態(tài)管理:使用Vue3的響應(yīng)式系統(tǒng)管理iframe的加載狀態(tài)
  • 異常處理機(jī)制:完善的錯(cuò)誤處理和恢復(fù)策略,提供友好的錯(cuò)誤界面
  • 動(dòng)態(tài)樣式調(diào)整:根據(jù)內(nèi)容和容器大小動(dòng)態(tài)調(diào)整iframe尺寸
  • 跨域安全處理:合理設(shè)置sandbox屬性和referrer策略,確保安全性
  • 加載狀態(tài)反饋:提供視覺(jué)反饋,優(yōu)化用戶等待體驗(yàn)
  • 備用方案支持:支持多個(gè)文檔源,在主源不可用時(shí)提供備選鏈接

這種方案既保證了功能的完整性,又提供了良好的用戶體驗(yàn)和可維護(hù)性。

技術(shù)實(shí)現(xiàn)要點(diǎn)

  • 使用Vue3的ref和watch實(shí)現(xiàn)響應(yīng)式狀態(tài)管理
  • 通過(guò)DOM API動(dòng)態(tài)調(diào)整iframe樣式和容器布局
  • 利用Element Plus組件庫(kù)提供加載和錯(cuò)誤界面
  • 使用PostMessage API實(shí)現(xiàn)iframe與主應(yīng)用的通信
  • 結(jié)合CSS動(dòng)畫提升加載體驗(yàn)

核心代碼實(shí)現(xiàn)

主組件模板代碼

在Main.vue中,我們實(shí)現(xiàn)了文檔頁(yè)面容器和iframe的基本結(jié)構(gòu):

<div v-if="page.asideIndex === '4'" class="doc-page-container" :key="'doc-page'">
  <!-- 加載狀態(tài)顯示 -->
  <div v-if="!iframeLoaded && !iframeError" class="iframe-loading">
    <div class="loading-spinner"></div>
    <p>正在加載文檔<span class="loading-dots"></span></p>
  </div>
  
  <!-- iframe組件 -->
  <iframe 
    ref="docIframe"
    class="doc-frame" 
    :src="iframeCurrentSrc" 
    @load="handleIframeLoad"
    @error="handleIframeError"
    allow="fullscreen"
    referrerpolicy="no-referrer"
    :class="{'iframe-visible': iframeLoaded}"
    sandbox="allow-scripts allow-same-origin allow-popups allow-forms"
  >
  </iframe>
  
  <!-- 錯(cuò)誤狀態(tài)顯示 -->
  <div v-if="iframeError" class="iframe-error">
    <el-icon class="error-icon"><WarningFilled /></el-icon>
    <p>加載文檔失敗,請(qǐng)檢查網(wǎng)絡(luò)連接或嘗試備用鏈接。</p>
    <div class="error-actions">
      <el-button type="primary" @click="reloadIframe">
        <el-icon><RefreshRight /></el-icon> 重新加載
      </el-button>
      <el-button @click="tryAlternativeUrl">
        <el-icon><SwitchButton /></el-icon> 嘗試備用鏈接
      </el-button>
    </div>
  </div>
</div>

狀態(tài)管理與初始化

在組合式API中管理iframe相關(guān)的狀態(tài):

// 聲明狀態(tài)變量
const docIframe = ref(null);
const iframeLoaded = ref(false);
const iframeError = ref(false);
const docUrl = ref('https://docs.tts88.top/');
const urlIndex = ref(0);
const iframeCurrentSrc = ref('');
const docUrls = [
  'https://docs.tts88.top/',
  // 可以添加備用鏈接
];

// iframe初始化函數(shù)
const initIframe = () => {
  iframeCurrentSrc.value = '';
  
  // 在清除src后,立即設(shè)置容器和iframe樣式以確保正確顯示
  nextTick(() => {
    // 修改頁(yè)面主容器樣式,保留基本結(jié)構(gòu)但減少內(nèi)邊距
    const mainContainer = document.querySelector('.modern-main');
    if (mainContainer instanceof HTMLElement && page?.value?.asideIndex === '4') {
      mainContainer.style.padding = '0';
      mainContainer.style.gap = '0';
    }
    
    const container = document.querySelector('.doc-page-container');
    if (container instanceof HTMLElement) {
      // 設(shè)置文檔容器填充可用空間,但不使用fixed定位
      container.style.display = 'flex';
      container.style.flexDirection = 'column';
      container.style.height = 'calc(100vh - 40px)'; // 只預(yù)留頂部導(dǎo)航欄的空間
      container.style.margin = '0';
      container.style.padding = '0';
      container.style.borderRadius = '0';
      container.style.boxShadow = 'none';
      container.style.position = 'relative';
    }
    
    if (docIframe.value) {
      docIframe.value.style.display = 'block';
      docIframe.value.style.flex = '1';
      docIframe.value.style.width = '100%';
      docIframe.value.style.height = '100%';
      docIframe.value.style.minHeight = '700px';
      docIframe.value.style.maxHeight = 'none';
      docIframe.value.style.margin = '0';
      docIframe.value.style.padding = '0';
      docIframe.value.style.border = 'none';
      docIframe.value.style.borderRadius = '0';
    }
    
    // 設(shè)置iframe源
    iframeCurrentSrc.value = docUrl.value;
    console.log('iframe 初始化源設(shè)置為:', docUrl.value);
  });
};

事件處理函數(shù)

處理iframe的加載和錯(cuò)誤事件:

// 處理 iframe 加載成功
const handleIframeLoad = (event) => {
  console.log('iframe 加載事件觸發(fā)');
  
  // 檢查iframe是否完全加載且可訪問(wèn)
  try {
    const iframe = event.target;
    
    // 不是所有iframe都會(huì)觸發(fā)跨域報(bào)錯(cuò),但我們需要檢查是否實(shí)際加載成功
    if (iframe.contentWindow && iframe.src.includes(docUrl.value)) {
      iframeLoaded.value = true;
      iframeError.value = false;
      
      console.log('iframe 加載成功:', {
        width: iframe.offsetWidth,
        height: iframe.offsetHeight
      });
      
      // 嘗試調(diào)整iframe高度
      nextTick(() => {
        adjustIframeHeight();
        // 發(fā)送初始化消息到iframe
        sendInitMessageToIframe();
      });
      
      // 顯示加載成功提示
      ElMessage({
        message: "文檔加載成功",
        type: "success",
        duration: 2000,
      });
    } else {
      console.warn('iframe可能加載不完整或存在跨域問(wèn)題');
    }
  } catch (error) {
    // 處理跨域安全限制導(dǎo)致的錯(cuò)誤
    console.error('檢查iframe出錯(cuò) (可能是跨域問(wèn)題):', error);
    // 我們不將這種情況標(biāo)記為錯(cuò)誤,因?yàn)閕frame可能仍然正常加載
    iframeLoaded.value = true;
  }
};

// 處理 iframe 加載失敗
const handleIframeError = (event) => {
  console.error('iframe 加載失敗:', event);
  iframeLoaded.value = false;
  iframeError.value = true;
  
  ElMessage({
    message: "文檔加載失敗,請(qǐng)檢查網(wǎng)絡(luò)連接",
    type: "error",
    duration: 3000,
  });
};

// 重新加載 iframe
const reloadIframe = () => {
  console.log('重新加載 iframe');
  iframeLoaded.value = false;
  iframeError.value = false;
  
  // 強(qiáng)制 iframe 重新加載
  initIframe();
  
  ElMessage({
    message: "正在重新加載文檔",
    type: "info",
    duration: 2000,
  });
};

???????// 嘗試使用備用鏈接
const tryAlternativeUrl = () => {
  urlIndex.value = (urlIndex.value + 1) % docUrls.length;
  docUrl.value = docUrls[urlIndex.value];
  console.log(`嘗試備用文檔鏈接: ${docUrl.value}`);
  
  iframeLoaded.value = false;
  iframeError.value = false;
  
  // 清空并重新設(shè)置src以確保重新加載
  initIframe();
  
  ElMessage({
    message: `正在嘗試備用鏈接: ${docUrl.value}`,
    type: "info",
    duration: 3000,
  });
};

樣式和動(dòng)畫設(shè)計(jì)

為iframe相關(guān)組件添加樣式:

.iframe-loading, .iframe-error {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  background-color: var(--card-background);
  z-index: 1000;
  text-align: center;
}

.iframe-loading {
  font-size: 18px;
  font-weight: 600;
  color: var(--text-primary);
}

.loading-spinner {
  width: 40px;
  height: 40px;
  border: 4px solid rgba(74, 108, 247, 0.2);
  border-radius: 50%;
  border-top-color: var(--primary-color);
  animation: spin 1s linear infinite;
  margin-bottom: 16px;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

.iframe-error {
  padding: 30px;
  background-color: var(--card-background);
}

.iframe-error p {
  margin: 16px 0;
  font-size: 16px;
  color: var(--text-secondary);
}

.error-icon {
  font-size: 48px;
  color: #ff4757;
  margin-bottom: 16px;
}

.error-actions {
  display: flex;
  gap: 16px;
  margin-top: 16px;
}

.loading-dots {
  display: inline-block;
  width: 30px;
  text-align: left;
}

.loading-dots:after {
  content: '.';
  animation: dots 1.5s steps(5, end) infinite;
}

@keyframes dots {
  0%, 20% {
    content: '.';
  }
  40% {
    content: '..';
  }
  60% {
    content: '...';
  }
  80%, 100% {
    content: '';
  }
}

跨域通信實(shí)現(xiàn)

發(fā)送消息到iframe

通過(guò)postMessage API實(shí)現(xiàn)與iframe內(nèi)容的通信:

// 向iframe發(fā)送消息
const sendMessageToIframe = (message) => {
  if (docIframe.value && docIframe.value.contentWindow) {
    try {
      docIframe.value.contentWindow.postMessage(message, '*');
      console.log('向iframe發(fā)送消息:', message);
    } catch (error) {
      console.error('向iframe發(fā)送消息失敗:', error);
    }
  }
};

// 在iframe加載完成后發(fā)送初始化消息
const sendInitMessageToIframe = () => {
  // 等待iframe完全加載
  setTimeout(() => {
    sendMessageToIframe({
      type: 'init',
      appInfo: {
        name: 'TTS Web Vue',
        version: '1.0',
        theme: document.body.classList.contains('dark-theme') ? 'dark' : 'light'
      }
    });
  }, 1000);
};

接收來(lái)自iframe的消息

監(jiān)聽(tīng)并處理iframe發(fā)送的消息:

// 處理來(lái)自iframe的消息
const handleIframeMessage = (event) => {
  console.log('收到消息:', event);
  
  // 確保消息來(lái)源安全,驗(yàn)證來(lái)源域名
  const isValidOrigin = docUrls.some(url => {
    try {
      const urlHost = new URL(url).hostname;
      return event.origin.includes(urlHost);
    } catch (e) {
      return false;
    }
  });
  
  // 如果消息來(lái)源不安全,忽略此消息
  if (!isValidOrigin) {
    console.warn('收到來(lái)自未知來(lái)源的消息,已忽略:', event.origin);
    return;
  }
  
  console.log('來(lái)自文檔頁(yè)面的消息:', event.data);
  
  // 處理不同類型的消息
  if (typeof event.data === 'object' && event.data !== null) {
    // 文檔加載完成消息
    if (event.data.type === 'docLoaded') {
      iframeLoaded.value = true;
      iframeError.value = false;
      
      ElMessage({
        message: "文檔頁(yè)面已準(zhǔn)備就緒",
        type: "success",
        duration: 2000,
      });
      
      // 對(duì)iframe內(nèi)容回送確認(rèn)消息
      sendMessageToIframe({
        type: 'docLoadedConfirm',
        status: 'success'
      });
    }
    
    // 調(diào)整高度消息
    if (event.data.type === 'resizeHeight' && typeof event.data.height === 'number') {
      const height = event.data.height;
      if (height > 0 && docIframe.value) {
        // 確保高度合理
        const safeHeight = Math.max(Math.min(height, 5000), 300);
        docIframe.value.style.height = `${safeHeight}px`;
        console.log(`根據(jù)iframe請(qǐng)求調(diào)整高度: ${safeHeight}px`);
      }
    }
  }
};

// 在組件掛載時(shí)添加消息監(jiān)聽(tīng)器
onMounted(() => {
  window.addEventListener('message', handleIframeMessage);
});

???????// 在組件卸載時(shí)移除監(jiān)聽(tīng)器
onUnmounted(() => {
  window.removeEventListener('message', handleIframeMessage);
});

自適應(yīng)布局實(shí)現(xiàn)

響應(yīng)式高度調(diào)整

動(dòng)態(tài)調(diào)整iframe高度以適應(yīng)不同屏幕尺寸:

// 添加新函數(shù)用于調(diào)整iframe高度
const adjustIframeHeight = () => {
  if (!docIframe.value) return;
  
  // 獲取容器高度
  const container = document.querySelector('.doc-page-container');
  if (!container) return;
  
  // 修改頁(yè)面主容器樣式,減少內(nèi)邊距但保留基本布局
  const mainContainer = document.querySelector('.modern-main');
  if (mainContainer instanceof HTMLElement && page?.value?.asideIndex === '4') {
    mainContainer.style.padding = '0';
    mainContainer.style.gap = '0';
  }
  
  // 獲取可用高度(視口高度減去頂部導(dǎo)航欄高度)
  const availableHeight = window.innerHeight - 40;
  
  // 設(shè)置container樣式以充分利用可用空間
  if (container instanceof HTMLElement) {
    container.style.height = `${availableHeight}px`;
    container.style.maxHeight = `${availableHeight}px`;
    container.style.margin = '0';
    container.style.padding = '0';
    container.style.borderRadius = '0';
    container.style.boxShadow = 'none';
    container.style.position = 'relative';
  }
  
  // 設(shè)置iframe樣式以充滿容器
  docIframe.value.style.width = '100%';
  docIframe.value.style.height = '100%';
  docIframe.value.style.minHeight = '700px';
  docIframe.value.style.maxHeight = 'none';
  docIframe.value.style.display = 'block';
  docIframe.value.style.flex = '1';
  docIframe.value.style.margin = '0';
  docIframe.value.style.padding = '0';
  docIframe.value.style.border = 'none';
  docIframe.value.style.borderRadius = '0';
};

// 監(jiān)聽(tīng)窗口大小變化事件
const handleResize = () => {
  if (page?.value?.asideIndex === '4' && iframeLoaded.value) {
    adjustIframeHeight();
  }
};

// 在組件掛載和窗口大小變化時(shí)調(diào)整高度
onMounted(() => {
  window.addEventListener('resize', handleResize);
});

???????onUnmounted(() => {
  window.removeEventListener('resize', handleResize);
});

移動(dòng)端顯示優(yōu)化

為移動(dòng)設(shè)備添加特定的樣式調(diào)整:

@media (max-width: 768px) {
  .doc-page-container {
    height: calc(100vh - 50px) !important; /* 為移動(dòng)端頂部導(dǎo)航欄留出更多空間 */
  }
  
  .iframe-loading p, .iframe-error p {
    font-size: 14px;
    padding: 0 20px;
  }
  
  .error-actions {
    flex-direction: column;
    width: 80%;
  }
  
  .loading-spinner {
    width: 30px;
    height: 30px;
  }
}

安全性考慮

iframe安全屬性設(shè)置

為確保iframe的安全性,我們?cè)O(shè)置了以下關(guān)鍵屬性:

<iframe 
  ref="docIframe"
  class="doc-frame" 
  :src="iframeCurrentSrc" 
  @load="handleIframeLoad"
  @error="handleIframeError"
  allow="fullscreen"
  referrerpolicy="no-referrer"
  :class="{'iframe-visible': iframeLoaded}"
  sandbox="allow-scripts allow-same-origin allow-popups allow-forms"
>
</iframe>

主要安全措施包括:

1.sandbox屬性:限制iframe內(nèi)容的權(quán)限,僅允許必要的功能

  • allow-scripts: 允許運(yùn)行腳本
  • allow-same-origin: 允許訪問(wèn)同源資源
  • allow-popups: 允許打開(kāi)新窗口
  • allow-forms: 允許表單提交

2.referrerpolicy:設(shè)置為no-referrer防止泄露引用信息

3.消息驗(yàn)證:驗(yàn)證接收消息的來(lái)源,防止惡意站點(diǎn)發(fā)送的消息

跨域消息驗(yàn)證

在處理iframe消息時(shí)進(jìn)行來(lái)源驗(yàn)證:

// 確保消息來(lái)源安全,驗(yàn)證來(lái)源域名
const isValidOrigin = docUrls.some(url => {
  try {
    const urlHost = new URL(url).hostname;
    return event.origin.includes(urlHost);
  } catch (e) {
    return false;
  }
});

// 如果消息來(lái)源不安全,忽略此消息
if (!isValidOrigin) {
  console.warn('收到來(lái)自未知來(lái)源的消息,已忽略:', event.origin);
  return;
}

用戶體驗(yàn)增強(qiáng)

加載狀態(tài)優(yōu)化

為提供更好的視覺(jué)反饋,我們添加了加載動(dòng)畫和進(jìn)度指示:

<div v-if="!iframeLoaded && !iframeError" class="iframe-loading">
  <div class="loading-spinner"></div>
  <p>正在加載文檔<span class="loading-dots"></span></p>
</div>

動(dòng)畫效果通過(guò)CSS實(shí)現(xiàn):

.loading-spinner {
  width: 40px;
  height: 40px;
  border: 4px solid rgba(74, 108, 247, 0.2);
  border-radius: 50%;
  border-top-color: var(--primary-color);
  animation: spin 1s linear infinite;
  margin-bottom: 16px;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

.loading-dots:after {
  content: '.';
  animation: dots 1.5s steps(5, end) infinite;
}

@keyframes dots {
  0%, 20% {
    content: '.';
  }
  40% {
    content: '..';
  }
  60% {
    content: '...';
  }
  80%, 100% {
    content: '';
  }
}

錯(cuò)誤處理與恢復(fù)

提供直觀的錯(cuò)誤界面和恢復(fù)選項(xiàng):

<div v-if="iframeError" class="iframe-error">
  <el-icon class="error-icon"><WarningFilled /></el-icon>
  <p>加載文檔失敗,請(qǐng)檢查網(wǎng)絡(luò)連接或嘗試備用鏈接。</p>
  <div class="error-actions">
    <el-button type="primary" @click="reloadIframe">
      <el-icon><RefreshRight /></el-icon> 重新加載
    </el-button>
    <el-button @click="tryAlternativeUrl">
      <el-icon><SwitchButton /></el-icon> 嘗試備用鏈接
    </el-button>
  </div>
</div>

性能優(yōu)化

減少重繪和回流

為提高iframe加載性能,我們采取了以下優(yōu)化措施:

// 先將iframe的src設(shè)為空,然后再設(shè)置目標(biāo)URL,減少重復(fù)加載
iframeCurrentSrc.value = '';

// 使用nextTick等待DOM更新后再進(jìn)行樣式調(diào)整
nextTick(() => {
  // 樣式調(diào)整代碼...
  
  // 最后再設(shè)置src
  iframeCurrentSrc.value = docUrl.value;
});

延遲加載與可見(jiàn)性優(yōu)化

只有在iframe加載完成后才顯示內(nèi)容,避免閃爍:

<iframe 
  :class="{'iframe-visible': iframeLoaded}"
  <!-- 其他屬性... -->
>
</iframe>
.doc-frame {
  opacity: 0;
  transition: opacity 0.3s ease;
}

.iframe-visible {
  opacity: 1;
}

總結(jié)與拓展

主要成果

通過(guò)Vue3實(shí)現(xiàn)內(nèi)嵌iframe,我們?yōu)門TS-Web-Vue項(xiàng)目帶來(lái)了以下價(jià)值:

  • 一體化用戶體驗(yàn):用戶無(wú)需離開(kāi)應(yīng)用即可訪問(wèn)文檔
  • 響應(yīng)式布局:自適應(yīng)不同屏幕尺寸,優(yōu)化移動(dòng)端體驗(yàn)
  • 完善的狀態(tài)管理:處理加載、錯(cuò)誤等各種狀態(tài),提升用戶體驗(yàn)
  • 安全可控:通過(guò)sandbox和消息驗(yàn)證確保安全性
  • 高性能:優(yōu)化加載過(guò)程,減少性能開(kāi)銷

未來(lái)可能的拓展方向

  • 內(nèi)容預(yù)加載:實(shí)現(xiàn)文檔預(yù)加載,進(jìn)一步提升加載速度
  • 深度鏈接:支持直接鏈接到文檔的特定部分
  • 離線支持:加入文檔緩存功能,支持離線訪問(wèn)
  • 內(nèi)容同步:實(shí)現(xiàn)iframe內(nèi)容與應(yīng)用狀態(tài)的雙向同步
  • 多文檔管理:支持多個(gè)文檔源和文檔切換功能

到此這篇關(guān)于Vue3如何實(shí)現(xiàn)內(nèi)嵌iframe文檔顯示功能的文章就介紹到這了,更多相關(guān)Vue3內(nèi)嵌iframe內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vue 不使用select實(shí)現(xiàn)下拉框功能(推薦)

    vue 不使用select實(shí)現(xiàn)下拉框功能(推薦)

    這篇文章主要介紹了vue 不使用select實(shí)現(xiàn)下拉框功能,在文章給大家提到了vue select 組件的使用與禁用,需要的朋友可以參考下
    2018-05-05
  • 前端vue+elementUI如何實(shí)現(xiàn)記住密碼功能

    前端vue+elementUI如何實(shí)現(xiàn)記住密碼功能

    這篇文章主要給大家介紹了關(guān)于vue+elementUI如何實(shí)現(xiàn)記住密碼功能的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • Vue3開(kāi)發(fā)右鍵菜單的示例詳解

    Vue3開(kāi)發(fā)右鍵菜單的示例詳解

    右鍵菜單在項(xiàng)目開(kāi)發(fā)中是屬于比較高頻的組件了,所以這篇文章小編主要來(lái)和大家介紹一下如何利用vue3開(kāi)發(fā)一個(gè)右鍵菜單,有需要的可以參考下
    2024-03-03
  • vue.js實(shí)現(xiàn)簡(jiǎn)單購(gòu)物車功能

    vue.js實(shí)現(xiàn)簡(jiǎn)單購(gòu)物車功能

    這篇文章主要為大家詳細(xì)介紹了vue.js實(shí)現(xiàn)簡(jiǎn)單購(gòu)物車功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • uniapp和vue如何獲取屏幕或盒子內(nèi)容的寬高

    uniapp和vue如何獲取屏幕或盒子內(nèi)容的寬高

    在實(shí)際開(kāi)發(fā)中我們會(huì)遇到不確定高度的情況,下面這篇文章主要給大家介紹了關(guān)于uniapp和vue如何獲取屏幕或盒子內(nèi)容的寬高,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-02-02
  • vue-cli安裝使用流程步驟詳解

    vue-cli安裝使用流程步驟詳解

    這篇文章主要介紹了 vue-cli安裝使用流程,本文分步驟給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-11-11
  • 淺談vuex actions和mutation的異曲同工

    淺談vuex actions和mutation的異曲同工

    這篇文章主要介紹了淺談vuex actions和mutation的異曲同工 ,詳細(xì)的介紹了actions和mutation的使用和區(qū)別,非常具有實(shí)用價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-12-12
  • webstorm和.vue中es6語(yǔ)法報(bào)錯(cuò)的解決方法

    webstorm和.vue中es6語(yǔ)法報(bào)錯(cuò)的解決方法

    本篇文章主要介紹了webstorm和.vue中es6語(yǔ)法報(bào)錯(cuò)的解決方法,小編總結(jié)了webstorm和.vue中出現(xiàn)的es6語(yǔ)法報(bào)錯(cuò),避免大家采坑,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-05-05
  • Vue中的computed與watch底層實(shí)現(xiàn)原理最佳實(shí)踐

    Vue中的computed與watch底層實(shí)現(xiàn)原理最佳實(shí)踐

    本文介紹Vue中computed和watch的底層實(shí)現(xiàn)原理,對(duì)比了核心概念、設(shè)計(jì)差異以及使用場(chǎng)景,通過(guò)分析computed的初始化、依賴追蹤、緩存機(jī)制,以及watch的初始化、深度監(jiān)聽(tīng)、異步更新,本文提供了一個(gè)全面的對(duì)比總結(jié),并給出了性能優(yōu)化和最佳實(shí)踐建議,感興趣的朋友一起看看吧
    2026-01-01
  • Vuex給state中的對(duì)象新添加屬性遇到的問(wèn)題及解決

    Vuex給state中的對(duì)象新添加屬性遇到的問(wèn)題及解決

    這篇文章主要介紹了Vuex給state中的對(duì)象新添加屬性遇到的問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-01-01

最新評(píng)論

博野县| 琼海市| 吉水县| 白城市| 巫山县| 文山县| 凌海市| 太和县| 霍山县| 任丘市| 托里县| 秦皇岛市| 堆龙德庆县| 太仆寺旗| 乌审旗| 宁河县| 淅川县| 静乐县| 双江| 婺源县| 临猗县| 柞水县| 闽清县| 苗栗市| 河津市| 淮阳县| 河南省| 峨边| 合阳县| 光泽县| 和平县| 利津县| 蓬溪县| 武邑县| 南靖县| 宁海县| 砀山县| 沅陵县| 土默特右旗| 广东省| 南召县|