目錄
Here are some slots
A wrapped slot
那么,为什么我们希望能够有条件地渲染插槽呢?
This is a pretty great component, amirite?
{{ heading }}
首頁 web前端 Vue.js 25個值得了解的Vue小技巧,原來還能這麼用!

25個值得了解的Vue小技巧,原來還能這麼用!

May 20, 2022 am 10:49 AM
vue vue.js

這篇文章總結整理25個Vue小技巧,學了這麼久才知道還能這麼用,現在分享給大家,希望對大家有所幫助,讓程式設計生活變得更容易!

25個值得了解的Vue小技巧,原來還能這麼用!

學習成為一個更好的Vue開發者並不總是關於那些需要花時間和精力才能掌握的大概念。掌握一些技巧和訣竅,可以讓我們的程式設計生活變得更容易--沒有大量重複的工作。

在用 Vue 開發的這幾年裡,我學到了很多有用的技巧。有些很取巧,有些幾乎每天都在用,有些則更高級--但它們都很有用。 (學習影片分享:vue影片教學

1、將一個prop 限制在一個類型的清單中

使用prop 定義中的 validator 選項,可以將一個prop 類型限制在一組特定的值中。

export default {
  name: 'Image',
  props: {
    src: {
      type: String,
    },
    style: {
      type: String,
      validator: s => ['square', 'rounded'].includes(s)
    }
  }
};
登入後複製

這個驗證函數接受一個prop,如果prop有效或無效,則傳回truefalse

當單單傳入的 true 或 false 來控制某些條件無法滿足需求時,我通常會使用這個方法來做。

按鈕類型或警告類型(訊息、成功、危險、警告)是最常見的用法、、。顏色也是一個很好的用途。

2、預設內容和擴充點

Vue中的插槽可以有預設的內容,這使我們可以製作出更容易使用的組件。

<button class="button" @click="$emit(&#39;click&#39;)">
  <slot>
    <!-- Used if no slot is provided -->
    Click me
  </slot>
</button>
登入後複製

我最喜歡使用預設槽,就是用它們來建立擴充點。

我們可以取元件的任何部分,將其封裝在一個插槽中,在外面我們可以用想要的任何內容覆蓋元件的該部分。預設情況下,它仍然會按照原來的方式工作,但這樣做會有了更多的選項

<template>
  <button class="button" @click="$emit(&#39;click&#39;)">
    <slot>
      <div class="formatting">
        {{ text }}
      </div>
    </slot>
  </button>
</template>
登入後複製

現在我們可以用許多不同的方式使用這個元件。簡單的、預設的方式,或是自訂的方式。

<!-- Uses default functionality of the component -->
<ButtonWithExtensionPoint text="Formatted text" />

<ButtonWithExtensionPoint>
  <div class="different-formatting">
    Do something a little different here
  </div>
</ButtonWithExtensionPoint>
登入後複製

3、使用引號來監聽巢狀屬性

#你可能不知道這一點,我們可以透過使用引號輕鬆地直接監聽巢狀值:

watch {
  &#39;$route.query.id&#39;() {
    // ...
  }
}
登入後複製

4、知道何時使用<span style="font-size: 18px;">v-if</span>(以及何時避免使用)

與其使用v-if,有時使用v-show來代替,會有更高的效能。

<ComplicatedChart v-show="chartEnabled" />
登入後複製

v-if被開啟或關閉時,它將建立並完全銷毀該元素。相反,v-show將創建該元素並將其留在那裡,透過將其樣式設定為display: none來隱藏它。

如果你要切換的元件的渲染成本很高,那麼這樣做會更有效率。

反過來說,如果不需要立即執行昂貴的元件件,可以使用v-if,這樣它就會跳過渲染它,而使頁面的載入速度更快一些。

5、單一作用域插槽的簡寫(不需要template 標籤)

限定範圍的插槽非常有趣,但為了使用它們,您還必須使用許多模板標記。

