Vue2.x高级使用

332 阅读2分钟

混入MIXIN

提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。

简单来说:mixin是一个抽离的vue公共对象

示例:

var mixins = {
    data () {
        return {
            username: "小明"
        }
​
    },
    computed: {
        reverseUsername () {
            return this.username.split('').reverse().join("")
        }
    },
    methods: {
        changeUsername () {
            this.username += "真帅!"
        }
    },
    created () {
        console.log("created")
    },
    mounted () {
        console.log("userMixin:mounted")
    },
}
​
​
export default mixins
import userMixin from ".../mixins"
export default {
  name: 'App',
  mixins:[userMixin],
  data(){
    return {
        username: "小黄"       
    }
  }
}

特点

选项合并

  • data冲突

    • 当组件和混入对象含有同名选项时,这些选项将以恰当的方式进行“合并”。冲突时以组件数据优先

      • 在mixins中和本身的data都用username,这时显示的是 “小黄”
    • 值为对象的选项将被合并为同一个对象;两个对象键名冲突时,取组件对象的键值对。

  • 钩子函数

    • 同名钩子函数将合并为一个数组,因此都将被调用。
    • 混入对象的钩子将在组件自身钩子之前调用。

全局混入——慎用

使用时格外小心!一旦使用全局混入,它将影响每一个之后创建的 Vue 实例。使用恰当时,这可以用来为自定义选项注入处理逻辑。

// 为自定义的选项 'myOption' 注入一个处理器。
Vue.mixin({
  created: function () {
    var myOption = this.$options.myOption
    if (myOption) {
      console.log(myOption)
    }
  }
})
​
new Vue({
  myOption: 'hello!'
})
// => "hello!"

请谨慎使用全局混入,因为它会影响每个单独创建的 Vue 实例 (包括第三方组件)。大多数情况下,只应当应用于自定义选项,就像上面示例一样。推荐将其作为插件发布,以避免重复应用混入。

自定义指令

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

举个聚焦输入框的例子,当页面加载时,将获得焦点。

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

注册局部指令

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

可以在模板中任何元素上使用新的 v-focus property,如下:

<input v-focus/>

钩子函数

一个指令定义对象可以提供如下几个钩子函数 (均为可选):

  • bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
  • inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
  • update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新。

钩子函数参数

指令钩子函数会被传入以下参数:

  • el:指令所绑定的元素,可以用来直接操作 DOM。
  • 一个对象,包含以下 property: binding
    • name:指令名,不包括 v- 前缀。
    • value:指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2
    • oldValue:指令绑定的前一个值,仅在 updatecomponentUpdated 钩子中可用。无论值是否改变都可用。
    • 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:上一个虚拟节点,仅在 updatecomponentUpdated 钩子中可用。

除了 el 之外,其它参数都应该是只读的,切勿进行修改。

image-20211208141038902.png

指令参数

指令的参数可以是动态的,绑定到对应的数据上。

<input v-model="value" v-focus="color"/>
data () {
    return {
      value: '' ,
      color: "yellow" 
    }
},
directives: {
    focus: {
      inserted(el, option) {
        el.focus()
        el.style.borderColor = option.value ? option.value : "black"
      }
    }
  }

v-focus绑定到color数据上,通过传入的option对象中的value值获取到数据,从而给输入框改样式。

函数简写

Vue.directive('color-swatch', function (el, binding) {
  el.style.backgroundColor = binding.value
})

想在 bindupdate 时触发相同行为,而不关心其它的钩子。

这同样也是全局注册自定义指令

自写插件

Vue.js 的插件应该暴露一个 install 方法。这个方法的第一个参数是 Vue 构造器,第二个参数是一个可选的选项对象:

  • 创建一个文件夹,然后在文件夹右键打开终端 npm init初始化
  • 创建index.js文件,将下面的自定义插件内容放进去
let myStyle = {
  install (Vue, options) {
    // 增加Vue的全局方法
    Vue.myGlobalMethod = function () {
      console.log("myStyle定义的全局方法");
    }
​
    // 添加全局指令
    Vue.directive("mystyle", {
      bind (el) {
        if (el.tagName === "INPUT") el.setAttribute("placeholder", "myStyle is here")
      }
    })
​
    // 添加全局混入
    Vue.mixin({
      method: {
        getMyBlogUrl() {
          console.log("https://juejin.cn/user/449027926131966/posts");
        }
      }
    })
​
    // 添加全局消息总线方法
    Vue.prototype.$eventBus = new Vue()
  }
}
​
export default myStyle

发布插件

  1. npm adduser 先登录(没注册的去npm官网注册)
  2. 按顺序输入账号、密码、邮箱
  3. npm publich 注意:install后面的名字是在npm init后产生的package.json文件里面的name
npm install lxm-style // 下载

image-20211208163008972.png

image-20211208163046196.png

image-20211208163149437.png

<input v-model="value" v-focus="color" v-mystyle @change="getMyBlogUrl"/>

image-20211208163336636.png

过滤器

Vue.js 允许你自定义过滤器,可被用于一些常见的文本格式化。过滤器可以用在两个地方:双花括号插值和 **v-bind** 表达式

<!-- 在双花括号中 -->
{{ message | capitalize }}
​
<!-- 在 `v-bind` 中 -->
<div v-bind:id="rawId | formatId"></div>

你可以在一个组件的选项中定义本地的过滤器

filters: {
  capitalize: function (value) {
    if (!value) return ''
    value = value.toString()
    return value.charAt(0).toUpperCase() + value.slice(1)
  }
}

在创建 Vue 实例之前全局定义过滤器:

Vue.filter('capitalize', function (value) {
  if (!value) return ''
  value = value.toString()
  return value.charAt(0).toUpperCase() + value.slice(1)
})
​
new Vue({
  // ...
})

过滤器也可以串联使用,由于每个过滤器返回的值可以作为下一个过滤器的参数

{{ message | filterA | filterB }}