Extend vue.js component from third-party library - javascript

I'm using component ElDatepicker from element-ui and I want to change it's template and event handler method.
I'm trying to do something like this in single file component:
import Vue from 'vue';
import ElDatePicker from 'element-datepicker'
Vue.use(ElDatePicker)
var dpkr = Vue.component('ElDatePicker')
console.log(dpkr)
export default {
extends: ['ElDatePicker']
}
But it doesn't work. How i can change it?
https://github.com/ElemeFE/element/tree/dev/packages/date-picker - component package

Your main problem is that extends should specify a single component and not an array. You should reference the component and not the name.
import Vue from 'vue';
import ElDatePicker from 'element-datepicker'
export default {
extends: ElDatePicker
}
The repo you posted is from element-ui
Do npm install element-ui
Then:
import { DatePicker } from 'element-ui'
export default {
// Use mixins for array syntax
mixins: [DatePicker]
// OR use extends without array
extends: DatePicker
}

You have to first install Element UI in your project using npm install element-ui.
Then you have to edit your main.ts/main.js file and add
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
This should solve your problem. For more help, check Element UI

Related

Vitest with element plus unplugin unknown extension for scss

I'm trying to run tests using Vitest on a Vue.js app that uses Element Plus registered as a plugin.
If I use mount on a component that contains an Element Plus component, I get the following error:
TypeError: Unknown file extension ".scss" for /home/projects/vitejs-vite-zcdxhn/node_modules/element-plus/theme-chalk/src/button.scss
The issue can be replicated on this StackBlitz.
My vite.config.js file looks like this:
import { defineConfig } from 'vite';
import vue from '#vitejs/plugin-vue';
import ElementPlus from 'unplugin-element-plus/vite';
export default defineConfig({
plugins: [vue(), ElementPlus({ useSource: true })],
});
My HelloWorld.vue component looks like this:
<script setup>
import { ElButton } from 'element-plus';
</script>
<template>
<el-button type="primary">Hello</el-button>
</template>
My HelloWorld.spec.js looks like this:
import { test, expect } from 'vitest';
import HelloWorld from '../HelloWorld.vue';
import { mount } from '#vue/test-utils';
test('hello world test', async () => {
const wrapper = mount(HelloWorld);
expect(wrapper.text()).toContain('Hello');
});
The seems to be specifically related to the ElementPlus({ useSource: true })] "unplugin" in plugins in vite.config.js because when I remove that, the problem goes away.
I've reviewed the docs for the various tools (Element Plus, Vite, Vitest), but I've not been able to find how to get this working.
Is there a custom test config that needs to be applied?

How do I fix "the requested module does not provide an export named 'default'"?

I'm developing app using JS and Vue.js and get error on line:
import Vue from 'vue'
I'm getting this:
Uncaught SyntaxError: The requested module
'/node_modules/.vite/vue.js?v=6dba2ea6' does not provide an export
named 'default'
I googled that might be caused by old Vue version, in my package.json vue version is 3.2.6, but
npm view vue version
returns 2.6.14, I tried to upgrade it with Vue CLI
vue upgrade
but npm command still return 2.6.14
I hope you could help me, what did I wrong or it is not even versions problem? Thanks!
The reason it didn't work is that Vue provides a named export, whereas you are trying to import it as though it had a default export.
To make a named import (which you must do with named exports), you need to wrap the name of the export you want to import in curly braces, so {} around Vue like this:
import { Vue } from 'vue';
// ^^^ name of export
It will work
The thing you want to do is import vue but it doesnot have a default export function or either the default thing to export is not set in vue module. So you have to select function named vue by adding curly braces.
If it had a default export function, then your code would have worked and in that case you could write anything in place of vue like below:
import anyname from 'vue'
anyname is name whatever you want.
This worked for me:-
import * as Vue from 'vue';
and similarly for different packages:-
import * as Vuex from 'vuex';
import * as VueRouter from 'vue-router';
As of time of writing:-
"devDependencies": {
...
"vue": "^3.2.45",
Another solution is to use the createApp() function like this:
import { createApp } from 'vue';
createApp(App).mount('#app')
I'm not experienced in Vue JS, but it looks like they no longer export a single object. Ranger a collection of things.
Usually as of Vue 2, in the src/main.js file, we’re bootstrapping the app by calling a new Vue as a constructor for creating an application instance.
import Vue from "vue";
import App from "./App.vue";
import router from './router'
const app = new Vue({
router,
render: h => h(App)
});
For Vue 3 the initialization code syntax has changed and is much cleaner and compact
import { createApp } from "vue";
createApp(App).use(store).mount('#app')

"Property $notify does not exist on type" - Can't use npm package on Vue App

I am using this npm package to send notifications in my Vue App. After following the instructions, and adding the required usages on the main.ts, I keep getting when I try to use the features of it:
Property '$notify' does not exist on type 'Shop'
main.ts:
import Vue from 'vue'
import Notifications from 'vue-notification'
import App from './App.vue'
Vue.use(Notifications)
new Vue({
render: h => h(App)
}).$mount('#app')
<script lang="ts">
import { Component, Vue } from "vue-property-decorator";
import Character from "./Character.vue";
import Vendor from "./Vendor.vue";
#Component<Shop>({
components: {
Character,
Vendor
},
})
export default class Shop extends Vue {
sellItem(itemID) {
this.$notify({
title: 'Important message',
text: 'Hello user!'
});
}
}
</script>
I have tried importing the component in the .vue file, however it does not recognize the type. What am I doing wrong? I can't find any solution for this...
Thank you.
Add a shim typings file
You need a file that imports and re-exports the type of "Vue", it is named vue-file-import.d.ts, but elsewhere on the internet it is commonly called vue-shim.d.ts. Regardless of name, the content needed is the same:
// vue-file-import.d.ts
declare module "*.vue" {
import Vue from "vue";
export default Vue;
}
Try placing the above file in /src location. But sometimes when you move around changing things it might not work so I suggest you to place it inside /typings location

