Vue.js之自定义指令、混入mixin、自定义插件、过渡与动画、异步组件

1.自定义指令

概念:
除了核心功能默认内置的指令 (如:v-model 和 v-show),Vue 也允许注册自定义指令。注意,在 Vue2.0 中,代码复用和抽象的主要形式是组件。然而,有的情况下,你仍然需要对普通 DOM 元素进行底层操作,这时候就会用到自定义指令。

全局自定义指令
全局定义:Vue.directive( 指令的名称,指令的选项 )

// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
  // 当被绑定的元素插入到 DOM 中时……
  inserted: function (el) {
    // 聚焦元素
    el.focus()
  }
})

局部自定义指令
局部定义:组件内选项: directives

directives: {
  focus: {
    // 指令的定义
    inserted: function (el) {
      el.focus()
    }
  }
}

然后你可以在模板中任何元素上使用新的 v-focus 属性,如下:

<input v-focus>

自定义指令中的钩子函数
一个指令定义对象可以提供如下几个钩子函数 (均为可选):
bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。
componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
unbind:只调用一次,指令与元素解绑时调用。

钩子函数参数
指令钩子函数会被传入以下参数:
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 钩子中可用。

案例:实现输入框自动获得焦点

<body>
  <div id="app" >
    <input type="text"v-focus>
  </div>
</body>
<script src="https://cdn.bootcss.com/vue/2.6.10/vue.js"></script>
<script>
  new Vue({
    el: '#app',
    directives:{
      'focus':{
       inserted(el){
          el.focus()
        }
      }
    }
  })
</script>

2.混入 mixin

混入 (mixin) 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。一个混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项。简单的说就是将组件的选项中的一部分分离出去,单独管理。
混入的方式有两种:

局部混入 mixins
局部混入定义示例代码:
定义一个局部混入将new Vue中的methods选项拿出来单独管理,当然该部分,也可单独写在一个js文件中,通过script引入来使用

  const obj={
    methods:{
      test(){
        alert('Hello World!')
      }
    }
  }

在new Vue() 实例中引用,mixins: [ 拿出来单独管理的自定义的名字 ],

 new Vue({
    el: '#app',
    mixins: [ obj ],
  })

完整案例代码如下:

<body>
  <div id="app">
    <button @click = "aa"> 点击 </button>
    <button @click = "bb"> 点击 </button>
  </div>
</body>
<script src="../../lib/vue.js"></script>
<script>
const obj = {
  methods: {
    test () {
      alert('Hello World!')
    }
  }
}
  new Vue({
    el: '#app',
    mixins: [ obj ],//引入定义的混合
    methods: {//虽然obj中有methods选项,但是在此处还是可以定义methods选项,并不冲突,可以看成
                //是两处的methods合并了
      bb () {
        alert('bb')
      },
      test () {//该方法在obj中的methods选项中已存在,故会将obj中的methods选项中的aa()覆盖。
        alert('你好 世界!')
      }
    }
  })
</script>

全局混入 Vue.mixin
全局混入定义示例代码:

 Vue.mixin({
    methods:{
      test(){
        alert('Hello World!')
      }
    }
  })

请谨慎使用全局混入,因为它会影响每个单独创建的 Vue 实例 (包括第三方组件)。大多数情况下,只应当应用于自定义选项,就像上面示例一样。
完整案例代码如下:

<body>
  <div id="app">
    <button @click = "aa"> 点击 </button>
  </div>
</body>
<script src="../../lib/vue.js"></script>
<script>
  // Vue.mixin(选项)
  Vue.mixin({
    methods: {
      aa () {
        alert('aa')
      }
    }
  })
  new Vue({
    el: '#app',
  })
</script>

3.自定义插件

(1). 定义的插件应该有一个 install 方法
(2) 自定义插件必须使用 Vue.use( 插件名称 ) 才能使用插件

例:自定义一个输入框自动获得焦点的插件
示例代码如下:
插件定义:最好写在一个单独的js文件中,然后通过script引入,如下

const MyPlugin = {
  install ( Vue, options ) {
    Vue.directive('focus',{
      inserted ( el ) {
        el.focus()
        el.style.background = 'red'
      }
    })
  }
}

插件引入并使用:
插件通过script引入,使用时用

Vue.use(插件名 ) 

