分享几个关于 Vue 的小知识

作者: jie 分类: Vue 发布时间: 2023-08-08 16:14

大家好,今天分享几个和Vue相关的小知识,希望对你有所帮助

1、在Vue.js中获取下拉框选择的值

有时候,我们希望在Vue.js中在选项改变时获取所选的选项。在这篇文章中,我们将学习如何在Vue.js中获取选择的选项。

在Vue.js中获取选择的选项 我们可以通过将@change设置为一个方法来在Vue.js中获取选择的选项。例如,我们可以这样写:

<template>
	<div id="app">
		<select name="fruit" @change="onChange($event)" v-model="key">
			<option value="1">apple</option>
			<option value="2">orange</option>
		</select>
	</div>
</template>
<script>
	export default {
		name: "App",
		data() {
			return {
				key: ""
			};
		},
		methods: {
			onChange(event) {
				console.log(event.target.value, this.key);
			},
		},
	};
</script>

我们将v-model设置为关键的响应式属性,将所选值的属性值绑定到该关键属性。

然后,我们将@change设置为onChange($event),以调用带有change事件对象的onChange函数。

在onChange函数中,我们获取事件对象,并使用event.target.value获取所选值的属性值。

由于我们使用v-model将其绑定到所选值的属性值,我们可以通过this.key获取相同的值。

作为替代,我们可以删除($event)并编写,得到相同的结果。

<template>
	<div id="app">
		<select name="fruit" @change="onChange" v-model="key">
			<option value="1">apple</option>
			<option value="2">orange</option>
		</select>
	</div>
</template>
<script>
	export default {
		name: "App",
		data() {
			return {
				key: ""
			};
		},
		methods: {
			onChange(event) {
				console.log(event.target.value, this.key);
			},
		},
	};
</script>

2、使用Vue.js在鼠标悬停在一个元素上时执行某些操作

要在鼠标悬停在一个元素上时执行某些操作,我们可以监听mouseover(鼠标悬停)和mouseleave(鼠标离开)事件。

例如,我们可以编写以下代码:

<template>
	<div id="app">
		<div @mouseover="hovered = true" @mouseleave="hovered = false">
			<p>hello world</p>
			<p v-show="hovered">hovered</p>
		</div>
	</div>
</template>
<script>
	export default {
		name: "App",
		data() {
			return {
				hovered: false
			};
		},
	};
</script>

我们有一个初始值为false的reactive属性hovered。

然后,我们添加@mouseover指令,并将其值设置为hovered = true,当我们将鼠标移到div内时,我们将@mouseover指令设置为hovered = false,以在将鼠标移到div内和移出div时切换hovered的状态。

我们使用v-show指令来在hovered为true时显示第二个p元素。

现在,当我们的鼠标在div内时,我们可以看到“hovered”被显示出来。

当我们将鼠标移出div时,“hovered”消失了。

3、在Vue.js中获取组件内的元素

有时候,我们希望在Vue.js中获取组件内的元素。在本文中,我们将讨论如何在Vue.js中获取组件内的元素。

要在Vue.js中获取组件内的元素,我们可以给想要获取的元素分配一个引用(ref)。然后,我们可以在任何生命周期或常规方法中使用this.$refs属性来获取该元素。

例如,我们可以编写以下代码:

<template>
	<div id="app">
		<span ref="someName" class="foo bar">Child Span</span>
	</div>
</template>
<script>
	export default {
		name: "App",
		mounted() {
			const childSpanClassAttr = this.$refs.someName.getAttribute("class");
			console.log(childSpanClassAttr);
		},
	};
</script>

我们将<span>的ref属性设置为”someName”。

然后,我们可以在任何生命周期或常规方法中通过this.$refs.someName来获取该<span>元素。

我们可以调用任何DOM元素方法,比如getAttribute,对其进行操作。

我们通过将’class’作为getAttribute的参数来获取’class’属性的值。

因此,控制台日志将打印出’foo bar’。

4、使用Vue.js检测元素外的点击

有时候,我们想要在Vue.js中检测元素外的点击。在本文中,我们将探讨如何使用Vue.js检测元素外的点击。

我们可以通过创建自定义指令来检测Vue.js中元素外的点击。比如,我们可以这样编写:

