在Vue中提供了一套为数据驱动视图更为方便的操作,这些操作被称为指令系统。我们看到的v-来头的行内属性,都是指令,不同的指令可以完成或者实现不同的功能。
除了核心功能默认内置的指令(v-model和v-show),Vue也允许注册自定义指令
指令使用的几种方式:
- //会实例化一个指令,但这个指令没有参数
- `v-xxx`
-
- // -- 将值传到指令中
- `v-xxx="value"`
-
- // -- 将字符串传入到指令中,如`v-html="'
内容
'"` - `v-xxx="'string'"`
-
- // -- 传参数(`arg`),如`v-bind:class="className"`
- `v-xxx:arg="value"`
-
- // -- 使用修饰符(`modifier`)
- `v-xxx:arg.modifier="value"`
注册一个自定义指令类似于组件注册,分为全局注册和局部注册。
举例如下:
Vue.directive第一个参数是指令的名字(不需要加上v-前缀),第二个参数可以是一个对象,也可以是一个指令函数
- Vue.directive('focus',{
- inserted:function(el){
- // 聚焦元素
- el.focus();//页面加载完成之后自动让输入框获取到焦点的小功能
- }
- })
局部注册通过在组件options选项中设置directive属性
- directive:{
- // 指令的定义
- focus:{
- inserted:function(el){
- el.focus()
- }
- }
- }
然后可以在模板中任何元素上使用v-focus指令,如下:
<input v-focus />
自定义指令也想组件一样存在钩子函数:
所有钩子函数的参数都有以下:
注意:除了el之外,其他参数都应该是只读的,切勿进行修改。如果需要再钩子之间共享数据,建议通过元素的dataset来进行。
举个栗子:
- "{ color: 'white', text: 'hello!' }">
- <script>
- Vue.directive('demo', function (el, binding) {
- console.log(binding.value.color) // "white"
- console.log(binding.value.text) // "hello!"
- })
- script>
使用自定义指令可以满足我们的日常一些场景,这里我列举几个我在项目中用到的自定义指令:
- Vue.directive('throttle', {
- inserted(el, binding) {
- // 获取指令参数时间,没有则默认赋值为2000
- let throttleTime = parseInt(binding.value) || 2000
- el.addEventListener('click', () => {
- // 第一次执行
- if (!el.disabled) {
- // 如果是第一次执行则表示可以进行点击操作
- el.disabled = true
- setTimeout(() => {
- el.disabled = false
- }, throttleTime)
- }
- })
- }
- })
-
- // 2.为button标签设置v-throttle自定义指令
- <Button size="large" type="success" v-throttle="5000">新增Button>
- // 一键复制自定义指令
- Vue.directive('copy', {
- // 选取文本框内容
- // 执行浏览器复制命令
- // 复制命令会将当前选中的内容复制到剪切板中(这里就是创建的input标签)
- // Input要在正常的编辑状态下原生复制方法才会生效
- inserted (el, binding) {
- if (!binding.value) {
- Message.error('请传入需要复制的内容')
- return
- }
- el.addEventListener('click', () => {
- console.log('binding.value', binding.value)
- // 模拟输入框
- let cInput = document.createElement('input')
- if (binding.value.newAccount === '') {
- cInput.value = '密码' + ':' + binding.value.newPassword
- } else {
- cInput.value = `企业名称:${binding.value.newCompanyName} , 用户名:${binding.value.newWebAccount} , 密码:${binding.value.newPassword};`
- }
- document.body.appendChild(cInput);
- cInput.select();
- document.execCommand("copy");
- Message.success('复制成功')
- document.body.removeChild(cInput);
- this.dialogVisible = false;
- // 这个根据自己业务自定义
- Vue.prototype.$emit("afterComfirm");
- })
- },
- componentUpdated(el, { value }) {
- el.$value = value;
- },
- })
-
-
- // 为button标签设置v-copy自定义指令
- <Button size="large" type="success" v-copy="infoObj">新增Button>
-
- // 其中infoObj如下:
- infoObj:{
- newPassword:this.newPassword,
- newAccount:this.newAccount
- ...
- }
-
- // 后面可以扩展将字段为传入的字段,不要写死