平时习惯了用自己所知的方法来解决问题。今天看到自己之前写的组件被同事改了一下,看到一些没怎么用过的方法。特意去恶补了一下,算给自己打个补丁并记录一下。
provide/inject
provide,inject这个东西,说实话我个人觉得至此为止,我遇到的工作中他能用的场景其实不多。这个东西就是props的加强版。
一搬父子传参我们可以用:
1.props
父子组件间通过属性的写法,直接传参。
// 父组件
<children :parmas="data"></children>
// 子组件用props接
props:{
data: Object
}
// 使用时直接在本vue实例用调
this.data
2.vuex
状态管理就是一个全局的库,在根部注册后,在任意实例中都可以通过store调用变量。
this.$store.state
3.provide/inject
这个就是介于前两者之间的东西。他是通过在某一父组件中注册一个变量。在其子孙组件中可以调用其变量。不局限在直接父子间。
用法:
// 父组件中
export default {
name: "Parent",
provide: {
for: "demo"
}
}
// 子孙组件
export default {
name: "grandson",
inject: ['for']
}
// 调用也是跟props一样
this.for
provide/inject就是一个局部的小库。在一些整体没有必要引Vuex,在某个模块中又需要用到一个库的项目中它是可以考虑的选择。
directive(自定义指令)
需要批量操作特定dom的时候,特别是需要用到dom节点的时候。可以考虑用自定义指令完成。 这个官网解释得很详细。自定义指令
1.注册
// 注意是在根部Vue调用directive注册,这里写指令的时候不需要加"v-"
Vue.directive('focus', {
inserted: function (el) {
el.focus()
}
})
2.使用
// 直接加"v-"即可,dom被直接聚焦
<input v-focus>
3.生命周期(钩子)
- bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
- inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
- update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。
- componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
- unbind:只调用一次,指令与元素解绑时调用。
4.参数解析
- el:指令所绑定的元素,可以用来直接操作 DOM 。
binding:一个对象,包含以下属性:
- name:指令名,不包括 v- 前缀。
- value:指令的绑定值,例如:v-my-directive=”1 + 1″ 中,绑定值为 2。
- oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
- expression:字符串形式的指令表达式。例如 v-my-directive=”1 + 1″ 中,表达式为 “1 + 1″。
- arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 “foo”。
- modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }。
- vnode:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。
- oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。
slot
slot是一个插槽。子组件假如是一个常用的模板,可是当中的内容又想要跟据父组件的不同有所不同。那么slot就可以排上用场。而slot本身有三种用法。
1.单个插槽| 默认插槽| 匿名插槽
// 父组件
<template>
<div class="father">
<h3>父组件</h3>
// child是子组件
<child>
// 里面内容便是插槽内容
<div class="tmpl">
<span>菜单1</span>
<span>菜单2</span>
</div>
</child>
</div>
</template>
// 子组件
<template>
<div class="child">
<h3>子组件</h3>
// 插槽预留位置
<slot></slot>
</div>
</template>
这样最终渲染出来的效果就是
<div class="father">
<h3>父组件</h3>
<div class="child">
<h3>子组件</h3>
<div class="tmpl">
<span>菜单1</span>
<span>菜单2</span>
</div>
</div>
</div>
这样子组件的内容便可以根据不同父组件的插槽内容来改变适应项目场景。
2.具名插槽
// 父组件
<template>
<div class="father">
<h3>父组件</h3>
<child>
<div class="tmpl" slot="up">
<span>菜单1</span>
<span>菜单2</span>
</div>
</child>
</div>
</template>
<template>
<div class="child">
<slot name="up"></slot>
<h3>这里是子组件</h3>
<slot></slot>
</div>
</template>
父组件中有slot属性注明的插槽内容会对应插入到slot 对应name的节点上。而匿名slot用法依旧。
3. 作用域插槽| 带数据的插槽
父组件在调用slot时可以访问子组件中的数据。
// 子组件中
<template>
<div class="child">
<h3>这里是子组件</h3>
// 作用域插槽data在script中定义
<slot :data="data"></slot>
</div>
</template>
// 父组件
<template>
<div class="father">
<h3>父组件</h3>
<child>
<template slot-scope="user">
<div class="tmpl">
<span v-for="item in user.data">{{item}}</span>
</div>
</template>
</child>
</div>
</template>
注意:slot是否使用是根据父组件调用时子组件标签中是否包含其他html模板,假如没有模板slot是无效的。
vue.use
平时全局注册组件或者工具,我们会用到use。但其实use,我们在自己的项目中也能针对自己的工具制定。
vue.use其实就是调用了一个函数。
// main.js中
import Vue from 'vue';
import test form "./use"
Vue.use(test);
//use.js中
export default function(a,b,c,d){
console.log(a,b,c,d)
}
// 打印输出结果是
ƒ Vue (options) {
if ( true &&
!(this instanceof Vue)
) {
warn('Vue is a constructor and should be called with the `new` keyword');
}
this._init(options);
} undefined undefined undefined
函数会传入一个Vue对象。这就可以让我们定制自己的内容。
批量注册
平时全局注册组件时。会用Vue.component()
// use.js中
import component1 from "./component1";
import component2 from "./component2";
import component3 from "./component3";
...
Vue.component(component1,component1);
Vue.component(component2,component2);
Vue.component(component3,component3);
...
这样就可以批量注册Vue组件了。
添加自己的vue方法
在use中可以定制添加自己常用的方法。
// use.js中
function add(){
...
}
Vue.prototype.add = add