幸運的是,有一個簡寫可以讓我們擺脫它,但只有在我們使用單一作用域槽的情況下。

普通寫法:

<DataTable>
  <template #header="tableAttributes">
    <TableHeader v-bind="tableAttributes" />
  </template>
</DataTable>
登入後複製

不使用 template:

<DataTable #header="tableAttributes">
  <TableHeader v-bind="tableAttributes" />
</DataTable>
登入後複製

簡單、直截了當,令人讚嘆不已。

6、有條件地渲染插槽

我們先來看如何做,然後在討論為什麼要隱藏插槽。

每個Vue組件都有一個特殊的$slots對象,裡面有你所有的插槽。預設槽的鍵是default,任何被命名的槽都使用其名稱作為鍵。

const $slots = {
  default: <default slot>,
  icon: <icon slot>,
  button: <button slot>,
};
登入後複製

但這個$slots物件只有適用於該元件的插槽,而不是每一個定義的插槽。

拿這個定義了幾個插槽的元件來說,包含幾個命名的插槽。

<!-- Slots.vue -->
<template>
  <div>
    <h2 id="Here-nbsp-are-nbsp-some-nbsp-slots">Here are some slots</h2>
    <slot />
    <slot name="second" />
    <slot name="third" />
  </div>
</template>
登入後複製

如果我們只對元件套用一個插槽,那麼只有那個插槽會顯示在我們的$slots物件中。

<template>
  <Slots>
    <template #second>
      This will be applied to the second slot.
    </template>
  </Slots>
</template>
登入後複製
$slots = { second: <vnode> }
登入後複製

我們可以在我們的元件中使用這一點來偵測哪些插槽已經被應用到元件中,例如,透過隱藏插槽的包裝元素。

<template>
  <div>
    <h2 id="A-nbsp-wrapped-nbsp-slot">A wrapped slot</h2>
    <div v-if="$slots.default" class="styles">
      <slot />
    </div>
  </div>
</template>
登入後複製

現在,套用樣式的包裝器div只有在我們用某些東西填滿這個插槽時才會被渲染。

如果不使用v-if,那麼如果沒有插槽,就會得到一個空的不必要的div。根據div的樣式,這可能會打亂我們的佈局,讓介面看起來很奇怪。

那么,为什么我们希望能够有条件地渲染插槽呢?

使用条件插槽的主要原因有三个:

  • 当使用封装的div来添加默认样式时
  • 插槽是空的
  • 如果我们将默认内容与嵌套槽相结合

例如,当我们在添加默认样式时,我们在插槽周围添加一个div:

<template>
  <div>
    <h2 id="This-nbsp-is-nbsp-a-nbsp-pretty-nbsp-great-nbsp-component-nbsp-amirite">This is a pretty great component, amirite?</h2>
    <div class="default-styling">
      <slot >
    </div>
    <button @click="$emit(&#39;click&#39;)">Click me!</button>
  </div>
</template>
登入後複製

然而,如果父组件没有将内容应用到该插槽中,我们最终会在页面上渲染出一个空的div

<div>
  <h2 id="This-nbsp-is-nbsp-a-nbsp-pretty-nbsp-great-nbsp-component-nbsp-amirite">This is a pretty great component, amirite?</h2>
  <div class="default-styling">
    <!-- 槽中没有内容,但这个div 仍然被渲染。糟糕 -->
  </div>
  <button @click="$emit(&#39;click&#39;)">Click me!</button>
</div>
登入後複製

解决方法就是像上面讲的一样,多个条件判断,就行啦。

7、如何监听一个插槽的变化

有时我们需要知道插槽内的内容何时发生了变化。

<!-- 可惜这个事件不存在 -->
<slot @change="update" />
登入後複製

不幸的是,Vue没有内置的方法让我们检测这一点。

然而,我的朋友Austin想出了一个非常干净的方法,使用MutationObserver来做这件事。

