关于 Vue 的使用中的一些注意事项和技巧

一、 一些容易忽略的特性

1. 简单传递多个 props 的方法

当一个组件需要分多个参数传递 props 值的时候,而这些参数又刚好是某个对象的属性

<template>
  <User
    :name="user.name"
    :avatar="user.avatar"
    :email="user.email"
    />
template>

这个时候可以直接通过v-bind绑定对象来将它的属性值作为 props 自动传递给组件

<template>
	<User v-bind="user"/>
template>
export default {
  setup() {
    return {
      user: {
        name: 'Timfan',
        avatar: 'my-profile.jpg',
        email: '[email protected]'
      }
    }
  }
};

这种用法同样也适用于通过 v-on 来绑定多个事件监听器

<template>
  <User v-on="userEventHandlers"/>
  
template>
export default {
  setup() {
    return {
      userEventHandlers: {
        updateName(newName) {
          // ...
        },
        deleteUser() {
          // ...
        },
        addFriend(friend) {
          // ...
        }
      }
    }
  }
};

2. 监听数组和对象的变化

不知道你是否有这样的疑惑,当你在使用侦听器 watch的时候,发现侦听的对象变化并没有正确地触发回调函数,通常这是因为侦听的对象是一个数组或者对象,但是没有设置deep的值为true造成的。

export default {
  name: 'ColourChange',
  props: {
    colours: {
      type: Array,
      required: true,
    },
  },
  watch: {
    // Use the object syntax instead of just a method
    colours: {
      // This will let Vue know to look inside the array
      deep: true,
      // We have to move our method to a handler field
      handler(oldVal, newVal)
        console.log('The list of colours has changed!');
        }
    }
  }
}

同理在 Vue 3 中使用的是响应式 API 来实现的,方式如下

watch(
  colours,
  () => {
    console.log('The list of colours has changed!');
  },
  {
    deep: true,
  }
);

详细用法可以参考官方文档 https://cn.vuejs.org/guide/essentials/watchers.html

3. 给 Prop 值添加校验

我们可以在 Props 的定义项里通过validator属性来传递一个回调来为它的值做校验

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

这个校验函数根据值是否有效,返回true或者false两种值。
通常按钮组件或者提示组件的类型(诸如:“info”, “success”, “danger”, “warning”)需要使用到该种用法作为有效值校验。这只是其中一种,还有更多的使用场景。

4. 全局组件

当你注册一个全局组件,你就不再需要进行第二次导入就可以在 template中使用:

/ Vue 3
import { createApp } from 'vue';
import GlobalComponent from './GlobalComponent.vue';
const app = createApp({})
app.component('GlobalComponent', GlobalComponent);

在 Vue 2 中采用如下方案

// Vue 2
import Vue from 'vue';
import GlobalComponent from './GlobalComponent.vue';
Vue.component('GlobalComponent', GlobalComponent);

现在你可以在项目中的任何 template 中使用 GlobalComponent全局组件,不需要进行额外的处理。当然全局组件和全局变量有着同样的利弊,请谨慎使用。

5. 监听嵌套的值需要带上引号

也许你之前没见过,但是确实可以直接通过引号括起来监听嵌套的值,特别在深层嵌套的情况下,特别方便。

watch: {
  '$route.query.id'() {
  // ...
  }
}

6. 如何监听组件中任何你想监听的对象

事实上组件中的任何响应式的变量都是可以通过watch来监听的:

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

只要这个值是refreactive转化的响应式对象,或者是computed实现的计算属性值,你都可以通过watch来监听它的变化。

7. hRender 函数

当我们使用render函数来代替template模板的时候,通常是通过h函数来实现的:

<script setup>
import { h } from 'vue';
const render = () => h('div', {}, 'Hello Wurld');
</script>

它的作用是创建了一个虚拟节点,一个 Vue 内部跟踪变化的对象和最终渲染到页面中的文本。
第一个参数也就是这个虚拟节点可以是任意的 HTML 元素,也可以是封装好的可以调用的 Vue 组件

<script setup>
import { h } from 'vue';
import MyComponent from './MyComponent.vue';
const render = () => h(MyComponent, {}, []);
</script>

第二个参数可以是一系列的props值,自身的属性,或者事件监听器

<script setup>
import { h } from 'vue';
import MyComponent from './MyComponent.vue';
const render = () => h(MyComponent, {
class: 'text-blue-400',
title: 'This component is the greatest',
onClick() {
console.log('Clicked!');
},
}, []);
</script>

第三个参数可以是一串文本,一个子节点组成的数组,或者用来定义slot的对象
h函数的使用为我们带来通过 javaScript 复杂的逻辑创建 html 的便利性。

8. 通过 Vue 路由参数携带状态

在开发中我们可以在页面路由中携带参数,这对于我们进入到某个页面预设一些操作是很有用的,比如进入到某个有默认选项的页面或者需要滚动到某个位置,都可以通过获取到路由中的参数值来达到。

const dateRange = this.$route.query.dateRange;

这对于分离的两个不同的应用之间的通信也是通过该原理实现的。

9. 在 Render 函数中使用自定义指令

我们很熟悉在 template 模板中使用自定义指令的方式,直接通过 v-指令名,而 Vue 提供了resolveDirectivewithDirectives两个接口,前者可以获取到自定义的指令添加到第二个接口的回调参数中

<script setup>
import { resolveDirective, withDirectives, h } from 'vue';
// Find the already registered directive by name
const focusDirective = resolveDirective('focus');
// Wrap the button with the directive
const render = () => withDirectives(
h('button', {}, []),
// An array of directives to apply
[
[focusDirective]
]
);
</script>

10. Vue 中定义 Web Component 的方式

我们如何在 Vue 应用中自定义在 html 中可以使用的元素,可以分三步完成:
第一步:通过 Vue 提供的接口defineCustomElement

import { defineCustomElement } from 'vue';
import MyVueComponent from './MyVueComponent.vue';
const customElement = defineCustomElement(MyVueComponent);

第二步:注册自定义元素到 DOM 中:

customElements.define('my-vue-component', customElement);

第三步:在 HTML 结构中直接使用该自定义元素

<html>
  <head>head>
  <body>
    <my-vue-component>my-vue-component>
  body>
html>

这样就实现了一个不需要任何框架就可以在浏览器中运行的自定义组件( 也就是通常说的 Web Component)。

11. 在 script setup 中访问内部属性和方法

当我们通过$ref来访问某个组件的时候,我们是无法直接访问组件内部的方法或者属性变量的

export default {
  expose: ['makeItPublic'],
  data() {
    return {
      privateData: 'Keep me a secret!',
    };
  },
  computed: {
    makeItPublic() {
      return this.privateData.toUpperCase();
    },
  },
};

但是 Vue 提供的 expose 可以将内部的属性或方法暴露出来供外部使用,这里可以访问makeItPublic方法

this.$refs.component.makeItPublic()

在 Vue3 中当我们使用

你可能感兴趣的:(vue.js,javascript,前端)