【Vue3.x】全局属性/方法的创建及使用

152 阅读1分钟

隨著项目需求的不斷增加,功能错综复杂,有时一些属性值或方法想要在很多个组件中被使用,且想要进行统一管理,就可以将这些属性值或方法注册在全局对象中。

1. 第一種

main.ts中添加全局變量和方法

import { createApp } from 'vue'
import router from './router'
import App from './App.vue'
import ElementPlus from 'element-plus'

import pinia from './store/store'
import './styles/index.scss'

// If you want to use ElMessage, import it.
import 'element-plus/theme-chalk/src/message.scss'
// import '~/styles/element/index.scss'

// import all element css, uncommented next line
import 'element-plus/dist/index.css'

const app = createApp(App)

app.config.globalProperties.$user = { name: '梅长苏', weapons: '长剑', title: '刺客' }

app.config.globalProperties.$addValue = (value: number) => {
    return value + 100
};
app.use(pinia)
app.use(router)
app.use(i18n)
app.use(ElementPlus)
app.mount('#app')

在頁面.vue中使用(template and script)

<template>
   <h2>this is firstValue</h2>
   {{ firstValue }}
   <el-divider />
   <h2>在頁面中直接使用</h2>
   {{$addValue(firstValue)}}
   <p>姓名:{{$user.name}} </p>
   <el-divider />
   <h2>this is button</h2>
   <el-button @click="changeFirst">ChangeFirst</el-button>
   
</template>
<script setup lang="ts">
import { getCurrentInstance, ref } from 'vue';

//在Script中使用全局方法
const instance = getCurrentInstance();
const firstValue = ref(10);
const changeFirst = ()=>{
   firstValue.value  = instance?.appContext.config.globalProperties.$addValue(firstValue.value)
}
</script>

2. 第二種

當屬性和方法相對較多時,考慮到代碼美觀和可維護性,使用插件形式添加

1.創建src/config/global.ts

import { App } from "vue";

export const addGlobalPropertiesPlugin = {
    install(app:App){
        // 注册想在全局使用的方法和变量
        app.config.globalProperties.$addValue = (value: number) => {
            return value + 150
        }
        app.config.globalProperties.$globalValue = "我是全局變量111";
    }
}

2.在main.ts中導入

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import { addGlobalPropertiesPlugin } from './config/global'

const app = createApp(App)
app.use(pinia)
app.use(addGlobalPropertiesPlugin)
app.use(router)
app.use(i18n)
app.use(ElementPlus)
app.mount('#app')

3.因為是ts文件,要設定類型

創建xx.d.ts文件,注意要被tsconfig.json中include包含,就可以被讀取到,我是和環境變量放到同級目錄了。

import { ComponentCustomProperties } from "vue";

declare module 'vue'{
    interface ComponentCustomProperties{
        $addValue(value: number): number;
        $globalValue:string;
    }
}

4.在script中使用

<script setup lang="ts">
    // getCurrentInstance获取当前组件实例的上下文信息
    import { getCurrentInstance,onMounted } from "vue"
    // 表示当前组件实例的类型
    import type { ComponentInternalInstance } from "vue"
    
    const { proxy } = getCurrentInstance() as ComponentInternalInstance;
 
    onMounted(()=>{
        console.log(proxy?.$addValue(2))     // 152
        console.log(proxy?.$globalValue)     // 我是全局变量
    })
<script>

3. 動態圖標

3.1 靜態圖標

 <el-icon>
     <User />
 </el-icon>

如果無法顯示,就更新最新版,或者局部註冊

<template>
<el-icon><sysIcon.CaretBottom /></el-icon>
<el-icon><sysIcon.CaretTop /></el-icon>
</template>

<script setup lang="ts">
import { CaretBottom,CaretTop } from "@element-plus/icons";

const sysIcon = markRaw({
    CaretBottom,
    CaretTop
})
</script>

3.2 動態圖標

註冊icon

import { markRaw } from 'vue'

import {
    HomeFilled,
    Checked,
    Histogram,
    Setting,
    EditPen,
    Message
  } from '@element-plus/icons-vue'

  const sysIcon = markRaw({
    HomeFilled,
    Checked,
    Histogram,
    Setting,
    EditPen,
    Message
  })
  export default sysIcon

全局導入main.ts

app.config.globalProperties.$icon = sysIcon;

頁面使用

<el-icon><component :is="$icon['Message']" /></el-icon>

接收子組件的傳參,再展示

    <template #default="scope">
      <el-icon>
        <component :is="scope.row.icon" />
      </el-icon>
    </template>