Reactive mathematical utility functions and composables for Vue.js applications
—
Reactive logical operations including AND, OR, and NOT with support for multiple arguments and aliased exports. These functions provide reactive Boolean logic that automatically updates when input values change.
Reactive AND operation that returns true only when all input values are truthy.
/**
* Reactive AND operation on multiple values
* @param args - Multiple reactive values to AND together
* @returns ComputedRef<boolean> that updates when any input changes
*/
function logicAnd(...args: MaybeRefOrGetter<any>[]): ComputedRef<boolean>;
// Alias for shorter usage
const and: typeof logicAnd;Usage Examples:
import { ref } from "vue";
import { logicAnd, and } from "@vueuse/math";
// Basic AND operation
const condition1 = ref(true);
const condition2 = ref(false);
const condition3 = ref(true);
const result = logicAnd(condition1, condition2, condition3);
console.log(result.value); // false (one condition is false)
condition2.value = true;
console.log(result.value); // true (all conditions are now true)
// Using the alias
const shortResult = and(condition1, condition2);
console.log(shortResult.value); // true
// Works with any truthy/falsy values
const name = ref("");
const email = ref("user@example.com");
const age = ref(25);
const isValidUser = logicAnd(name, email, age);
console.log(isValidUser.value); // false (empty name is falsy)
name.value = "John";
console.log(isValidUser.value); // true (all values are truthy)
// Mixed with computed values
const hasPermissions = computed(() => user.role === 'admin');
const isAuthenticated = ref(true);
const canAccess = logicAnd(hasPermissions, isAuthenticated);Reactive OR operation that returns true when at least one input value is truthy.
/**
* Reactive OR operation on multiple values
* @param args - Multiple reactive values to OR together
* @returns ComputedRef<boolean> that updates when any input changes
*/
function logicOr(...args: MaybeRefOrGetter<any>[]): ComputedRef<boolean>;
// Alias for shorter usage
const or: typeof logicOr;Usage Examples:
import { ref } from "vue";
import { logicOr, or } from "@vueuse/math";
// Basic OR operation
const hasEmail = ref(false);
const hasPhone = ref(false);
const hasSocial = ref(true);
const hasContact = logicOr(hasEmail, hasPhone, hasSocial);
console.log(hasContact.value); // true (at least one contact method)
hasSocial.value = false;
console.log(hasContact.value); // false (no contact methods)
hasPhone.value = true;
console.log(hasContact.value); // true (phone is available)
// Using the alias
const quickCheck = or(hasEmail, hasPhone);
// Permission checking
const isOwner = ref(false);
const isAdmin = ref(false);
const isModerator = ref(true);
const canEdit = logicOr(isOwner, isAdmin, isModerator);
console.log(canEdit.value); // true (moderator can edit)
// Fallback values
const primaryApi = ref("");
const secondaryApi = ref("");
const localCache = ref("cached-data");
const hasDataSource = logicOr(primaryApi, secondaryApi, localCache);
console.log(hasDataSource.value); // true (local cache available)Reactive NOT operation that inverts the truthiness of a single value.
/**
* Reactive NOT operation on a value
* @param v - Reactive value to invert
* @returns ComputedRef<boolean> containing the inverted boolean value
*/
function logicNot(v: MaybeRefOrGetter<any>): ComputedRef<boolean>;
// Alias for shorter usage
const not: typeof logicNot;Usage Examples:
import { ref } from "vue";
import { logicNot, not } from "@vueuse/math";
// Basic NOT operation
const isLoading = ref(true);
const isReady = logicNot(isLoading);
console.log(isReady.value); // false (not ready while loading)
isLoading.value = false;
console.log(isReady.value); // true (ready when not loading)
// Using the alias
const isNotEmpty = not(ref(""));
console.log(isNotEmpty.value); // false (empty string is falsy)
// Toggle pattern
const isVisible = ref(false);
const isHidden = logicNot(isVisible);
// UI state management
const hasErrors = ref(false);
const isValid = logicNot(hasErrors);
const canSubmit = computed(() => isValid.value && form.isDirty);
// Inverting complex conditions
const isOffline = computed(() => !navigator.onLine);
const isOnline = logicNot(isOffline);import { ref, computed } from "vue";
import { logicAnd, logicOr, logicNot } from "@vueuse/math";
// User authentication and authorization
const isLoggedIn = ref(false);
const hasValidToken = ref(false);
const isEmailVerified = ref(false);
const isBanned = ref(false);
// Complex authentication state
const isAuthenticated = logicAnd(isLoggedIn, hasValidToken);
const isVerified = logicAnd(isAuthenticated, isEmailVerified);
const isNotBanned = logicNot(isBanned);
const canAccess = logicAnd(isVerified, isNotBanned);
console.log(canAccess.value); // false (not logged in)
// Simulate login flow
isLoggedIn.value = true;
hasValidToken.value = true;
isEmailVerified.value = true;
console.log(canAccess.value); // true (all conditions met)
// Ban user
isBanned.value = true;
console.log(canAccess.value); // false (user is banned)import { ref, computed } from "vue";
import { logicAnd, logicOr, logicNot } from "@vueuse/math";
// Form fields
const username = ref("");
const email = ref("");
const password = ref("");
const confirmPassword = ref("");
const agreeToTerms = ref(false);
// Field validations
const isUsernameValid = computed(() => username.value.length >= 3);
const isEmailValid = computed(() => /\S+@\S+\.\S+/.test(email.value));
const isPasswordValid = computed(() => password.value.length >= 8);
const isPasswordMatch = computed(() => password.value === confirmPassword.value);
// Combined validations using logical operations
const areFieldsValid = logicAnd(
isUsernameValid,
isEmailValid,
isPasswordValid,
isPasswordMatch
);
const hasRequiredConsent = logicAnd(agreeToTerms);
const canSubmit = logicAnd(areFieldsValid, hasRequiredConsent);
// Error states
const hasUsernameError = logicAnd(
computed(() => username.value.length > 0), // Only show error if user has typed
logicNot(isUsernameValid)
);
const hasEmailError = logicAnd(
computed(() => email.value.length > 0),
logicNot(isEmailValid)
);
// Watch for changes
watch(canSubmit, (isValid) => {
console.log(`Form ${isValid ? 'can' : 'cannot'} be submitted`);
});
// Test the form
username.value = "john";
email.value = "john@example.com";
password.value = "secretpassword";
confirmPassword.value = "secretpassword";
agreeToTerms.value = true;
console.log(canSubmit.value); // trueimport { ref, computed } from "vue";
import { logicAnd, logicOr, logicNot } from "@vueuse/math";
// Feature flags
const enableBetaFeatures = ref(false);
const enablePremiumFeatures = ref(false);
const isDebugMode = ref(true);
// User properties
const isPremiumUser = ref(false);
const isBetaTester = ref(true);
const isDeveloper = ref(false);
// Feature availability logic
const canUseBetaFeatures = logicAnd(enableBetaFeatures, isBetaTester);
const canUsePremiumFeatures = logicOr(
logicAnd(enablePremiumFeatures, isPremiumUser),
isDeveloper // Developers get access to everything
);
const showDebugInfo = logicOr(isDebugMode, isDeveloper);
const showAdvancedSettings = logicOr(canUsePremiumFeatures, canUseBetaFeatures);
// Environment-based features
const isProduction = computed(() => process.env.NODE_ENV === 'production');
const isDevelopment = logicNot(isProduction);
const enableAnalytics = logicAnd(isProduction, logicNot(isDeveloper));
console.log({
canUseBeta: canUseBetaFeatures.value,
canUsePremium: canUsePremiumFeatures.value,
showDebug: showDebugInfo.value,
showAdvanced: showAdvancedSettings.value,
enableAnalytics: enableAnalytics.value
});
// Simulate feature toggle
enableBetaFeatures.value = true;
console.log(`Beta features now ${canUseBetaFeatures.value ? 'enabled' : 'disabled'}`);import { ref, computed } from "vue";
import { logicAnd, logicOr, logicNot } from "@vueuse/math";
// Application states
const isIdle = ref(true);
const isLoading = ref(false);
const hasData = ref(false);
const hasError = ref(false);
// State transitions
const canStartLoading = logicAnd(isIdle, logicNot(isLoading));
const canShowData = logicAnd(hasData, logicNot(hasError), logicNot(isLoading));
const canRetry = logicOr(hasError, logicAnd(logicNot(hasData), logicNot(isLoading)));
const shouldShowSpinner = logicAnd(isLoading, logicNot(hasError));
// State machine functions
function startLoading() {
if (canStartLoading.value) {
isIdle.value = false;
isLoading.value = true;
hasError.value = false;
}
}
function finishLoading(success: boolean, data?: any) {
isLoading.value = false;
if (success) {
hasData.value = !!data;
hasError.value = false;
isIdle.value = false;
} else {
hasError.value = true;
hasData.value = false;
isIdle.value = true;
}
}
function reset() {
isIdle.value = true;
isLoading.value = false;
hasData.value = false;
hasError.value = false;
}
// Usage
console.log(`Can start loading: ${canStartLoading.value}`); // true
startLoading();
console.log(`Should show spinner: ${shouldShowSpinner.value}`); // true
setTimeout(() => {
finishLoading(true, { users: [] });
console.log(`Can show data: ${canShowData.value}`); // true
}, 1000);Install with Tessl CLI
npx tessl i tessl/npm-vueuse--math