<template>
	<!-- 创建一个宽度和高度为 500px 的 DIV,ID 为 "app" -->
	<div id="app" style="width: 500px; height: 500px">
		<!-- 该 DIV 使用了自定义指令 v-click-outside,用来监听点击元素外部的事件 -->
		<div v-click-outside="onClickOutside">hello world</div>
	</div>
</template>

<script>
	// 导入 Vue 库
	import Vue from "vue";
	// 创建一个自定义指令 "click-outside"
	Vue.directive("click-outside", {
		// 当指令绑定到元素时,会立即调用 bind 函数
		bind(el, binding, vnode) {
			// 创建一个函数来处理点击事件
			el.clickOutsideEvent = (event) => {
				// 如果点击的不是元素本身,也不是其内部的任何元素,那么就触发绑定的函数
				if (!(el === event.target || el.contains(event.target))) {
					// 在 Vue 实例上执行绑定的函数
					vnode.context[binding.expression](event);
				}
			};
			// 在 body 元素上添加 click 事件监听器
			document.body.addEventListener("click", el.clickOutsideEvent);
		},
		// 当指令与元素解除绑定时,会立即调用 unbind 函数
		unbind(el) {
			// 移除在 body 元素上的 click 事件监听器
			document.body.removeEventListener("click", el.clickOutsideEvent);
		},
	});
	// 导出 Vue 实例
	export default {
		name: "App", // 组件名
		methods: {
			// 自定义一个方法来处理点击元素外部的事件
			onClickOutside() {
				console.log("clicked outside"); // 控制台输出信息 "clicked outside"
			},
		},
	};
</script>

使用 Vue.directive 方法来添加自定义指令,该方法使用指令名称和一个对象作为参数,该对象具有 bind 和 unbind 方法以在 bind 方法中添加 el 方法。

在 clickOutsideEvent 方法中,我们检查 el 是否不是 event.target 并且它不包含 event.target。

如果都为 true,则添加 vnode.context[binding.expression](event); 来运行我们设置为 v-click-outside 指令值的方法。

然后,我们调用document.body.addEventListener 来添加一个点击事件监听器以运行 clickOutsideEvent。

在 unbind 方法中,我们使用 removeEventListener 来删除事件监听器。

然后,在模板中,我们添加 v-click-outside 并将其值设置为 onClickOutside,以在单击外部时运行该方法。

当我们单击外部时,应该看到“clicked outside”被记录。

我们可以通过创建自定义指令来检测 Vue.js 中元素外的点击。这段 Vue.js 代码中的自定义指令 “v-click-outside” 主要用于处理点击元素外部的事件。这种功能在很多应用场景中都非常有用,以下是一些具体的示例:

  • 下拉菜单(Dropdown)或模态窗口(Modal):当用户点击下拉菜单或模态窗口的外部区域,我们通常期望下拉菜单或模态窗口会关闭。这就需要检测用户是否点击了元素的外部,如果是,那么就触发一个函数来关闭下拉菜单或模态窗口。
  • 上下文菜单(Context Menu):在右键打开的上下文菜单中,当用户点击菜单外的其他地方时,通常需要关闭这个菜单。同样可以使用这个自定义指令来监听点击事件,并在点击事件发生在菜单外部时,关闭上下文菜单。
  • 工具提示(Tooltip):工具提示也有类似的需求。当工具提示展示时,如果用户点击了工具提示以外的其他地方,我们通常希望工具提示会消失。
  • 表单验证(Form Validation):在某些场景下,你可能希望用户在完成输入并且点击输入框外部时,进行表单验证。你可以利用这个指令来实现这种效果。
  • 搜索自动完成(Search Autocomplete):在搜索框输入时,会出现一个自动完成的下拉菜单。当用户在选中某个搜索建议或者点击搜索框以外的地方时,我们通常需要关闭这个自动完成的菜单。

在上述所有场景中,通过 “v-click-outside” 这个自定义指令,你可以非常简单地处理点击元素外部的事件,进而实现你的交互需求。

5、如何在Vue组件实例内的方法中调用过滤器?

我们可以从this.options.$filters属性中获取过滤器函数来调用Vue组件实例中的过滤器。

例如,我们可以编写:

<template>
	<div id="app">
		{{ truncatedText }} <!-- 在页面上显示计算属性 truncatedText 的结果 -->
	</div>
</template>

<script>
	import Vue from "vue"; // 导入 Vue 框架
	// 在 Vue 框架中定义一个名为 "truncate" 的过滤器,该过滤器接收三个参数:text, stop, clamp
	// text 为需要截断的文本
	// stop 为截断的字符位置
	// clamp 为当文本被截断时添加的字符,默认为 "..."
	Vue.filter("truncate", (text, stop, clamp) => {
		return text.slice(0, stop) + (stop < text.length ? clamp || "..." : ""); // 如果 stop 小于文本长度,就在截断的地方添加 clamp 参数指定的内容,如果没有指定 clamp,就添加 "..."
	});
	export default {
		name: "App", // 组件的名称
		computed: {
			// 定义一个计算属性,使用上面定义的 "truncate" 过滤器,传入的文本为 "Lorem ipsum dolor sit amet, consectetur adipiscing elit",截断位置为 10,截断后添加的字符为 "..."
			truncatedText() {
				return this.$options.filters.truncate(
					"Lorem ipsum dolor sit amet, consectetur adipiscing elit",
					10,
					"..."
				);
			},
		},
	};
</script>

我们有一个名为 truncatedText 的属性,它返回被截断的文本。

过滤器是通过 Vue.filter 方法定义的,其名称作为第一个参数。

第二个参数是过滤器函数。

要调用 truncate 过滤器方法,我们使用 this.$options.filters.truncate,并传入要截断的文本、截断文本的字符数量以及截断文本后的缩写符号。

然后我们在模板中显示这段文本。

6、如何深度监视对象数组的内容变化?

我们可以使用watcher来深度监视对象数组并使用Vue.js计算更改。

例如,我们可以编写:

App.vue

<template>
  <div id="app">
    <Person :person="person" v-for="person in people" :key="person.id"></Person>
  </div>
</template>
<script>
import Person from "@/components/Person";
export default {
  name: "App",
  components: {
    Person,
  },
  data() {
    return {
      people: [
        { id: 0, name: "Bob", age: 27 },
        { id: 1, name: "Frank", age: 32 },
        { id: 2, name: "Joe", age: 38 },
      ],
    };
  },
};
</script>

Person.vue

<template>
  <div class="hello">
    <div class="person">
      {{ p.name }}
      <input type="text" v-model="p.age" />
    </div>
  </div>
</template>
<script>
export default {
  name: "Person",
  props: {
    person: Object,
  },
  data() {
    return {
      p: {},
    };
  },
  watch: {
    p: {
      handler(newValue) {
        console.log(newValue.id);
        console.log(newValue.age);
      },
      deep: true,
    },
  },
  mounted() {
    this.p = { ...this.person };
  },
};
</script>

在App.vue中,我们有一个people数组,用于使用v-for呈现Person组件。

我们将person作为person prop的值传递。

然后在Person中,我们添加了props属性来接受person prop。

我们有一个p响应式属性,我们在mounted hook中将其设置为person的副本作为其值。

在watch属性中的p watcher中,我们记录newValue值。

我们将deep选项设置为true,以便让我们监视对象中的更改。

在模板中,我们呈现p.name,并将p.age绑定为文本输入的输入值。

现在,当我们在文本输入中键入时,p watcher应该运行并记录newValue.age值。

7、如何在Vue.js的组件中调用全局自定义函数?

我们可以创建混入(mixins)使助手函数在Vue.js的单文件组件中全局可用。

例如,我们可以这样编写:

<template>
  <!--在HTML中展示capitalizedName这个计算属性-->
  <div id="app">
    {{ capitalizedName }}
  </div>
</template>

<script>
// 引入Vue库
import Vue from "vue";

// 创建一个全局混入,添加了一个可以在任何组件中使用的方法capitalizeFirstLetter
Vue.mixin({
  methods: {
    // 这个方法的作用是将传入的字符串的首字母转化为大写
    capitalizeFirstLetter: (str) => str[0].toUpperCase() + str.slice(1),
  },
});

