FAQ
Question List
Q1: How to use $global in non-component files?
javascript
// utils/helper.js
let globalService = null;
export const setGlobalService = (service) => {
globalService = service;
};
export const useGlobal = () => {
if (!globalService) {
throw new Error('Global service not initialized');
}
return globalService;
};
// main.js or App.vue
import { setGlobalService } from './utils/helper';
const $global = inject('$global');
setGlobalService($global);Q2: When is it necessary to pass true for computed properties?
When you need to use theme colors reactively in computed or watch, you should pass true:
javascript
// ✅ Reactive
const color = $tc('primary.main', true);
watch(color, (newColor) => {
// Triggers when the theme switches
});
// ❌ Non-reactive
const color = $tc('primary.main');
// Will not update when the theme switchesQ3: How to clear all attention components?
Availability:
Scifi
Base
Admin
Prime
javascript
const {
$tMessageCloseAll,
$tNotifyCloseAll,
$tToastClose,
$tFlashClose
} = inject('$global');
const clearAllAttentions = () => {
$tMessageCloseAll();
$tNotifyCloseAll();
$tToastClose();
$tFlashClose();
};Q4: What are the differences between adaptive modes?
fixed: Fixed layout, does not respond to window changes.flexible: Elastic layout, scales proportionally.stretch: Stretch layout, fills available space.extension: Extension layout, intelligently adapts to multiple scenarios.disabled: Disables adaptation.
Q5: How to judge device type?
vue
<script setup>
import { inject, computed } from 'vue';
const { $deviceInfo } = inject('$global');
const isMobile = computed(() =>
$deviceInfo.value.type === 'mobile' ||
$deviceInfo.value.touchable
);
const isTablet = computed(() =>
$deviceInfo.value.type === 'tablet'
);
</script>
<template>
<div v-if="isMobile">Mobile Interface</div>
<div v-else-if="isTablet">Tablet Interface</div>
<div v-else>Desktop Interface</div>
</template>Q6: How does Admin's keepAlive work?
Availability:
Scifi
Base
Admin
Prime
vue
<script setup>
import { inject } from 'vue';
import { useRoute } from 'vue-router';
const route = useRoute();
const { tabAdd, keepAliveAdd, $AKeepAlive } = inject('$global');
// Open new tab and enable cache
const openCachedPage = (routeConfig) => {
// Add tab
tabAdd({
meta: {
label: 'UserList',
keepAlive: true
},
path: '/user/list'
});
// Add to cache list
keepAliveAdd({ label: 'UserList' });
};
</script>
<template>
<router-view v-slot="{ Component }">
<keep-alive :include="$AKeepAlive">
<component :is="Component" />
</keep-alive>
</router-view>
</template>Notes
- Reactive Usage: State values automatically unwrap
.valuein templates, but must be accessed manually in<script>. - Computed Properties: Remember to pass the
trueparameter when using methods like$tcto retrieve computed properties. - Attention Sorting: Use
$tAttentionDispatcherto uniformly manage the display order of multiple reminder components. - Theme Switching: Ensure the theme is registered in the system before switching.
- Admin Features: Related functions can only be used when
isActAdminFeaturesistrue. - Encrypted Storage: It is recommended to use
tStoreCryptofor storing sensitive data. - Reload Selection: Use
softReload()when state needs to be preserved, andhardReload()when a complete refresh is required. - Route Query: Using
updateRouteQuerywill not trigger a page refresh, making it suitable for dynamically updating URL parameters. - Floater Mounting: It is recommended to use
$optFloaterToinstead of directly using$gFloaterTo, as the former intelligently selects based on the adaptive state. - I18n Initialization: Call
initI18n()at application startup to ensure language data is loaded.
Best Practices
Performance Optimization
vue
<script setup>
import { inject, computed } from 'vue';
const { $gTheme, $tc } = inject('$global');
// ✅ Good Practice: Use computed property
const primaryColor = $tc('primary.main', true);
// ❌ Avoid: Repeated calls in template
// <div :style="{ color: $tc('primary.main') }"></div>
</script>Conditional Rendering
vue
<script setup>
import { inject } from 'vue';
const {
isActAdminFeatures,
isActEchartsFeatures,
$ADMIN
} = inject('$global');
</script>
<template>
<AdminPanel v-if="isActAdminFeatures" />
<ChartComponent v-if="isActEchartsFeatures" />
</template>Error Handling
vue
<script setup>
import { inject } from 'vue';
const { $tLoading, $tLoadingClose, $tMessage } = inject('$global');
const handleAction = async () => {
$tLoading({
appendTo:"#app",
visible: true,
desc:'Processing...',
spinner: 'ringA'
});
try {
await performAction();
$tMessage({ type: 'success', content: 'Operation successful' });
} catch (error) {
$tMessage({
type: 'error',
content: error.message || 'Operation failed'
});
} finally {
$tLoadingClose();
}
};
</script>Theme Adaptation
vue
<script setup>
import { inject, computed } from 'vue';
const { $gThemeScheme, $tc } = inject('$global');
// In extremely rare cases, dynamically adjust styles based on the theme's light/dark scheme.
// Usually, this is not needed.
const echartsStyle = computed(() => ({
backgroundColor: $gThemeScheme.value === 'dark'
? $tc('common.bg')
: $tc('primary.base'),
color: $gThemeScheme.value === 'dark'
? '#fff'
: '#333'
}));
</script>Reactive Listening
vue
<script setup>
import { inject, watch } from 'vue';
const { $gResizeCounter, $gTheme } = inject('$global');
// Listen for window size changes
watch($gResizeCounter, (newVal) => {
console.log('Window resized', newVal);
// Execute responsive layout adjustment
});
// Listen for theme changes
watch($gTheme, (newTheme) => {
console.log('Theme switched to', newTheme);
// Execute theme-related processing
});
</script>Component Communication
Using provide/inject for component communication is more recommended. The data bus method of communication is used in TechUI's Tui3DPanel for communication between all peer Panel components of the same type.
vue
<script setup>
import { inject, onMounted, onUnmounted } from 'vue';
const { $tBus } = inject('$global');
onMounted(() => {
// Listen for global events
$tBus.on('dataUpdate', handleDataUpdate);
});
onUnmounted(() => {
// Clean up listeners
$tBus.off('dataUpdate', handleDataUpdate);
});
const handleDataUpdate = (data) => {
console.log('Received data update', data);
};
const notifyOthers = () => {
// Emit global event
$tBus.emit('dataUpdate', { id: 1, name: 'test' });
};
</script>Secure Storage
vue
<script setup>
import { inject } from 'vue';
const { tStoreCrypto, openEnc, openDec } = inject('$global');
// Store sensitive data
const saveUserCredentials = (credentials) => {
// Method 1: Use tStoreCrypto
tStoreCrypto.s('local','userCred', credentials);
// Method 2: Use openEnc/openDec
const encrypted = openEnc(credentials);
localStorage.setItem('userCred', encrypted);
};
// Read sensitive data
const loadUserCredentials = () => {
// Method 1
return tStoreCrypto.g('local','userCred');
// Method 2
const encrypted = localStorage.getItem('userCred');
return openDec(encrypted);
};
</script>