Is it possible to use defineAsyncComponent and dynamic <component> with non-vue native web components?
Let's assume I have a web component, which was created with lit and now I want to use it via defineAsyncComponent inside my Vue project. Something like this:
const MyAsyncComponent = defineAsyncComponent(
async () => (await import('my-native-web-component')).MyNativeWebComponent,
);
<template>
<component :is="MyAsyncComponent" />
</template>
Related
I have a simple landing page using Vue3 Vite (SSG) without Vuex.
I need to pass a screenWidth value being watched in App.vue to a bunch of child components so that they change images depending on the user's screenWidth.
I could use props to pass this value, but it seems a bit cumbersome to write them for 8 child components, and to use composition data export or provide / inject is definitely overkill.
is there not a way to simply access a parent's data via something like instance.parent (didn't work), $parent.message (Vue2 way), etc from a child component?
// Parent:
data() {
return {
screenWidth: 123
}
}
// Child
<div v-if="$parent.screenWidth > 1200">
img...
</div>
EDIT: Solving this with props for now as no other (working) solution seems to be available in Vite for what used to be easy as pie in Vue2.
EDIT 2: It occurs to me now that using VueUse's built in useWindowSize might have been a good solution here.
Use v-model binding.
Parent component (assuming setup script):
<script setup lang='ts'>
import {ref} from 'vue';
const screenWidth = ref(720);
// use screenWidth as a regulat reactive variable here
</script>
<template>
<Child v-model="screenWidth" />
</template>
Child component:
<script setup lang="ts">
import {ref, watchEffect} from 'vue';
const props = defineProps<{
modelValue: number;
}>();
const emit = defineEmits<{
(e: 'update:modelValue', value: number): void
}>();
const value = ref(props.modelValue);
watchEffect(() => value.value = props.modelValue);
function setValue(newValue: number) {
value.value = key;
emit('update:modelValue', value.value);
}
</script>
<template>
// Use `value` and `setValue` here
</template>
In element-plus we already have icons for example <i-mdi-edit />
how can use these icons so i can create my own component
<Icon name="edit" />
and i pass the name property so i can get the icon
my Icon component as follows;
<script setup lang="ts">
import { ref } from "vue";
let props = withDefaults(defineProps<{ name: string }>(), {
name: "edit",
});
let component = ref(`i-mdi-${props.name}`);
</script>
<template>
<component :is="component" />
</template>
You can use dynamic components for that.
For example, in your case, and assuming you have the name prop registered, you can use something like:
<component :is="`i-mdi-${name}`"></component>
Edit: Since you mentioned element plus, here is a working example. However, in this case, it seems a bit redundant to do like you want.
Component 1:-
<template>
<blur :isData="isData">
<!-- logic/implementation of component 1 -->
<div>
</div>
</blur>
<template>
<script>
import blur from "../shared/Blur";
name: "component-1",
components: {
blur,
},
</script>
Just like this component1.vue, I have multiple components which are using blur component. Is it possible that instead of writing and importing blur in every single component, I can make some base class that can transfer the blur functionality in every single component in the folder. Can something like this be achieved in vue ?
With Vue.component you can create globally registered components:
Vue.component('my-component-name', {
// ... options ...
})
Find out more here
Diving into vue 3, trying to add Vue to an existing asp.net core project. Since the frontend is mostly razor pages, the app isn't being mounted with a templated component that has a hierarchy of components.
const vueApp = createApp({});
What I'm trying to do:
vueApp.component('MyComponent', require('./components/MyComponent').default);
vueApp.mount('#app');
I've also tried it this way, as described in the docs:
import { createApp } from 'vue/dist/vue.esm-browser'
import MyComponent from './components/MyComponent.vue'
const vueApp = createApp({
components: {
MyComponent
}
});
vueApp.mount('#app');
I've tried every version of this. requiring MyComponent.vue, with and without the default, importing MyComponent and using it that way (instead of require), none of them work. I just continue getting [Vue warn]: Failed to resolve component 'mycomponent' (Yes I did check the html coming back from the server, It's properly capitalized...not sure why the error is lower case).
MyComponent.vue looks like this:
<template>
<lots of vanilla html>
</template>
<script>
export default {
name: 'MyComponent',
data() {
return { some: "data" }
},
methods: { ... },
mounted() { ...}
}
</script>
//no component styling
Am I missing something here? Or is this no longer possible? I'm using the default vue-cli webpack config, if that matters.
Thanks
So, after rereading the docs (for what feels like the 10th time), I think I figured out the problem. It's actually not a Vue issue at all, it's my use of the Vue component.
In my asp.net core cshtml, I was referencing the component in PascalCase, like this:
<MyComponent />
Turns out this is a no no. By convention (enforced by the browser I guess), custom elements can only be referenced in the DOM using kebab-case, like this:
<my-component />
My vue app is still defining the component in PascalCase.
My main.js file is importing MyComponent, then passing it into the createApp options.components object.
const vueApp = createApp({
components: {
MyComponent
}
});
The more you know, I guess.
I am using a component library within my web app and I'd like to attach functionality to one of the provided components.
So let's say I have a .vue file
<template>
<div>
... some stuff
<LibraryComponent />
</div>
</template>
<script>
import LibraryComponent from 'library'
export default {
components: {
LibraryComponent
}
}
</script>
I would love to be able to reach into the LibraryComponent and attach a method to the mounted hook from the parent. I figure I can update the code of the component itself in node_modules but that seems like a bad solution if the package gets updated.
Vue’s lifecycle hooks emit their own custom events.
Take a look at this article:
Vue.js Component Hooks as Events