// 导出当前Vue组件
export default {
  // 组件名称
  name: "App",
  // 组件的data属性,定义了组件的内部状态
  data() {
    return {
      // 定义了一个名为name的状态,初始值为"james"
      name: "james",
    };
  },
  // 计算属性,这是根据组件状态或者其它计算属性派生出的值
  computed: {
    // capitalizedName计算属性,会调用我们在全局混入中定义的capitalizeFirstLetter方法,对name状态进行处理
    capitalizedName() {
      return this.capitalizeFirstLetter(this.name);
    },
  },
};
</script>

我们通过调用Vue.mixin并传入一个对象来创建我们自己的混入。

这将创建一个全局混入,所以它会自动在所有组件中可用。

在这个对象中,我们设置了methods属性,它是带有一些组件方法的对象。

它有一个capitalizeFirstLetter方法,这个方法接收一个字符串并返回一个首字母大写的字符串。

接下来,我们在data方法中返回name这个响应式属性。

然后我们创建了一个名为capitalizedName的计算属性,它调用了混入中的capitalizeFirstLetter方法并将this.name作为参数,返回处理后的结果。

接着,我们将capitalizedName添加到模板中进行渲染。

最后,我们看到结果显示为‘James’。

8、在Vue.js中使用setTimeout

我们可以通过将箭头函数作为参数传递给setTimeout来在Vue.js中使用它。

例如,我们可以编写:

<template>
  <div id="app">
    <button @click="setShow">show</button>
    <p v-if="show">hello</p>
  </div>
</template>
<script>
export default {
  name: "App",
  data() {
    return {
      show: false,
    };
  },
  methods: {
    setShow() {
      setTimeout(() => {
        this.show = true;
      }, 2000);
    },
  },
};
</script>

我们有一个名为setShow的方法,它调用setTimeout并传入一个箭头函数作为第一个参数,该箭头函数调用this.show为true。

第二个参数是在毫秒中运行第一个参数的回调之前的延迟时间。

我们必须使用箭头函数才能在回调函数中获得正确的this值。

这个this应该是组件实例,因为箭头函数不绑定它们的this值。

我们将setShow设置为@click指令的值,以便在单击按钮时运行它。

因此,当我们单击它时,div会显示,因为show变为true。

9、如何防止点击按钮时,点击事件冒泡到父级元素?

当在Vue.js中点击一个包含按钮的元素时,我们可以使用self修饰符来防止点击事件冒泡到父元素。

例如,我们可以这样写:

<template>
  <div id="app">
    <div class="parent" @click.self="showAlert('parent clicked')">
      <span class="child" @click="showAlert('child1 clicked')">Child1</span>
      <span class="child" @click="showAlert('child2 clicked')">Child2</span>
      <span class="child" @click="showAlert('child3 clicked')">Child3</span>
    </div>
  </div>
</template>
<script>
export default {
  name: "App",
  methods: {
    showAlert(str) {
      alert(str);
    },
  },
};
</script>
<style scoped>
.parent {
  padding: 20px;
}
</style>

我们在外部div元素上添加self修饰符,这样点击事件就只会限定在父级div中。

当我们点击每个div或span元素时,将会运行showAlert方法。

10、使用Vue.js滚动到一个元素

有时候,我们需要使用Vue.js滚动到一个元素。 在本文中,我们将看看如何使用Vue.js滚动到一个元素。

我们可以通过为想要滚动到的元素分配一个引用来使用Vue.js滚动到该元素然后,我们可以在分配给引用的元素上调用scrollIntoView方法来滚动到该元素。例如,我们可以编写:

<template>
  <div id="app">
    <button @click="scrollToElement">scroll to last</button>
    <p v-for="n of 100" :key="n" :ref="n === 100 ? 'last' : undefined">
      {{ n }}
    </p>
  </div>
</template>
<script>
export default {
  name: "App",
  methods: {
    scrollToElement() {
      const [el] = this.$refs.last;
      if (el) {
        el.scrollIntoView({ behavior: "smooth" });
      }
    },
  },
};
</script>

我们有一个名为scrollToElement的按钮,用于调用该方法。然后我们有一些p元素,其中最后一个引用被分配给最后一个p元素。在scrollToElement方法中,我们通过解构使用this.$refs.last获取分配给最后一个引用的元素。然后我们调用el.scrollIntoView,并使用一个具有behavior属性的对象来更改滚动行为。

发表回复