`npm init react-app` leads to `'React' is not defined no-undef` when changing function component to class component

I used npm init react-app appname which creates, among other files, App.js. In that file is a function component:
function App() {
return (
<SomeJSX />
);
}
I edited the function component into a class component, like so:
class App extends React.Component{
render() {
return (
<TheSameJSX />
);
}
}
Now, when I run npm start, I get an error:
Failed to compile
src/App.js
Line 4:19: 'React' is not defined no-undef
Search for the keywords to learn more about each error.
I imagine I need to add some setting somewhere that will automatically include React without me needing to explicitly import it at the top of every file. How do I do this? And why does this npm package not do that by default? I know a bit about javascript (and html and css), and have read a bit about React, but I am completely unaware of how npm or webpack works.
Thanks in advance!
EDIT: To clarify, I know how to import stuff with javascript. I can easily add import React from 'react'; to the file and make it work. However, I find it difficult to believe that adding an import statement to every single javascript file is the recommended method, and I don't understand why this example app wouldn't be set up so as to avoid having to do that. Am I mistaken? Do I really need to manually import the same thing over and over again within the same project? Could I set a global variable to React so that I can use it from wherever?
In your default function component you're not extending any classes and just writing a simple function
function App() {
return (
<SomeJSX />
);
}
In class component, you're in fact extending the Class Component by React.Component provided by React default export object and hence you must import it from the package
//only use one of these
import * as React from "react";
import {Component} from "react"; // you can directly extend without writing `React.` with this import
import React from "react"
So your code would be
import React from "react";
class App extends React.Component{
render() {
return (
<TheSameJSX />
);
}
}
Any of the above imports should be fine with a preference to the first and second one.

Vue + Typescript - Import errors with class based decorators

I'm trying to set up Vue 3 with TypeScript and class-based components. However, I keep getting on error on importing the Component decorator the Vue constructor:
This expression is not callable. Type 'typeof
import("/Users/*folder*/node_modules/vue-class-component/dist/vue-class-component")'
has no call signatures. Vetur(2349)
mycode.vue:
<script lang="ts">
import Vue from 'vue'
import Component from 'vue-class-component'
#Component // 1st Error '#Component'
export default class ProdItem extends Vue { // 2nd error 'Vue'
}
</script>
You might be trying to use the example from the official vue-class-component docs, but that's currently for the 7x version, which can only be used with Vue 2.
Vue 3 requires vue-class-component 8x, which is not yet documented, but you can refer to vue-class-component Issue #406 that describes the changes. The notices relevant to your question:
#Component will be renamed to #Options.
#Options is optional if you don't declare any options with it.
Vue constructor is provided from vue-class-component package.
Since your component has no options, you could just omit the #Options decorator from your component:
// BEFORE:
import Component from 'vue-class-component'
#Component
class {}
// AFTER:
/* no options used, so no #Options decorator needed */
class {}
Also, Vue 3 no longer exports the Vue constructor, but vue-class-component does, so your component would have to extend that instead:
// BEFORE:
import Vue from 'vue'
// AFTER:
import { Vue } from 'vue-class-component'
For reference, you can use Vue CLI to generate a Vue 3 + TypeScript project to play with a working example that uses the latest vue-class-component as described above.
With a decorator, you don't need ({}).
Try
<script lang="ts">
import Vue from 'vue'
import Component from 'vue-class-component'
#Component // 1st Error '#Component'
export default class ProdItem extends Vue { // 2nd error 'Vue'
}
</script>
Based on this issue and this one you could do :
<script lang="ts">
import {vue} from 'vue-class-component'
export default class ProdItem extends Vue {
}
</script>

Categories