完整插件引入并使用当示例代码如下:

<body>
  <div id="app">
    <input type="text" v-focus>
    <Hello></Hello>
  </div>
</body>
<script src="../../lib/vue.js"></script>
<script src="./10-自定义插件.js"></script>
<script>
  Vue.use( MyPlugin ) //使用插件
 Vue.component('Hello',{
      template: '<div> hello </div>'
      })
  new Vue({
    el: '#app'
  })
</script>

4.过渡&动画

过渡
Vue 在插入、更新或者移除 DOM 时,提供多种不同方式的应用过渡效果。
包括以下工具:
在 CSS 过渡和动画中自动应用 class
可以配合使用第三方 CSS 动画库,如 Animate.css
在过渡钩子函数中使用 JavaScript 直接操作 DOM
可以配合使用第三方 JavaScript 动画库,如 Velocity.js

Vue 提供了 transition 的封装组件(内置组件),在下列情形中,可以给任何元素和组件添加进入/离开过渡。
条件渲染 (使用 v-if)
条件展示 (使用 v-show)
动态组件
组件根节点

过渡的类名
在进入/离开的过渡中,会有 6 个 class 切换。
v-enter:定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除。
v-enter-active:定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数。
v-enter-to(已被废弃,但是还是能使用): 2.1.8版及以上 定义进入过渡的结束状态。在元素被插入之后下一帧生效 (与此同时 v-enter 被移除),在过渡/动画完成之后移除。
v-leave: 定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除。
v-leave-active:定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。
v-leave-to(已被废弃,但是还是能使用): 2.1.8版及以上 定义离开过渡的结束状态。在离开过渡被触发之后下一帧生效 (与此同时 v-leave 被删除),在过渡/动画完成之后移除。
对于这些在过渡中切换的类名来说,如果你使用一个没有名字的 ,则 v- 是这些类名的默认前缀。如果你使用了 ,那么 v-enter 会替换为 my-transition-enter。
这里以一个例子来说明:

<div id="demo">
  <button v-on:click="show = !show">
    Toggle
  </button>
  <transition name="fade">//此处的fade是与写的类名.fade-enter-active对应的
    <p v-if="show">hello</p>
  </transition>
</div>

new Vue({
  el: '#demo',
  data: {
    show: true
  }
})

.fade-enter-active, .fade-leave-active {
  transition: opacity .5s;
}
.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
  opacity: 0;
}

自定义过渡的类名
我们可以通过以下特性来自定义过渡类名:
enter-class
enter-active-class
enter-to-class (2.1.8+)
leave-class
leave-active-class
leave-to-class (2.1.8+)
他们的优先级高于普通的类名,这对于 Vue 的过渡系统和其他第三方 CSS 动画库,如 Animate.css 结合使用十分有用。
示例:

5、异步组件

在大型应用中,我们可能需要将应用分割成小一些的代码块,并且只在需要的时候才从服务器加载一个模块。为了简化,Vue 允许你以一个工厂函数的方式定义你的组件,这个工厂函数会异步解析你的组件定义。Vue 只有在这个组件需要被渲染的时候才会触发该工厂函数,且会把结果缓存起来供未来重渲染。
如你所见,这个工厂函数会收到一个 resolve 回调,这个回调函数会在你从服务器得到组件定义的时候被调用。你也可以调用 reject(reason) 来表示加载失败。这里的 setTimeout 是为了演示用的,如何获取组件取决于你自己。一个推荐的做法是将异步组件和 webpack 的 code-splitting 功能一起配合使用:

Vue.component('async-webpack-example', function (resolve) {
  // 这个特殊的 `require` 语法将会告诉 webpack
  // 自动将你的构建代码切割成多个包,这些包
  // 会通过 Ajax 请求加载
  require(['./my-async-component'], resolve)
})

你也可以在工厂函数中返回一个 Promise,所以把 webpack 2 和 ES2015 语法加在一起,我们可以写成这样:

Vue.component(
  'async-webpack-example',
  // 这个 `import` 函数会返回一个 `Promise` 对象。
  () => import('./my-async-component')
)

当使用局部注册的时候,你也可以直接提供一个返回 Promise 的函数:

new Vue({
  // ...
  components: {
    'my-component': () => import('./my-async-component')
  }
})
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值