MutationObserver接口提供了监视对DOM树所做更改的能力。它被设计为旧的Mutation Events功能的替代品,该功能是DOM3 Events规范的一部分。

export default {
  mounted() {
    // 当有变化时调用`update`
    const observer = new MutationObserver(this.update);

    // 监听此组件的变化
    observer.observe(this.$el, {
      childList: true,
      subtree: true
    });
  }
};
登入後複製

这个涉及的内容还是很多的,后面会单独出一篇文章来讲,记得关注刷碗智的公众号 <大迁世界> 哦

8、将局部和全局的 <span style="font-size: 18px;">style</span>混合在一起

通常情况下,在处理样式时,我们希望它们能被划分到一个单独的组件中。

<style scoped>
  .component {
    background: green;
  }
</style>
登入後複製

不过,如果需要的话,也可以添加一个非作用域样式块来添加全局样式

<style>
  /* 全局 */
  .component p {
    margin-bottom: 16px;
  }
</style>

<style scoped>
  /* 在该组件内有效 */
  .component {
    background: green;
  }
</style>
登入後複製

但要小心,全局样式是危险的,难以追踪。但有时,它们是一个完美的逃生舱口,正是你所需要的。

9、重写子组件的样式--正确的方法

Scoped CSS在保持内容整洁方面非常棒,而且不会将样式引入应用的其他组件中。

但有时你需要覆盖一个子组件的样式,并跳出这个作用域。

Vue有一个 deep 选择器:

<style scoped>
.my-component >>> .child-component {
  font-size: 24px;
}
</style>
登入後複製

注意:如果你使用像SCSS这样的CSS预处理器,你可能需要使用/deep/来代替。

10、用上下文感知组件创造魔法

**上下文感知组件(context-aware)**是“魔法的”,它们自动适应周围发生的事情,处理边缘情况、状态共享等等。

有3种主要的 context-aware ,但 Configuration 是我最感兴趣的一种。

1)状态共享

当你把一个大的组件分解成多个小的组件时,它们往往仍然需要共享状态。

我们可以在 "幕后 "做这些工作,而不是把这些工作推给使用者。

我们一般会把 Dropdown 组件分解成 SelectOption 组件,这样会获得更多的灵活性。但是为了方便使用,SelectOption组件彼此共享 selected 状态。

<!-- 为简单起见,作为一个单一组件使用 -->
<Dropdown v-model="selected" :options="[]" />

<!-- 分多个组件,更灵活 -->
<Select v-model="selected">
  <Option value="mustard">Mustard</Option>
  <Option value="ketchup">Ketchup</Option>
  <div class="relish-wrapper">
    <Option value="relish">Relish</Option>
  </div>
</Select>
登入後複製

2) Configuration

有时,一个组件的行为需要根据应用程序的其他部分的情况来改变。这通常是为了自动处理边缘情况,否则处理起来会很烦人。

一个 PopupTooltip 应该重新定位,以便它不会溢出页面。但是,如果该组件是在一个modal 内,它应该重新定位,以便它不会溢出 modal。

如果Tooltip知道它是在一个模态里面,这可以自动完成。

3)样式

创建了 context-aware的CSS,根据父级或同级元素的情况应用不同的样式。

.statistic {
  color: black;
  font-size: 24px;
  font-weight: bold;
}

.statistic + .statistic {
  margin-left: 10px;
}
登入後複製

CSS变量让我们更进一步,允许我们在一个页面的不同部分设置不同的值。

11、如何在Vue之外创建一个具有响应性的变量(Vue2和3)

如果你从Vue之外得到一个变量,让它具有反应性是很好的。

这样,我们就可以在computed propswatch和其他任何地方使用它,它的工作方式就像Vue中的任何其他状态一样。

如果我们使用的选项API,需要的只是将其放在组件的数据部分中:

const externalVariable = getValue();

export default {
  data() {
    return {
      reactiveVariable: externalVariable,
    };
  }
};
登入後複製

如果使用Vue3的组合API,可以直接使用refreactive

