前端修仙路- vue基础进阶

前端修仙路- vue基础进阶

前言:我们大多数人在使用vue的时候,觉得很简单,但实际基础不扎实,有很多好用的特性项目中并没有用到,久而久之就忘了,特写此文铭记。


混入(mixin)

概念解释: 当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项。

混入规则

  1. data混入: 合并data,如果键名冲突以组件数据优先。
  2. 钩子混入(生命周期函数): 同名钩子合并成一个数组,依次调用,并且混入钩子优先调用。
  3. 值为对象的混入:如 methods、components 和 directives,将被合并为同一个对象。键名冲突时,组件数据优先。

eg:

var mixin = {
  created: function () {
    console.log('混入对象的钩子被调用')
  },
  data: function () {       //混入data
    return {
      message: 'hello',
      foo: 'abc'
    }
  }
}

new Vue({
  mixins: [mixin],          //局部混入
  data: function () {
    return {
      message: 'goodbye',
      bar: 'def'
    }
  },
  created: function () {
    console.log(this.$data)
  }
})
//=> 混入对象的钩子被调用
// => { message: "goodbye", foo: "abc", bar: "def" }

全局混入

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

new Vue({
  myOption: 'hello!'
})
// => "hello!"

小提示

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

自定义指令(directive)

概念解释: 常见的指令有v-model,v-show等,当你需要操作dom的时候,就可以用自定义指令来处理。

钩子(指令生命周期)

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

钩子参数

含有黄色标注的应该重点记忆,比较常用:

  • el:指令所绑定的元素,可以用来直接操作 DOM。
  • binding:一个对象,包含以下 property:
    • 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 钩子中可用。

eg:

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

//注册局部指令
export default{
    // ...省略组件无关选项
    directives: {
        focus: {
            // 指令的定义
            inserted: function (el,binding) {
            el.focus()
            }
        }
    }
}
// <input v-focus>  使用指令

动态指令参数

指令的参数可以是动态的。例如,在 v-mydirective:[argument]="value" 中,argument 参数可以根据组件实例数据进行更新!

// 注册v-pin指令
Vue.directive('pin', function (el, binding) { //为函数表示触发bind和update
    el.style.position = 'fixed'
    var s = (binding.arg == 'left' ? 'left' : 'top')
    el.style[s] = binding.value + 'px'
  }
)


new Vue({
  el: '#dynamicexample',
  data: function () {
    return {
      direction: 'left'
    }
  }
})

// <p v-pin:[direction]="200">I am pinned onto the page at 200px to the left.</p>

过滤器(filter)

用途:过滤器常用于一些常见的文本格式化。

两种注册方式:

// 全局注册capitalize过滤器
Vue.filter('capitalize', function (value) {
  if (!value) return ''
  value = value.toString()
  return value.charAt(0).toUpperCase() + value.slice(1)
})

// 局部注册
export default{
  // ...省略无关选项
  filters: {
    capitalize: function (value) {
        if (!value) return ''
        value = value.toString()
        return value.charAt(0).toUpperCase() + value.slice(1)
        }
    }
}

使用方式也有两种:

<!-- 在双花括号中 -->
{{ message | capitalize }}

<!-- 在 `v-bind` 中 -->
<div v-bind:message="message | capitalize"></div>

插件

概念解释:插件通常用来为 Vue 添加全局功能。

用途

  1. 添加全局方法或者 property
  2. 添加全局资源:指令/过滤器/过渡等
  3. 通过全局混入来添加一些组件选项,如vue-router
  4. 添加 Vue 实例方法,通过把它们添加到 Vue.prototype 上实现

自定义插件:

let MyPlugin = {};
MyPlugin.install = function (Vue, options) {
  // 1. 添加全局方法或 property
  Vue.myGlobalMethod = function () {
    // 逻辑...
  }

  // 2. 添加全局资源
  Vue.directive('my-directive', {
    bind (el, binding, vnode, oldVnode) {
      // 逻辑...
    }
    ...
  })

  // 3. 注入组件选项
  Vue.mixin({
    created: function () {
      // 逻辑...
    }
    ...
  })

  // 4. 添加实例方法
  Vue.prototype.$myMethod = function (methodOptions) {
    // 逻辑...
  }
}
export default MyPlugin

使用插件:

// 调用 `MyPlugin.install(Vue)`
Vue.use(MyPlugin, { someOption: true }) //第二个参数可选

函数式组件(functional)

概念解释:函数式组件用来定义那些没有响应数据,也不需要有任何生命周期的场景,它只接受一些props 来显示组件。

使用方法:

  • 方式一:
Vue.component('component', {
  functional: true,
  // Props 是可选的
  props: {
    // ...
  },
  // 为了弥补缺少的实例
  // 提供第二个参数作为上下文
  render: function (createElement, context) {
    // ...
  }
})
  • 方式二
<template functional>   //render 可以改写成template
  <div class="root">
      hello {{props.name}}  //渲染props
  </div>
</template>

<script>
export default {
    functional:true,    //启用函数式组件
    props:{
        name:{
            type:String,
            default:'hzz'
        }
    },
    name:'HelloWorld'
}
</script>

正因为函数组件没有响应式数据,也不需要生命周期函数,因此性能会有所提升,如果只是纯静态展示内容,推荐使用函数式组件。

提供/注入(provide/inject)

概念解释:这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。如果你熟悉 React,这与 React 的Context特性很相似。

用途:provide 和 inject 主要在开发高阶插件/组件库时使用。并不推荐用于普通应用程序代码中。

eg:

// 祖先组件
export default{
    //...省略组件无关选项
    provide: {
        foo: 'bar'
    }
}

// 子孙组件
export default{
    //...省略组件无关选项
    inject: ['foo'],
    created () {
        console.log(this.foo) // => "bar"
    }
}

提示

provide 和 inject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的 property 还是可响应的。

彩蛋

看vue文档,发现了一个奇特的跨组件传值方式,特分享给大家:

共享数据

import Vue from 'vue'
const state = Vue.observable({count:0})
export default state

组件A

<template>
  <div class="root">
      crossA count: {{this.count}}
  </div>
</template>

<script>
import state from '../module/crossState';
export default {
    props:{},
    computed:{
        count(){return state.count}
    },
    name:'CrossA'
}
</script>

组件B

<template>
  <div @click="changeCount()" class="root">
      crossB count: {{this.count}}
  </div>
</template>

<script>
import state from '../module/crossState';
export default {
    props:{},
    methods:{
        changeCount(){
            state.count++
        }
    },
    computed:{
        count(){return state.count}
    },
    name:'CrossB'
}
</script>

当点击组件B的时候,组件A的值也会跟着改变,其核心利用了Vue.observable定义了一个响应式对象,而计算属性依赖该对象属性,于是count改变时,重新计算属性,实现了数据的双向绑定,也实现了跨组件传值。

这期到此结束 😃

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值