Vue基础知识-脚手架开发-props、ref、mixin(混入) 与plugin (插件) 全解析

一、项目结构与完整代码

首先梳理项目结构(基于 Vue-cli 初始化的基础结构),确保代码文件对应清晰:

src/
├─ components/       # 组件目录
│  ├─ Student.vue    # 学生组件(props演示)
│  ├─ Mixin1.vue     # 混入演示组件1
│  └─ Mixin2.vue     # 混入演示组件2
├─ mixin.js          # 混入文件(代码复用)
├─ plugins.js        # 插件文件(全局功能)
├─ App.vue           # 根组件(整合所有特性)
└─ main.js           # 入口文件(初始化Vue、引入插件)

1. src/mixin.js(混入文件:代码复用)

/* 
    编写混合
    这里用分别暴露 
    mixin混入:
        对于data中的数据及methods方法:若原来的组件有用原来的,没有则混合加入
        对于钩子函数:先执行混合里的。再执行组件自己的

*/
export const mixin = {
    data() {
        return {
            x:100
        }
    },
    methods:{
        show(){
            alert(this.name)
        },
       
    },
    mounted() {
        console.log('挂载完毕')
    },
}

2. src/plugins.js(插件文件:全局功能扩展)

/* 
Vue插件:本质是包含install方法的对象,用于扩展Vue全局功能
  install方法参数:
  - Vue:Vue构造函数(固定第一个参数)
  - options:Vue.use(plugin, options)传递的额外参数(可选)
*/
export default{
    install(Vue,args){ //args参数可省略
        //定义全局过滤器 Vue.filter()
        //定义全局指令Vue.directive()
        //定义全局混入Vue.mixin()
        //定义全局方法
        Vue.prototype.hello = (msg)=>{alert(msg)}
    }
}

3. src/components/Student.vue(props 演示:父子通信)

<template>
    <div>
        <h1>{{ msg }}</h1>
        <h1>姓名:{{ name }}</h1>
        <h1>年龄{{ age+1 }}</h1>
    </div>
</template>

<script>
    export default {
        name:"Student",
        data() {
            return {
                msg:'北京大学',
            }
            
        },
        //props作用:让组件可以接受外部传入的数据。props中的内容会出现在vc身上
        // 写法1:表示可以在使用该组件时传入age,name参数。*用得多*
        props:['age','name'],
        /* 
        写法2:限定参数类型。不符合控制台会给警告
        props:{
            name:String,
            age:Number
        } 
        写法3:
        props:{
            name:{
                type:String,
                required:true //引用该组件必须要传入name,不传控制台会给警告。required和default不共存,没意义
            },
            age:{
                type:Number,
                default:99 //默认值
            }
        } 
        */
       /* 
        props中的属性不建议修改,会有警告。因为Vue框架设计的核心之一是单向数据流,即数据从父组件流向子组件,并通过props传递。这便于调试
        <input type="button" value="age++" @click="age++"/> 
        若有改的业务,解决方法:
            data(){
                return{
                    //让myAge来进行状态管理
                    myAge:this.age  //这里的this.age来源于props。说明先加载props再加载data
                }
            }
        */ 
    }
</script>

<style>

</style>

4. src/components/Mixin1.vue(混入演示 1)

<template>
    <div>
        <h1 @click="show">点我显示name1</h1>
    </div>
</template>

<script>
    import {mixin}  from '../mixin'
    export default {
        data() {
            return {
                name:'name1'
            }
        },
        //引入了mixin中的methos,data,amounted
        mixins:[
            mixin
        ],
        /* 
        methods:{
            show(){
                alert(this.name)
            }
        }  
        */
    }
</script>

<style>

</style>

5. src/components/Mixin2.vue(混入演示 2)

<template>
    <div>
        <h1 @click="show">点我显示name2</h1>
    </div>
</template>

<script>
    import {mixin}  from '../mixin'
    export default {
        data() {
            return {
                name:'name2'
            }
        },
        //引入了mixin中的methos,data,amounted
        mixins:[
            mixin
        ]
       /*  
       methods:{
            show(){
                alert(this.name)
            }
        } 
        */
    }
</script>

<style>

</style>

6. src/App.vue(根组件:整合所有特性)

<template>
    <div>
        <!--
            知识点1:ref引用
               ref引用的对象会出现在vc的$refs属性上,可用于获取dom对象或vc对象。获取方式:this.$refs.xxx
        -->
        <h1 ref="h">呵呵哒</h1>
        <input type="button" @click="show" value="获取dom对象"/>
        <input type="button" @click="showVC" value="获取vc对象"/>

        <hr>
        <!--
            知识点2:props传参
            :age和age写法都行。:age表示引号里当作表达式,因此这里的18传递的是数字类型
        -->
        <Student :age="18" name="张三" ref="student"></Student>
        <Student age="18" name="李四"></Student>

        <hr>
        <!--
            知识点3:mixins混入
        -->
        <Mixin1></Mixin1>
        <Mixin2></Mixin2>

        <hr>
        <!--
            知识点4:plugins插件
        -->
        <input type="button" @click="hello('你好')" value="调用全局方法" />
    </div>
</template>

<script>
    import Student from './components/Student.vue'
    import Mixin1 from './components/Mixin1.vue'
    import Mixin2 from './components/Mixin2.vue'
    export default {
        name:'App',
        data() {
            return {
                
            }
        },
        components:{
            Student,
            Mixin1,
            Mixin2
        },
        methods:{
            show(){
                console.log(this.$refs.h)
            },
            showVC(){
                console.log(this.$refs.student)
                //父子可以交互数据了:this.$refs.student.msg = '呵呵哒'
            }
        }
    }