import { ref } from &#39;vue&#39;;

// 可以完全在Vue组件之外完成
const externalVariable = getValue();
const reactiveVariable = ref(externalVariable);

console.log(reactiveVariable.value);
登入後複製

使用 reactive 代替:

import { reactive } from &#39;vue&#39;;

//  可以完全在Vue组件之外完成
const externalVariable = getValue();
// reactive 只对对象和数组起作用
const anotherReactiveVariable = reactive(externalVariable);

// Access directly
console.log(anotherReactiveVariable);
登入後複製

如果你还在使用 Vue2,你可以使用observable而不是reactive来实现完全相同的结果。

12、v-for 中的解构

你知道可以在-vfor中使用解构吗?

<li
  v-for="{ name, id } in users"
  :key="id"
>
  {{ name }}
</li>
登入後複製

更广为人知的是,可以通过使用这样的元组从v-for中取出索引。

<li v-for="(movie, index) in [
  &#39;Lion King&#39;,
  &#39;Frozen&#39;,
  &#39;The Princess Bride&#39;
]">
  {{ index + 1 }} - {{ movie }}
</li>
登入後複製

当使用一个对象时,可以这样使用 key

<li v-for="(value, key) in {
  name: &#39;Lion King&#39;,
  released: 2019,
  director: &#39;Jon Favreau&#39;,
}">
  {{ key }}: {{ value }}
</li>
登入後複製

也可以将这两种方法结合起来,获取key以及属性的 index

<li v-for="(value, key, index) in {
  name: &#39;Lion King&#39;,
  released: 2019,
  director: &#39;Jon Favreau&#39;,
}">
  #{{ index + 1 }}. {{ key }}: {{ value }}
</li>
登入後複製

13、在指定范围内循环

v-for指令允许我们遍历数组,但它也允许我们遍历一个范围

<template>
  <ul>
    <li v-for="n in 5">Item #{{ n }}</li>
  </ul>
</template>
登入後複製

渲染结果:

Item #1
Item #2
Item #3
Item #4
Item #5
登入後複製

当我们使用带范围的v-for时,它将从1开始,以我们指定的数字结束。

14、监听你的组件中的任何东西

export default {
  computed: {
    someComputedProperty() {
      // Update the computed prop
    },
  },
  watch: {
    someComputedProperty() {
      // Do something when the computed prop is updated
    }
  }
};
登入後複製

我们可以监听:

  • 计算属性
  • props
  • 嵌套值

如果你使用组合API,任何值都可以被监视,只要它是一个refreactive对象。

15、窃取 prop 类型

我从一个子组件中复制 prop 类型,只是为了在一个父组件中使用它们。但我发现,偷取这些 prop 类型要比仅仅复制它们好得多。

例如,我们在这个组件中使用了一个Icon组件。

<template>
  <div>
    <h2 id="nbsp-heading-nbsp">{{ heading }}</h2>
    <Icon
      :type="iconType"
      :size="iconSize"
      :colour="iconColour"
    />
  </div>
</template>
登入後複製

