文章目录
前言
作为一个内心骚动想做点小系统的后端来说,学习Vue是过不去的一个坎,毕竟香嘛~
遂写一篇博文用于记录在Vue中用的比较多的,且不容易记的知识点,方便自己在需要使用时能够查找到相关知识点以及如何快速使用。
正文
1. $emit方法
$emit会申明一个事件的绑定,例如:
..
methods: {
clickfun: function() {
this.count++;
// 自定义一个clicknow事件,就像click事件样。
this.$emit("clicknow", this.count);
},
clicknowfunc: function(data) {
console.log(data);
}
}
..
<!-- 点击clicknow之后,就会触发clicknowfunc方法。 -->
<button @clicknow="clicknowfunc"></button>
2. $on
对于 o n , 有 点 类 似 于 j q u e r y 的 on,有点类似于jquery的 on,有点类似于jquery的(xxx).on(“事件名称”, function(){}) (比喻的可能有点不对)
意思就是将要调用某个事件,就拿$emit的例子来说:
<script>
new Vue({
el: '#root',
data(){},
created(){
// 相当于触发clicknow事件,然后调用了clicknowfunc方法。
this.$on("clicknow", this.clicknowfunc);
},
methods:{
clickfun: function() {
this.count++;
// 自定义一个clicknow事件,就像click事件样。
this.$emit("clicknow", this.count);
},
clicknowfunc: function(data) {
console.log(data);
}
}
})
</script>
3. 自定义指令——direcctive
除了Vue核心功能的指令,例如v-model双向绑定指令,v-show展示指令,Vue还可以自定义指令。
例如需要对于一个input需要焦点聚焦的需求,就可以通过directive方法来实现。
首先可以注册一个全局自定义指令:v-focus
注册全局指令
和注册全局组件一样,可以通过Vue.directive来注册全局指令。
Vue.directive('focus', {
// 当被绑定的元素插入到DOM中时...
inserted: function(el) {
// 聚焦元素
el.focus();
}
})
注册局部指令
除了可以注册全局指令,当然也有注册局部指令,在Vue组件内也可以接受一个directives选项:
directives: {
// focus就是指令的名称,通过:vue-focus来使用。
focus: {
// 指令的定义
inserted: function(el) {
el.focus();
}
}
}
注册完自定义指令后,就可以在input元素里使用了
<input v-focus>
2.1 钩子函数
一个指令定义对象可以提供如下几个钩子函数 (均为可选):
-
bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
-
inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
-
update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。
-
componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
-
unbind:只调用一次,指令与元素解绑时调用。
更详细内容在Vue官网查看:自定义指令
2.2 示例
<html>
<head>
<title>directive 用法</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="root">
<div v-loading="isLoading">{{data}}</div>
<button @click="update">更新</button>
</div>
<script>
Vue.directive('loading', {
update(el, binding, vnode) {
if (binding.value) {
const div = document.createElement('div')
div.innerText = '加载中...'
div.setAttribute('id', 'loading')
div.style.position = 'absolute'
div.style.left = 0
div.style.top = 0
div.style.width = '100%'
div.style.height = '100%'
div.style.display = 'flex'
div.style.justifyContent = 'center'
div.style.alignItems = 'center'
div.style.color = 'white'
div.style.background = 'rgba(0, 0, 0, .7)'
document.body.append(div)
} else {
document.body.removeChild(document.getElementById('loading'))
}
}
})
new Vue({
el: '#root',
data() {
return {
isLoading: false,
data: ''
}
},
methods: {
update() {
this.isLoading = true
setTimeout(() => {
this.data = '用户数据'
this.isLoading = false
}, 3000)
}
}
})
</script>
</body>
</html>
4. Vue.extend
Vue.extend主要是用来生成组件的构造函数。在Vue.js API官方文档中,有专门介绍:
Vue.extend使用基础Vue构造器,创建一个“子类”,参数是一个包含组件选项的对象。需要注意的,在Vue.extend()中它必须是函数。
4.1 案例1
<html>
<head>
<title>Vue.extend 用法</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="root">
<Test :msg="message"></Test>
</div>
<script>
const component = Vue.extend({
template: '<div>{{msg}}</div>',
props: {
msg: {
type: String,
default: 'default message'
}
},
name: 'Test'
})
Vue.component('Test')
new Vue({
el: '#root',
data() {
return {
message: "Test Extend Component"
}
}
})
</script>
</body>
</html>
4.2 案例2
<html>
<head>
<title>Vue.extend 用法2</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<style>
#loading-wrapper {
position: fixed;
top: 0;
left: 0;
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
background: rgba(0,0,0,.7);
color: #fff;
}
</style>
</head>
<body>
<div id="root">
<button @click="showLoading">显示Loading</button>
</div>
<script>
// Loading方法中,定义了一个Vue的extend,即构造方法,并申明为LoadingComponent。
function Loading(msg) {
const LoadingComponent = Vue.extend({
template: '<div id="loading-wrapper">{{msg}}</div>',
props: {
msg: {
type: String,
default: msg
}
},
name: 'LoadingComponent'
})
const div = document.createElement('div')
div.setAttribute('id', 'loading-wrapper')
document.body.append(div)
// 通过$mount方法,将LoadingComponent挂载到id为loading-wrapper元素上
new LoadingComponent().$mount('#loading-wrapper')
return () => {
document.body.removeChild(document.getElementById('loading-wrapper'))
}
}
// 定义一个Vue原型,用于去调用Loading方法。
Vue.prototype.$loading = Loading
new Vue({
el: '#root',
methods: {
showLoading() {
const hide = this.$loading('正在加载,请稍等...')
setTimeout(() => {
hide()
}, 2000)
}
}
})
</script>
</body>
</html>
5. Vue.use
官网中,Vue.use(plugin),主要用来安装“插件”,定义如下:
-
参数:
- {Object | Function} plugin
-
用法:
安装 Vue.js 插件。如果插件是一个对象,必须提供 install 方法。如果插件是一个函数,它会被作为 install 方法。install 方法调用时,会将 Vue 作为参数传入。
该方法需要在调用 new Vue() 之前被调用。
当 install 方法被同一个插件多次调用,插件将只会被安装一次。
5.1 案例
结合上面的Vue.extend的案例2进行一起讲解,
<html>
<head>
<title>Vue.use 用法</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<style>
#loading-wrapper {
position: fixed;
top: 0;
left: 0;
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
background: rgba(0,0,0,.7);
color: #fff;
}
</style>
</head>
<body>
<div id="root">
<button @click="showLoading">显示Loading</button>
</div>
<script>
// 定义一个loading插件,将插件需要定义的方法声明在install方法里,
const loadingPlugin = {
// 在install方法里,传入vm作为Vue
install: function(vm) {
// 通过extend定义一个LoadingComponent的构造函数
const LoadingComponent = vm.extend({
template: '<div id="loading-wrapper">{{msg}}</div>',
props: {
msg: {
type: String,
default: 'loading...'
}
}
}, 'LoadingComponent')
function Loading(msg) {
const div = document.createElement('div')
div.setAttribute('id', 'loading-wrapper')
document.body.append(div)
new LoadingComponent({
props: {
msg: {
type: String,
default: msg
}
}
}).$mount('#loading-wrapper')
return () => {
document.body.removeChild(document.getElementById('loading-wrapper'))
}
}
vm.prototype.$loading = Loading
}
// install方法结束
}
Vue.use(loadingPlugin)
new Vue({
el: '#root',
methods: {
showLoading() {
const hide = this.$loading('正在加载,请稍等...')
setTimeout(() => {
hide()
}, 2000)
}
}
})
</script>
</body>
</html>
6. 指令
根据官方文档的理解,指令(Directives)是带有v- 前缀的特殊属性。对于指令v-的值,预期结果就相当于一个JS表达式计算的结果,例如:
<p v-if="seen">你可以看到我了</p>
如果seen的值为false,则不会插入该<p>
元素。
<div id="app">
<label for="r1">控制p标签元素的展示。</label><input type="checkbox" v-model="use" id="r1">
<br><br>
<p v-if="use">你可以看到我了</p>
</div>
<script>
new Vue({
el: '#app',
data:{
use: false
}
});
</script>
运行该demo,可以发现指令的控制就是响应式地操作DOM。指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM。
一些指令能够接收一个“参数”,在指令名称之后以冒号表示。例如,v-bind 指令可以用于响应式地更新 HTML attribute:
<a v-bind:href="url">...</a>
在这里 href 是参数,告知 v-bind 指令将该元素的 href attribute 与表达式 url 的值绑定。
另一个例子是 v-on 指令,它用于监听 DOM 事件:
<a v-on:click="doSomething">...</a>
6.1 缩写
v- 前缀作为一种视觉提示,用来识别模板中 Vue 特定的 attribute。当你在使用 Vue.js 为现有标签添加动态行为 (dynamic behavior) 时,v- 前缀很有帮助,然而,对于一些频繁用到的指令来说,就会感到使用繁琐。同时,在构建由 Vue 管理所有模板的单页面应用程序 (SPA - single page application) 时,v- 前缀也变得没那么重要了。因此,Vue 为 v-bind 和 v-on 这两个最常用的指令,提供了特定简写:
v-bind的缩写
<!-- 完整语法 -->
<a v-bind:href="url">...</a>
<!-- 缩写 -->
<a :href="url">...</a>
<!-- 动态参数的缩写 (2.6.0+) -->
<a :[key]="url"> ... </a>
v-on
<!-- 完整语法 -->
<a v-on:click="doSomething">...</a>
<!-- 缩写 -->
<a @click="doSomething">...</a>
<!-- 动态参数的缩写 (2.6.0+) -->
<a @[event]="doSomething"> ... </a>
它们看起来可能与普通的 HTML 略有不同,但 : 与 @ 对于 attribute 名来说都是合法字符,在所有支持 Vue 的浏览器都能被正确地解析。而且,它们不会出现在最终渲染的标记中。缩写语法是完全可选的,但随着你更深入地了解它们的作用,你会庆幸拥有它们。