</script>

<style>

</style>

7. src/main.js(入口文件:初始化 Vue、引入插件)

import Vue from 'vue'
import App from './App.vue'

/* 
    全局混合:
    import {mixin} from './mixin'
    Vue.mixin(mixin) 
*/
import plugins from './plugins'

//Vue.use本质会执行插件的install方法

//Vue.use(plugins) 无参引入插件

Vue.use(plugins,'参数')//有参引入插件

Vue.config.productionTip = false
new Vue({
    render: h => h(App),
}).$mount('#app')

二、核心知识点解析

1. props:父子组件通信

(1)什么是 props?

props是 Vue 中父组件向子组件传递数据的单向数据流机制,子组件通过props接收父组件的数据,且数据会挂载到子组件实例(vc)上,可直接在模板或逻辑中使用。

(2)props 的 3 种写法(按场景选择)
写法语法示例适用场景特点
基础写法props: ['age', 'name']简单场景(无需校验)简洁,无类型 / 必填校验
类型校验props: { name: String, age: Number }需要确保数据类型不符合类型会触发警告
完整配置props: { name: { type: String, required: true } }复杂场景(需校验 + 默认值)支持类型、必填、默认值、自定义验证
(3)关键注意事项:单向数据流
  • 为什么不能直接修改 props?
    Vue 设计props为单向数据流(父→子),目的是保证数据来源唯一,便于调试(避免子组件修改父组件数据导致的混乱)。直接修改props会触发控制台警告。
  • 正确修改方案:
    子组件用自身data接收props(如myAge: this.age),后续修改myAge,不影响父组件的原始数据。

2. ref:获取 DOM 与组件实例

(1)什么是 ref?

ref是 Vue 提供的用于标记 DOM 元素或组件实例的属性,通过this.$refs.xxx可快速获取标记的元素或实例,避免手动操作document.querySelector

(2)ref 的 2 种常用场景
  1. 获取 DOM 元素
    给 DOM 元素加ref="xxx",通过this.$refs.xxx获取原生 DOM 对象,可直接操作 DOM(如修改样式、获取内容)。
    示例:this.$refs.titleDom.style.color = 'red'

  2. 获取组件实例
    给子组件加ref="xxx",通过this.$refs.xxx获取子组件实例(vc),可访问子组件的datamethods,实现父子组件交互。
    示例:this.$refs.studentRef.myAge = 25(修改子组件数据)

(3)注意事项
  • ref获取时机:需在组件mounted钩子后获取(DOM 未挂载时this.$refs.xxxundefined)。
  • 避免过度使用:优先通过数据驱动(如v-ifv-for)操作 DOM,ref仅在必要时使用(如复杂 DOM 操作、组件交互)。

3. mixin:组件代码复用

(1)什么是 mixin?

mixin(混入)是 Vue 中提取多个组件公共代码(数据、方法、钩子函数)的机制,避免重复编写相同逻辑,提高代码复用率。

(2)mixin 的 2 种使用方式
  1. 局部混入:仅当前组件使用,通过mixins: [mixin1, mixin2]引入(支持多个混入)。
    示例:Mixin1.vue 和 Mixin2.vue 引入mixin,复用show方法和x数据。

  2. 全局混入:所有组件都会继承,通过Vue.mixin(mixin)注册(谨慎使用,避免污染全局)。
    示例:main.js 中注释的Vue.mixin(mixin),全局混入后所有组件都有x数据和show方法。

(3)mixin 的优先级规则(关键)
  • 数据(data)和方法(methods):组件自身的优先级高于混入(组件有则用组件的,无则用混入的)。
    例:若组件和混入都有show方法,执行组件的show
  • 钩子函数(如 mounted):混入的钩子先执行,组件的钩子后执行(两者都会执行,不覆盖)。
    例:mixin 的mounted先打印,再打印 Mixin1/Mixin2 的mounted

4. plugin:Vue 全局功能扩展

(1)什么是 plugin?

plugin(插件)是 Vue 中扩展全局功能的机制,本质是包含install方法的对象,可用于注册全局方法、过滤器、指令、混入等,一次注册,全项目可用。

(2)插件的核心流程
  1. 定义插件:必须包含install方法,第一个参数是Vue构造函数,后续参数是Vue.use传递的额外参数。
    示例:plugins.js 中install方法挂载全局方法hello

  2. 使用插件:通过Vue.use(plugin, options)注册,Vue会自动调用插件的install方法。
    示例:main.js 中Vue.use(plugins, '插件初始化参数'),传递参数并初始化插件。

  3. 调用全局功能:插件挂载的全局方法(如this.hello)可在所有组件中通过this调用。
    示例:App.vue 中this.hello('内容')调用全局方法。

(3)插件的常见用途
  • 注册全局方法(如接口请求方法this.$http)。
  • 注册全局过滤器(如日期格式化{{ time | dateFormat }})。
  • 注册全局指令(如自动聚焦v-focus)。
  • 注入全局混入(如全局权限校验)。

三、总结

特性核心作用应用场景注意事项
props父子组件通信(父→子)父组件向子组件传递数据单向数据流,不直接修改 props
ref获取 DOM / 组件实例复杂 DOM 操作、父子组件交互挂载后获取,避免过度使用
mixin组件代码复用多个组件有相同数据 / 方法 / 钩子注意优先级,避免全局混入污染
plugin全局功能扩展全局方法、过滤器、指令必须包含 install 方法
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值