为了让它工作,我们需要添加正确的 prop 类型,从``Icon`组件复制。

import Icon from &#39;./Icon&#39;;
export default {
  components: { Icon },
  props: {
    iconType: {
      type: String,
      required: true,
    },
    iconSize: {
      type: String,
      default: &#39;medium&#39;,
      validator: size => [
        &#39;small&#39;,
        &#39;medium&#39;,
        &#39;large&#39;,
        &#39;x-large&#39;
      ].includes(size),
    },
    iconColour: {
      type: String,
      default: &#39;black&#39;,
    },
    heading: {
      type: String,
      required: true,
    },
  },
};
登入後複製

多么痛苦啊。

Icon 组件的 prop类型被更新时,我们肯定会忘记返回这个组件并更新它们。随着时间的推移,当该组件的 prop类型开始偏离Icon组件中的 prop 类型时,就会引入错误。

因此,这就是为什么我们要窃取组件的 prop 类型:

import Icon from &#39;./Icon&#39;;
export default {
  components: { Icon },
  props: {
    ...Icon.props,
    heading: {
      type: String,
      required: true,
    },
  },
};
登入後複製

不需要再复杂了。

除了在我们的例子中,我们把 icon 加在每个 prop 名称的开头。所以我们必须做一些额外的工作来实现这一点。

import Icon from &#39;./Icon&#39;;

const iconProps = {};

Object.entries(Icon.props).forEach((key, val) => {
  iconProps[`icon${key.toUpperCase()}`] = val;
});

export default {
  components: { Icon },
  props: {
    ...iconProps,
    heading: {
      type: String,
      required: true,
    },
  },
};
登入後複製

现在,如果Icon组件中的 prop 类型被修改,我们的组件将保持最新状态。

但是,如果一个 prop 类型从 Icon 组件中被添加或删除了呢?为了应对这些情况,我们可以使用v-bind和一个计算的 prop 来保持动态。

16、检测元素外部(或内部)的单击

有时我需要检测一个点击是发生在一个特定元素el的内部还是外部。这就是我通常使用的方法。

window.addEventListener(&#39;mousedown&#39;, e => {
  // 获取被点击的元素
  const clickedEl = e.target;
  
  if (el.contains(clickedEl)) {
   //在 "el "里面点击了
  } else {
   //在 "el "外点击了
  }
});
登入後複製

17、递归插槽

有一次,我决定看看我是否可以只用模板来做一个v-for组件。在这个过程中,我也发现了如何递归地使用槽。

<!-- VFor.vue -->
<template>
    <div>
        <!--  渲染第一项 -->
    {{ list[0] }}
        <!-- 如果我们有更多的项目,继续!但是不要使用我们刚刚渲染的项 -->
    <v-for
      v-if="list.length > 1"
            :list="list.slice(1)"
        />
    </div>
</template>
登入後複製

如果你想用作用域插槽来做这件事,只是需要一些调整

<template>
  <div>
    <!-- Pass the item into the slot to be rendered -->
    <slot v-bind:item="list[0]">
      <!-- Default -->
      {{ list[0] }}
    </slot>

    <v-for
      v-if="list.length > 1"
      :list="list.slice(1)"
    >
      <!-- Recursively pass down scoped slot -->
      <template v-slot="{ item }">
        <slot v-bind:item="item" />
      </template>
    </v-for>
  </div>
</template>
登入後複製

下面是这个组件的使用方法。

<template>
  <div>
    <!-- 常规列表 -->
    <v-for :list="list" />

    <!-- 加粗的项目列表 -->
    <v-for :list="list">
      <template v-slot="{ item }">
        <strong>{{ item }}</strong>
      </template>
    </v-for>
  </div>
</template>
登入後複製

18、组件元数据

并不是添加到一个组件的每一点信息都是状态。有时我们需要添加一些元数据,给其他组件提供更多信息。

例如,如果正在为谷歌 analytics这样的分析仪表:

25個值得了解的Vue小技巧,原來還能這麼用!

如果你想让布局知道每个小组件应该占多少列,你可以直接在组件上添加元数据。

export default {
  name: &#39;LiveUsersWidget&#39;,
  // ? 只需将其作为一个额外的属性添加
  columns: 3,
  props: {
    // ...
  },
  data() {
    return {
      //...
    };
  },
};
登入後複製
export default {
  name: &#39;LiveUsersWidget&#39;,
  // ?  只需将其作为一个额外的属性添加
  columns: 3,
  props: {
    // ...
  },
  data() {
    return {
      //...
    };
  },
};
登入後複製

你会发现这个元数据是组件上的一个属性。

import LiveUsersWidget from &#39;./LiveUsersWidget.vue&#39;;
const { columns } = LiveUsersWidget;
登入後複製

我们也可以通过特殊的$options属性从组件内部访问元数据。

export default {
  name: &#39;LiveUsersWidget&#39;,
  columns: 3,
  created() {
    // ? `$options` contains all the metadata for a component
    console.log(`Using ${this.$options.metadata} columns`);
  },
};
登入後複製

只要记住,这个元数据对组件的每个实例都是一样的,而且不是响应式的。

这方面的其他用途包括(但不限于):

  • 保持单个组件的版本号
  • 用于构建工具的自定义标志,以区别对待组件
  • 在计算属性、数据、watch 等之外为组件添加自定义功能
  • 其它

19、多文件单文件组件

这是**SFC(单文件组件)**的一点已知功能。

可以像常规HTML文件一样导入文件:

<template src="./template.html"></template>
<script src="./script.js"></script>
<style scoped src="./styles.css"></style>
登入後複製

如果你需要分享样式、文件或其他任何东西,这可能会非常方便。

20、可重复使用的组件并不是你所想的那样

可重复使用的组件不一定是大的或复杂的东西。

我经常让小的和短的组件可以重复使用。

因为我没有到处重写这段代码,所以更新它变得更加容易,而且我可以确保每个OverflowMenu的外观和工作方式都完全一样--因为它们是一样的!"。

<!-- OverflowMenu.vue -->
<template>
  <Menu>
    <!-- 添加一个自定义按钮来触发我们的菜单   -->
    <template #button v-slot="bind">
      <!-- 使用bind来传递click处理程序、a11y 属性等 -->
      <Button v-bind="bind">
        <template #icon>
          <svg src="./ellipsis.svg" />
        </template>
      </Button>
    </template>
  </Menu>
</template>
登入後複製

在这里,我们采用了一个菜单组件,但在触发它的按钮上添加了一个 ellipsis 图标。(省略号)的图标来触发它的打开。

这似乎不值得把它做成一个可重复使用的组件,因为它只有几行。难道我们就不能在每次要使用这样的菜单时添加图标吗?

但是这个OverflowMenu将被使用几十次,现在如果我们想更新图标或它的行为,我们可以非常容易地做到。而且,使用它也更简单了。

21、从组件外部调用一个方法

我们可以从一个组件的外部通过给它一个 ref 用来调用一个方法。

<!-- Parent.vue -->
<template>
  <ChildComponent ref="child" />
</template>
登入後複製
登入後複製
// Somewhere in Parent.vue
this.$refs.child.method();
登入後複製
登入後複製

再解释一下这个问题。

有时候,“最佳实践”并不适用于你正在做的事情,你需要一个像这样的逃生口。

通常情况下,我们使用 props 和 events 在组件之间进行交流。props 被下发到子组件中,而events 被上发到父组件中。

<template>
  <ChildComponent
    :tell-me-what-to-do="someInstructions"
    @something-happened="hereIWillHelpYouWithThat"
  />
</template>
登入後複製
// Child.vue
export default {
  props: [&#39;trigger&#39;],
  watch: {
    shouldCallMethod(newVal) {
      if (newVal) {
        // Call the method when the trigger is set to `true`
        this.method();
      }
    }
  }
}
登入後複製

这可以正常工作,但只能在第一次调用时使用。如果您需要多次触发此操作,则必须进行清理并重置状态。逻辑是这样的

  • 父组件将 true 传递给触发器 prop
  • Watch 被触发,然后 Child 组件调用该方法
  • 子组件发出一个事件,告诉父组件该方法已被成功触发
  • Parent组件将 trigger 重置为 false,所以我们可以从头再来一次

相反,如果我们在子组件上设置一个 ref,我们可以直接调用该方法:

<!-- Parent.vue -->
<template>
  <ChildComponent ref="child" />
</template>
登入後複製
登入後複製
// Somewhere in Parent.vue
this.$refs.child.method();
登入後複製
登入後複製

是的,我们打破了 “props down, events up"” 的规则,我们打破了封装,但是这样做更清晰,更容易理解,所以是值得的

有时,"最好的 "解决方案最终会成为最糟糕的解决方案。

22、监听数组和对象

使用 watcher 最棘手的部分是,有时它似乎不能正确触发。

通常,这是因为我们试图监听数组或对象,但没有将deep设置为true

export default {
  name: &#39;ColourChange&#39;,
  props: {
    colours: {
      type: Array,
      required: true,
    },
  },
  watch: {
    // 使用对象语法,而不仅仅是方法
    colours: {
      // 这将让Vue知道要在数组内部寻找
      deep: true,

      handler()
        console.log(&#39;The list of colours has changed!&#39;);
      }
    }
  }
}
登入後複製

使用Vue 3的API会是这样的:

watch(
  colours,
  () => {
    console.log(&#39;The list of colours has changed!&#39;);
  },
  {
    deep: true,
  }
);
登入後複製

23、用Vue Router进行深度链接

我们可以在URL中存储(一点)状态,允许我们直接跳到页面上的一个特定状态。

例如,你加载一个已经选择了日期范围过滤器的页面:

someurl.com/edit?date-range=last-week
登入後複製

这对于应用中用户可能共享大量链接的部分来说是非常棒的,对于服务器渲染的应用,或者在两个独立的应用之间通信的信息比普通链接通常提供的更多。

我们可以存储过滤器、搜索值、模态框是打开还是关闭,或者在列表的哪个位置滚动以完美地实现无限分页。

使用 vue-router 获取查询参数是这样工作的(这也适用于大多数Vue框架,如Nuxt和Vuepress):

const dateRange = this.$route.query.dateRange;
登入後複製

为了改变它,我们使用 RouterLink 组件并更新 query

<RouterLink :to="{
  query: {
    dateRange: newDateRange
  }
}">
登入後複製

24、<span style="font-size: 18px;">template</span> 标签的另一个用途

template 标签可以在模板中的任何地方使用,以更好地组织代码。

我喜欢用它来简化v-if逻辑,有时也用v-for

在这个例子中,我们有几个元素都使用同一个v-if条件。

<template>
  <div class="card">
    <img  src="/static/imghw/default1.png"  data-src="imgPath"  class="lazy"   / alt="25個值得了解的Vue小技巧,原來還能這麼用!" >
    <h3>
      {{ title }}
    </h3>
    <h4 v-if="expanded">
      {{ subheading }}
    </h4>
    <div
      v-if="expanded"
      class="card-content"
    >
      <slot />
    </div>
    <SocialShare v-if="expanded" />
  </div>
</template>
登入後複製

这有点笨拙,而且一开始并不明显,一堆这样的元素被显示和隐藏在一起。在一个更大、更复杂的组件上,这可能是一个更糟糕的情况

但我们能优化它。

我们可以使用 template 标签来分组这些元素,并将 v-if 提升到模板 template 本身。

<template>
  <div class="card">
    <img  src="/static/imghw/default1.png"  data-src="imgPath"  class="lazy"   / alt="25個值得了解的Vue小技巧,原來還能這麼用!" >
    <h3>
      {{ title }}
    </h3>
    <template v-if="expanded">
      <h4>
        {{ subheading }}
      </h4>
      <div class="card-content">
        <slot />
      </div>
      <SocialShare />
    </template>
  </div>
</template>
登入後複製

现在看起来就更容易理解,而且它在做什么,一目了然。

25、处理错误(和警告)的更好方法

我们可以为Vue中的错误和警告提供一个自定义处理程序。

// Vue 3
const app = createApp(App);
app.config.errorHandler = (err) => {
  alert(err);
};

// Vue 2
Vue.config.errorHandler = (err) => {
  alert(err);
};
登入後複製

像 Bugsnag 和 Rollbar 这样的错误跟踪服务,可以钩住这些处理程序来记录错误,但你也可以用它们来更优雅地处理错误,以获得更好的用户体验。

例如,如果一個錯誤未被處理,應用程式不會直接崩潰,你可以顯示一個完整的錯誤螢幕,讓使用者刷新或嘗試其他東西。

在Vue3 中,錯誤處理程序只能處理 template 和 watcher 錯誤,但是 Vue2的錯誤處理程序可以捕捉幾乎所有錯誤。這兩個版本中的警告處理程序只在開發階段有效。

(學習影片分享:web前端開發程式設計基礎影片

以上是25個值得了解的Vue小技巧,原來還能這麼用!的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

vue.js vs.反應:特定於項目的考慮因素 vue.js vs.反應:特定於項目的考慮因素 Apr 09, 2025 am 12:01 AM

Vue.js適合中小型項目和快速迭代,React適用於大型複雜應用。 1)Vue.js易於上手,適用於團隊經驗不足或項目規模較小的情況。 2)React的生態系統更豐富,適合有高性能需求和復雜功能需求的項目。

vue怎麼給按鈕添加函數 vue怎麼給按鈕添加函數 Apr 08, 2025 am 08:51 AM

可以通過以下步驟為 Vue 按鈕添加函數:將 HTML 模板中的按鈕綁定到一個方法。在 Vue 實例中定義該方法並編寫函數邏輯。

vue多頁面開發是啥意思 vue多頁面開發是啥意思 Apr 07, 2025 pm 11:57 PM

Vue 多頁面開發是一種使用 Vue.js 框架構建應用程序的方法,其中應用程序被劃分為獨立的頁面:代碼維護性:將應用程序拆分為多個頁面可以使代碼更易於管理和維護。模塊化:每個頁面都可以作為獨立的模塊,便於重用和替換。路由簡單:頁面之間的導航可以通過簡單的路由配置來管理。 SEO 優化:每個頁面都有自己的 URL,這有助於搜索引擎優化。

vue遍歷怎麼用 vue遍歷怎麼用 Apr 07, 2025 pm 11:48 PM

Vue.js 遍歷數組和對像有三種常見方法:v-for 指令用於遍歷每個元素並渲染模板;v-bind 指令可與 v-for 一起使用,為每個元素動態設置屬性值;.map 方法可將數組元素轉換為新數組。

vue的div怎麼跳轉 vue的div怎麼跳轉 Apr 08, 2025 am 09:18 AM

Vue 中 div 元素跳轉的方法有兩種:使用 Vue Router,添加 router-link 組件。添加 @click 事件監聽器,調用 this.$router.push() 方法跳轉。

vue怎麼a標籤跳轉 vue怎麼a標籤跳轉 Apr 08, 2025 am 09:24 AM

實現 Vue 中 a 標籤跳轉的方法包括:HTML 模板中使用 a 標籤指定 href 屬性。使用 Vue 路由的 router-link 組件。使用 JavaScript 的 this.$router.push() 方法。可通過 query 參數傳遞參數,並在 router 選項中配置路由以進行動態跳轉。

vue組件傳值是什麼意思 vue組件傳值是什麼意思 Apr 07, 2025 pm 11:51 PM

Vue 組件傳值是一種在組件之間傳遞數據和信息的機制。它可以通過屬性 (props) 或事件 (events) 實現:屬性 (props):聲明要在組件中接收的數據,在父組件中傳遞數據。事件 (events):使用 $emit 方法觸發事件,並使用 v-on 指令在父組件中監聽。

React與Vue:Netflix使用哪個框架? React與Vue:Netflix使用哪個框架? Apr 14, 2025 am 12:19 AM

NetflixusesAcustomFrameworkcalled“ Gibbon” BuiltonReact,notReactorVuedIrectly.1)TeamSperience:selectBasedonFamiliarity.2)ProjectComplexity:vueforsimplerprojects:reactforforforproproject,reactforforforcompleplexones.3)cocatizationneedneeds:reactoffipicatizationneedneedneedneedneedneeds:reactoffersizationneedneedneedneedneeds:reactoffersizatization needefersmoreflexibleise.4)

See all articles