vue-混入

混入

mixin

Mixin 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。一个 mixin 对象可以包含任意组件选项。当组件使用 mixin 对象时,所有 mixin 对象的选项将被“混合”进入该组件本身的选项。

var obj = {
    data:function(){
        return {
          name:'zhangsan'
        }
    }
}
export default {
  mixins:[obj]
}

选项合并

当组件和 mixin 对象含有同名选项时,这些选项将以恰当的方式进行“合并”。

比如,每个 mixin 可以拥有自己的 data 函数。每个 data 函数都会被调用,并将返回结果合并。在数据的 property 发生冲突时,会以组件自身的数据为优先。

var obj = {
data:function(){
    return {
      name:'zhangsan'
    }
}
}
export default {
  mixins:[obj],
  data:function(){
    return {
      name:'lisi'//优先
    }
  }
}

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

 
var obj={
created(){
      console.log(1)
    } 
}

created(){
      console.log(2)//1,2都打印
    }
//钩子函数

值为对象的选项,例如 methods、components 和 directives,将被合并为同一个对象。两个对象键名冲突时,取组件对象的键值对。

全局mixin

你还可以为 Vue 应用程序全局应用 mixin:

//main.js
var obj={
data(){
 return{
       msg:'hello',
   }

createApp(App).mixin(obj).use(store).use(router).mount('#app')

Mixin 也可以进行全局注册。使用时格外小心!一旦使用全局 mixin,它将影响每一个之后创建的组件 (例如,每个子组件)。

钩子函数: 1、是个函数,在系统消息触发时被系统调用  2、不是用户自己触发的

钩子函数的名称是确定的,当系统消息触发,自动会调用。

常见的钩子函数:vue的生命周期函数,vue的自定义指令等

自定义指令

在VUE中,我们可以在实例的directive属性中,自定义指令,这些指令可以被该实例使用;

如果是全局注册话,那么所有的子组件都可以使用!

在 Vue 3 中,我们为自 定义指令创建了一个更具凝聚力的 API。正如你所看到的,它们与我们的组件生命周期方法有很大的不同,即使我们正与类似的事件钩子,我们现在把它们统一起来了:

const MyDirective = {
  created(el, binding, vnode, prevVnode) {}, // 新增
  beforeMount() {},
  mounted() {},
  beforeUpdate() {}, // 新增
  updated() {},
  beforeUnmount() {}, // 新增
  unmounted() {}
}

指令创建

directives:{
    focus:{
      mounted(el, binding, vnode) {
        el.focus()
      }
    }
}

指令钩子函数参数

el:指令所绑定的元素,可以用来直接操作 DOM。

binding:一个对象,包含以下 property:

value:指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2。

oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论 值是否改变都可用。

arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 "foo"。

modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }。

instance:指向vue实例。

vnode:Vue 编译生成的虚拟节点。

prevVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。

指令参数

v-focus:color
el.style[binding.arg] = 'red';

动态指令参数

v-focus:[direction]
direction: 'color'

指令值

v-focus:color="'blue'"
el.style[binding.arg] = binding.value;

渲染函数

Vue 推荐在绝大多数情况下使用模板来创建你的 HTML。然而在一些场景中,你真的需要 JavaScript 的完全编程的能力。这时你可以用渲染函数,它比模板更接近编译器。

例如我们的需求是,在组件标签中传递一个属性值1-6,然后在子组件中分别使用h1-h6去包裹插槽的内容:

<anchored-heading :level="1">Hello world!</anchored-heading>

如果利用传统的模式,我们的逻辑可能会比较复杂,需要判断传值,且放置多个插槽。

<template>
    <h1 v-if="level === 1">
    <slot></slot>
  </h1>
  <h2 v-else-if="level === 2">
    <slot></slot>
  </h2>
  <h3 v-else-if="level === 3">
    <slot></slot>
  </h3>
  <h4 v-else-if="level === 4">
    <slot></slot>
  </h4>
  <h5 v-else-if="level === 5">
    <slot></slot>
  </h5>
  <h6 v-else-if="level === 6">
    <slot></slot>
  </h6>
</template>
<script>
export default {   
    props:['level']
}
</script>

这里用模板并不是最好的选择:不但代码冗长,而且在每一个级别的标题中重复书写了 <slot></slot>。

虽然模板在大多数组件中都非常好用,但是显然在这里它就不合适了。那么,我们来尝试使用 render 函数重写上面的例子:

<script>
import { h,ref } from 'vue'
export default {
    props:['level'],
    setup(props, { slots, attrs, emit }) {    
        return () => [
            h('h' + props.level, { class: 'title' }, slots.default())
        ]
    }
}
</script>

如果我们想要写的更加复杂,可以在h1元素中再创建子元素:

<script>
import { h,ref } from 'vue'
export default {
    props:['level'],
    setup(props, { slots, attrs, emit }) {    
        return () => [
            h('h' + props.level, { class: 'title' }, [
                h('span',{class:'s'},slots.default())
            ])
        ]
    }
}
</script>

h函数的第二个参数:

// 3.x 语法
{
  class: ['button', { 'is-outlined': isOutlined }],
  style: [{ color: '#34495E' }, { backgroundColor: buttonColor }],
  id: 'submit',
  innerHTML: '',
  onClick: submitForm,
  key: 'submit-button'
}

V3 setup() 函数

  • setup函数是v3提供新的组件选项。

  • 之前的data、声明周期、自定义函数都可以放置在内

  • 在创建组件之前执行,初始化props,紧接着就调用setup函数,从生命周期钩子的视角来看,它会在beforeCreate钩子之前被调用

  • 是mixins的强化版,比mixins更加灵活

  • 因为setup()是在解析其它组件选项之前被调用的,所以避免使用this

V3 ref() 函数 

在setup函数中,可以使用ref函数,用于创建一个响应式数据,当数据发生改变时,Vue会自动更新UI

例如:使用ref函数定义一个变量count:

<template>
    <h1>{{ count }}</h1>
    <button @click="change_count">点我</button>
</template>
<script>
import { ref } from 'vue'
export default {   
    setup() {  
        let count = ref(0);
        function change_count() {
            count.value += 1;
        }
        return { count, change_count }
    }
}
</script>

注意:

  • 在setup中定义的变量或方法,都必须通过return {xxx,xxx}暴露出去,外界才能使用

  • ref函数仅能监听基本类型的变化,不能监听复杂类型的变化(比如对象、数组)

V3 reactive 函数

用来检测复杂数据类型的变化

<template>
    <h1>{{ obj }}</h1>
    <button @click="change_age">点我</button>
</template>
<script>
import { reactive } from 'vue'
export default {   
    setup() {  
        let obj = reactive({ name: "Alice", age: 12 });
        function change_age() {
            ++obj.age
        }
        return { obj, change_age }
    }
}
</script>

JSX

如果你写了很多 render 函数,可能会觉得上面这样的代码写起来麻烦,我们需要对元素进行很多配置。

用于在 Vue 中使用 JSX 语法,它可以让我们回到更接近于模板的语法上:

<script>
export default {
    props:['level'],
    setup(props, { slots, attrs, emit }) {   
        return () => <h1>{slots.default()}</h1>
    }
}
</script>

注意:在HTML文件中,JSX是无法编译的,在脚手架中可以。

自定义插件

插件通常用来为 Vue 添加全局功能。插件的功能范围没有严格的限制——一般有下面几种:

添加全局方法或者 property。如:vue-custom-element

添加全局资源:指令/过滤器/过渡等。如 vue-touch

通过全局混入来添加一些组件选项。如 vue-router

添加 Vue 实例方法,通过把它们添加到 Vue.prototype 上实现。

一个库,提供自己的 API,同时提供上面提到的一个或多个功能。如 vue-router

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

myplugin.js vue3
export default{
    
    install:(Vue,options)=>{
        console.log(options)
        //1.在插件中封装一个方法
        Vue.config.globalProperties.$getname=()=>{
            console.log('xiaoming');
        },
        //2.在插件中封装一个指令
         Vue.directive('color', {
                created(el, binding, vnode, oldVnode) {
                el.style.color='red';
            }
        })
        //3.为插件插件一个mixin
        Vue.mixin({
            data(){
                return{
                    admin:'zhangsan'
                }
            }
        })
    }
}

插件的使用:

main.js
import myplugin from './utils/myplugin'
createApp(App).use(myplugin,{}).mount('#app') 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值