I'm new to vuejs and have implemented this example:
Auth0 vuejs and api example
It works just fine, but I run into some issues when trying to merge the vuejs code to my own project.
When loading the page requiring authentication, I get this error:
index.vue?4db4:11 Uncaught (in promise) TypeError: Cannot destructure property 'getAccessTokenSilently' of 'Object(...)(...)' as it is undefined.
The code for my page, looks like this:
<script>
import Layout from "../../../layouts/main.vue";
import { getProtectedResource } from "#/services/message.service";
import { ref } from "vue";
import { useAuth0 } from "#auth0/auth0-vue";
const message = ref("");
const getMessage = async () => {
const { getAccessTokenSilently } = useAuth0();
const accessToken = await getAccessTokenSilently();
const { data, error } = await getProtectedResource(accessToken);
if (data) {
message.value = JSON.stringify(data, null, 2);
}
if (error) {
message.value = JSON.stringify(error, null, 2);
}
};
getMessage();
export default {
components: {
Layout
},
data() {
return {
};
},
methods: {
rightcolumn() {
if (document.querySelector('.layout-rightside-col').classList.contains('d-none'))
{
document.querySelector('.layout-rightside-col').classList.remove('d-none')
} else {
document.querySelector('.layout-rightside-col').classList.add('d-none')
}
}
}
};
</script>
<template>
<Layout>
<p id="page-description">
<span
>This page retrieves a <strong>protected message</strong> from an
external API.</span
>
<span
><strong
>Only authenticated users can access this page.</strong
></span
>
</p>
<CodeSnippet title="Protected Message" :code="message" />
</Layout>
</template>
I've tried the example from the documentation provided here enter link description here
<script>
import Layout from "../../../layouts/main.vue";
//import { getProtectedResource } from "#/services/message.service";
//import { ref } from "vue";
import { useAuth0 } from "#auth0/auth0-vue";
export default {
setup() {
const { loginWithRedirect } = useAuth0();
return {
login: () => {
loginWithRedirect();
}
};
},
components: {
Layout
},
data() {
return {
};
},
methods: {
rightcolumn() {
if (document.querySelector('.layout-rightside-col').classList.contains('d-none')) {
document.querySelector('.layout-rightside-col').classList.remove('d-none')
} else {
document.querySelector('.layout-rightside-col').classList.add('d-none')
}
}
}
}
</script>
But still receives this error:
index.vue?4db4:11 Uncaught (in promise) TypeError: Cannot destructure
property 'loginWithRedirect' of 'Object(...)(...)' as it is undefined.
at setup (index.vue?4db4:11:1)
I'm registrering the plugin this way in main:
createApp(App)
.use(store)
.use(router)
.use(VueApexCharts)
.use(BootstrapVue3)
.component(VueFeather.type, VueFeather)
.use(Maska)
.use(Particles)
.use(i18n)
.use(
createAuth0({
domain: 'xyz.auth0.com',
client_id: 'secret',
redirect_uri: 'http://localhost:4040/callback',
audience: 'https://audience',
})
)
.use(vClickOutside).mount('#app');
My package.json file:
{
"name": "vuejs",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"#auth0/auth0-vue": "^1.0.2",
"#ckeditor/ckeditor5-build-classic": "^32.0.0",
"#ckeditor/ckeditor5-vue": "^2.0.1",
"#fullcalendar/bootstrap": "^5.10.1",
"#fullcalendar/core": "^5.10.1",
"#fullcalendar/daygrid": "^5.10.1",
"#fullcalendar/interaction": "^5.10.1",
"#fullcalendar/list": "^5.10.1",
"#fullcalendar/timegrid": "^5.10.1",
"#fullcalendar/vue3": "^5.10.1",
"#j-t-mcc/vue3-chartjs": "^1.2.0",
"#popperjs/core": "^2.11.2",
"#simonwep/pickr": "^1.8.2",
"#vue-leaflet/vue-leaflet": "^0.6.1",
"#vueform/multiselect": "^2.3.1",
"#vueform/slider": "^2.0.8",
"#vueform/toggle": "^2.0.1",
"#vuelidate/core": "^2.0.0-alpha.34",
"#vuelidate/validators": "^2.0.0-alpha.26",
"#zhuowenli/vue-feather-icons": "^5.0.2",
"aos": "^2.3.4",
"apexcharts": "^3.33.0",
"axios": "^0.27.2",
"bootstrap": "^5.2.1",
"bootstrap-vue-3": "^0.3.3",
"chart.js": "^3.7.0",
"click-outside-vue3": "^4.0.1",
"core-js": "^3.6.5",
"echarts": "^5.3.0",
"feather-icons": "^4.28.0",
"firebase": "^9.6.6",
"highlight.js": "^11.4.0",
"leaflet": "^1.7.1",
"lottie-web": "^5.8.1",
"maska": "^1.5.0",
"moment": "^2.29.1",
"node-sass": "6.0.1",
"particles.vue3": "^1.40.2",
"prismjs": "^1.26.0",
"sass-loader": "^10.2.1",
"simplebar": "^5.3.6",
"simplebar-vue3": "^0.1.5",
"sweetalert2": "^11.4.32",
"swiper": "^6.8.4",
"vue": "3.2.36",
"vue-router": "^4.0.15",
"vue-draggable-next": "^2.1.1",
"vue-easy-lightbox": "^1.3.0",
"vue-feather": "^2.0.0",
"vue-flatpickr-component": "^9.0.5",
"vue-i18n": "^9.2.0-beta.15",
"vue-prismjs": "^1.2.0",
"vue3-apexcharts": "^1.4.1",
"vue3-count-to": "^1.1.2",
"vue3-echarts": "^1.0.4",
"vue3-google-map": "^0.8.3",
"vue3-quill": "^0.2.6",
"vuevectormap": "^1.0.8",
"vuex": "^4.0.2",
"yarn": "^1.22.17"
},
"devDependencies": {
"#vue/cli-plugin-babel": "~4.5.0",
"#vue/cli-plugin-eslint": "~4.5.0",
"#vue/cli-service": "~4.5.0",
"#vue/compiler-sfc": "^3.0.0",
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",
"eslint-plugin-vue": "^7.0.0"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/vue3-essential",
"eslint:recommended"
],
"parserOptions": {
"parser": "babel-eslint"
},
"rules": {}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
]
}
Using #auth0/auth0-vue has a limitation. useAuth0 must be used in the setup hook. Read the documentation for info.
To add login to your application, use the loginWithRedirect function that is exposed on the return value of useAuth0, which you can access in your component's setup function.
<script>
import { ref } from "vue";
import { useAuth0 } from "#auth0/auth0-vue";
export default {
setup() {
const message = ref("");
const { getAccessTokenSilently } = useAuth0();
const getMessage = async () => {
const accessToken = await getAccessTokenSilently();
const { data, error } = await getProtectedResource(accessToken);
if (data) {
message.value = JSON.stringify(data, null, 2);
}
if (error) {
message.value = JSON.stringify(error, null, 2);
}
};
getMessage();
return {
message
}
},
...
}
</script>
<template>...</template>
Related
I've tried setting up a very simple nuxt content example, but even for that I'm running into an Maximum call stack size exceeded error when opening localhost:port/
pages/_slag.vue:
<template>
<nuxt-content :document="doc" />
</template>
<script>
export default {
async asyncData({ $content, params }) {
const doc = await $content(params.slug || 'index');
return { doc }
}
};
</script>
content/index.md:
# Hello #nuxtjs/content!
Super fast HMR!
nuxt-config.js:
export default {
vue: {
config: {
// https://vue-loader.vuejs.org/options.html#cachedirectory-cacheidentifier
},
},
target: 'static',
buildModules: [
],
modules: [
'#nuxt/content'
],
content: {
},
build: {
},
generate: {
concurrency: 2000,
}
}
package.json:
"dependencies": {
"#nuxtjs/axios": "^5.13.6",
"#nuxtjs/tailwindcss": "^4.2.1",
"#nuxt/content": "1.14.0",
"core-js": "^3.18.0",
"nuxt": "^2.15.8",
"vue-inline-svg": "^2.0.0"
},
"devDependencies": {
"#vue/test-utils": "^1.2.1",
"babel-core": "7.0.0-bridge.0",
"babel-jest": "^27.0.5",
"jest": "^27.0.5",
"postcss": "^8.3.5",
"vue-jest": "^3.0.4"
},
"optionalDependencies": {
"fsevents": "^2.3.2"
}
What am I doing wrong?
You are not fetching the data you query for. Update your $content to be as follows: $content(params.slug || 'index').fetch()
I'm experimenting with the Composition API with Vue3. But there were some points I couldn't find. The same code did not work in two different projects.
What I want to do in my own project is to take the data through the API and use it according to what is required. In short, do the necessary get/post operations. I got this API from Vue's own example.
This is the first project code, package.json and error message
<template>
<div class="home">
<div v-for="datas in data" :key="datas.description">
{{ datas.description }}
</div>
</div>
</template>
<script lang="ts">
import { Options, Vue } from "vue-class-component";
import axios from "axios";
import { ref } from "vue";
#Options({
props: {
msg: String,
},
})
export default class HelloWorld extends Vue {
setup() {
let data = ref([]);
axios
.get("https://api.coindesk.com/v1/bpi/currentprice.json")
.then((res) => {
data.value = res.data.bpi;
});
}
}
</script>
{
"name": "api-project",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"axios": "^0.21.1",
"core-js": "^3.6.5",
"vue": "^3.0.0",
"vue-class-component": "^8.0.0-0",
"vue-router": "^4.0.0-0"
},
"devDependencies": {
"#vue/cli-plugin-babel": "~4.5.0",
"#vue/cli-plugin-router": "~4.5.0",
"#vue/cli-plugin-typescript": "~4.5.0",
"#vue/cli-service": "~4.5.0",
"#vue/compiler-sfc": "^3.0.0",
"node-sass": "^4.12.0",
"sass-loader": "^8.0.2",
"typescript": "~4.1.5"
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
]
}
Vue warn
This is the second project code, package.json, and data
<template>
<div v-for="datas in data" :key="datas.description">
{{ datas.description }}
</div>
</template>
<script lang="ts">
import axios from "axios";
import { ref } from "vue";
export default {
name: "HelloWorld",
setup() {
let data = ref([]);
axios.get("https://api.coindesk.com/v1/bpi/currentprice.json").then((res) => {
data.value = res.data.bpi;
});
return {
data,
};
},
}
</script>
{
"name": "test-api",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"axios": "^0.21.1",
"core-js": "^3.6.5",
"vue": "^3.0.0"
},
"devDependencies": {
"#vue/cli-plugin-babel": "~4.5.0",
"#vue/cli-plugin-eslint": "~4.5.0",
"#vue/cli-service": "~4.5.0",
"#vue/compiler-sfc": "^3.0.0",
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",
"eslint-plugin-vue": "^7.0.0",
"node-sass": "^4.12.0",
"sass-loader": "^8.0.2",
"typescript": "~4.1.5"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/vue3-essential",
"eslint:recommended"
],
"parserOptions": {
"parser": "babel-eslint"
},
"rules": {}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
]
}
my data
Could there be an error in my Composition API usage? I've heard that in some videos, "then" is not used for the Composition API. But that's the only way I was able to pull the data from the API.
If my solution is wrong, what method should it be, I'm new at Vuejs can you help?
You need to return the variables from the setup function so that they can be accessed from within the template.
If setup returns an object, the properties on the object can be
accessed in the component's template, as well as the properties of the
props passed into setup:
setup() {
let data = ref([]);
axios
.get("https://api.coindesk.com/v1/bpi/currentprice.json")
.then((res) => {
data.value = res.data.bpi;
});
// return the data as an object
return {
data
}
}
Read more about this in the official vue doc
You can create api dir inside src folder and then inside api dir create a file api.ts and put this code
export async function callApi(endpoint :string, method :string){
return await fetch(endpoint,{
method:method,
headers: {
'Content-type': 'application/json; charset=UTF-8',
},
}).then(async response => {
const resData = await response.json()
if (!response.ok) {
// do something to determine request is not okay
resData.isSuccess = false
}
return resData
}).catch(error => {
console.log("callApi in api.ts err")
console.log(error)
throw error
})
}
Go to you component and use this code
<template>
<div v-for="(item,i) in data.records" v-bind:key="i">
{{ item.chartName}}
</div>
</template>
<script>
import {onMounted,reactive} from "vue"
import {callApi} from "#/api/api"
export default{
name:'MyComponent',
setup() {
const data = reactive({
records: [],
})
onMounted( async() =>{
getRecords()
})
const getRecords = async() => {
let resData = await callApi('https://api.coindesk.com/v1/bpi/currentprice.json', 'GET')
data.records = resData
}
return {
data,
}
}
}
</script>
enter code here
I can't seem to get the following example to work with vue3 and testing library.
https://github.com/testing-library/vue-testing-library/blob/main/src/tests/translations-vue-i18n.js
I've even tried to modify the example like so to get $t to be recognized by injecting messages into a mock but no luck.
Does anyone have an example that works with vue 3?
Here are the details ...
Translations.spec.js
import '#testing-library/jest-dom'
import {render, fireEvent} from '#testing-library/vue'
import Vuei18n from 'vue-i18n'
import Translations from '#/components/Translations'
const messages = {
en: {
Hello: 'Hello!',
message: {
hello: 'Hello!'
}
},
ja: {
Hello: 'こんにちは',
message: {
hello: 'こんにちは'
}
},
}
test('renders translations', async () => {
const {queryByText, getByText} = render(Translations, {
global: {
mocks: {
$t: (messages) => messages
}
}
}, vue => {
// Let's register and configure Vuei18n normally
vue.use(Vuei18n)
const i18n = new Vuei18n({
locale: 'ja',
fallbackLocale: 'ja',
messages,
})
// Notice how we return an object from the callback function. It will be
// merged as an additional option on the created Vue instance.
return {
i18n,
}
})
//expect(getByText('Hello!')).toBeInTheDocument()
//await fireEvent.click(getByText('Japanese'))
expect(getByText('こんにちは')).toBeInTheDocument()
//expect(queryByText('Hello!')).not.toBeInTheDocument()
})
Translations.vue
<template>
<div>
<h2>{{ $t("Hello") }}</h2>
<h2>{{ $t("message.hello") }}</h2>
<button #click="switchLocale('en')">English</button>
<button #click="switchLocale('ja')">Japanese</button>
</div>
</template>
<script>
export default {
name: 'Translations',
methods: {
switchLocale(locale) {
this.$i18n.locale = locale
},
},
}
</script>
package.json
{
"name": "mc",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"test:unit": "vue-cli-service test:unit"
},
"dependencies": {
"#fortawesome/fontawesome-svg-core": "^1.2.35",
"#fortawesome/free-solid-svg-icons": "^5.15.3",
"#fortawesome/vue-fontawesome": "^3.0.0-4",
"#popperjs/core": "^2.9.2",
"bootstrap": "^5.0.2",
"core-js": "^3.6.5",
"es6-promise": "^4.2.8",
"vue": "^3.1.4",
"vue-hotjar": "^1.4.0",
"vue-i18n": "^9.1.6",
"vue-loader": "^16.2.0",
"vue-router": "^4.0.10",
"vuex": "^4.0.2"
},
"devDependencies": {
"#babel/core": "^7.14.8",
"#babel/preset-env": "^7.14.8",
"#testing-library/jest-dom": "^5.14.1",
"#testing-library/vue": "^6.4.2",
"#vue/cli-plugin-babel": "^4.5.13",
"#vue/cli-plugin-eslint": "^4.5.13",
"#vue/cli-plugin-router": "^4.5.13",
"#vue/cli-plugin-unit-jest": "^4.5.13",
"#vue/cli-plugin-vuex": "^4.5.13",
"#vue/cli-service": "^4.5.13",
"#vue/compiler-sfc": "^3.1.4",
"#vue/eslint-config-prettier": "^6.0.0",
"#vue/test-utils": "^2.0.0-rc.9",
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",
"eslint-plugin-prettier": "^3.4.0",
"eslint-plugin-vue": "^7.0.0",
"flush-promises": "^1.0.2",
"prettier": "^2.3.2",
"typescript": "^4.3.5",
"vue-jest": "^5.0.0-alpha.10"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/vue3-essential",
"eslint:recommended"
],
"parserOptions": {
"parser": "babel-eslint"
},
"rules": {}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
]
}
Error
FAIL tests/unit/Translations.spec.js
● renders translations
TestingLibraryElementError: Unable to find an element with the text: こんにちは. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.
<body>
<div>
<div>
<h2>
Hello
</h2>
<h2>
message.hello
</h2>
<button>
English
</button>
<button>
Japanese
</button>
</div>
</div>
</body>
47 | //await fireEvent.click(getByText('Japanese'))
48 |
> 49 | expect(getByText('こんにちは')).toBeInTheDocument()
| ^
50 |
51 | //expect(queryByText('Hello!')).not.toBeInTheDocument()
52 | })
I had the same problem and solved it like this:
I am using the next version of #vue/test-utils and vue-jest ("#vue/test-utils": "^2.0.0-rc.16" + "vue-jest": "^5.0.0-alpha.10").
I created a file called jest.init.js (u can call it anything u like)
import { config } from '#vue/test-utils';
import translations from '#/locales/en';
config.global.mocks = {
$t: (msg) => translations[msg],
};
and then initiate it as setup file in jest.config.js
module.exports = {
...
setupFiles: [
'./tests/unit/jest.init.js',
],
...
};
This answer is for everyone stumbling across that question when using Composition API where there's no global $t to mock.
I've solved it by exporting a function createConfiguredI18n in src/plugins/i18n.ts:
import { createI18n, I18nOptions } from 'vue-i18n'
import deDE from '#/locales/de-DE.json'
import enUS from '#/locales/en-US.json'
// Type-define 'de-DE' as the master schema for the resource
type MessageSchema = typeof deDE
export function createConfiguredI18n(locale: string, fallbackLocale: string) {
return createI18n<I18nOptions, [MessageSchema], 'de-DE' | 'en-US'>({
locale: locale || 'en-US',
fallbackLocale: fallbackLocale || 'en-US',
messages: {
'de-DE': deDE,
'en-US': enUS,
},
})
}
export const i18n = createConfiguredI18n('de-DE', 'en-US')
Then in the unit test you can do the following to initialize vue-i18n with your translations:
import {flushPromises, mount, VueWrapper} from '#vue/test-utils'
import {nextTick} from 'vue'
import {createConfiguredI18n} from '#/plugins/i18n'
...
describe('SubjectUnderTest', () => {
it('should display translation "FooBar"', async () => {
const locale = 'de-DE'
const fallbackLocale = 'en-US'
const wrapper = await createWrapper({locale, fallbackLocale})
...
}
async function createWrapper(options: {
locale: string
fallbackLocale: string
}): Promise<VueWrapper> {
const i18n = createConfiguredI18n(options.locale, options.fallbackLocale)
const wrapper = mount(sut, {
global: {
plugins: [i18n],
},
})
await nextTick()
await flushPromises()
return wrapper
}
}
If you don't want the translations but instead mock them and check for the keys only, you can do the following in your unit test instead:
import {flushPromises, mount, VueWrapper} from '#vue/test-utils'
import {nextTick} from 'vue'
import {i18n} from '#/plugins/i18n'
...
i18n.global.t = (key) => key
describe('SubjectUnderTest', () => {
it('should display translation for key "foo.bar"', async () => {
const wrapper = await createWrapper()
...
}
async function createWrapper(): Promise<VueWrapper> {
const wrapper = mount(sut, {
global: {
plugins: [i18n],
},
})
await nextTick()
await flushPromises()
return wrapper
}
}
Using Jest + babel.
Babel Config
module.exports = {
presets: [["#babel/preset-env", { targets: { node: "current" } }], "#babel/preset-typescript"],
plugins: [
"#babel/plugin-proposal-export-default-from",
["#babel/plugin-proposal-decorators", { decoratorsBeforeExport: true }],
["#babel/plugin-proposal-class-properties", { loose: true }]
]
};
Docs state that decorator plugin should be befor the class properties, which I'm doing.
But I'm still getting this error
"Unexpected Token"
public showReorderTooltip = false;
^
Jest Config
module.exports = {
transform: {
"^.+\\.[t|j]s?$": "babel-jest",
".*\\.(vue)$": "vue-jest"
},
// transformIgnorePattclaerns: [],
moduleNameMapper: {
"^#/(.*)$": "<rootDir>/src/$1",
"^common/(.*)$": "<rootDir>/src/common/$1",
"^price/(.*)$": "<rootDir>/src/price/$1",
"^eligibility/(.*)$": "<rootDir>/src/eligibility/$1"
}
};
I added the class properties plugin due to an error I was having where it wouldn't transpile the public static variables on a class. Now it does that. But then it didn't like the decorator I had at the top. Ok, seems to be a plugin. That works, but now it doesn't like class properties again? Or is there yet another plugin to handle "normal" class properties?
The entire project setup is
vue-property-decorator //where the decorators are coming from
typescript
vue
vuetify
some other minor libraries
vue-cli //not using webpack directly though I imagine the vue-cli is using it
package.json
"#babel/core": "^7.8.7",
"#babel/plugin-proposal-class-properties": "^7.8.3",
"#babel/plugin-proposal-decorators": "^7.8.3",
"#babel/plugin-proposal-export-default-from": "^7.8.3",
"#babel/preset-typescript": "^7.8.3",
"#types/jest": "^25.1.4",
"#types/lodash": "4.14.136",
"#types/qs": "6.5.3",
"#vue/cli-plugin-router": "^4.1.0",
"#vue/cli-plugin-typescript": "^4.1.2",
"#vue/cli-plugin-vuex": "^4.1.0",
"#vue/cli-service": "^4.1.2",
"#vue/test-utils": "^1.0.0-beta.32",
"babel-core": "^7.0.0-bridge.0",
"babel-jest": "^25.1.0",
"babel-preset-env": "^1.7.0",
"cross-env": "^6.0.3",
"css-loader": "2.1.1",
"file-loader": "3.0.1",
"font-awesome": "^4.7.0",
"jest": "^25.1.0",
"jest-serializer-vue": "^2.0.2",
"jquery": "3.4.1",
"jwt-decode": "2.2.0",
"moment": "2.24.0",
"node-sass": "^4.13.1",
"sass": "^1.23.7",
"sass-loader": "^8.0.0",
"ts-jest": "^25.2.1",
"tslint": "5.16.0",
"typescript": "3.4.5",
"vee-validate": "2.2.7",
"vue": "2.6.10",
"vue-class-component": "7.2.2",
"vue-cli-plugin-vuetify": "^2.0.3",
"vue-jest": "^3.0.5",
"vue-property-decorator": "^8.4.0",
"vue-router": "3.0.6",
"vue-template-compiler": "2.6.10",
"vuejs-datepicker": "1.5.4",
"vuetify": "^2.2.8",
"vuex": "3.1.1",
"vuex-persist": "^2.2.0",
"vuex-typescript": "3.0.2"
Since other files are working, I'm posting a working file and the file causing issues to see if there's some obvious setup issue.
Working Test
import Vue from "vue";
import { Component, Prop, Inject, Watch } from "vue-property-decorator";
import moment from "moment";
import * as _ from "lodash";
export const DATE_FORMAT = "MM-DD-YYYY";
export const DATE_FORMAT_YYYY_MM_DD = "YYYY-MM-DD";
#Component({
})
export default class PEMDatePicker extends Vue {
#Prop()
label: string;
#Prop()
value: string;
#Prop()
rules: Array<Function>; //https://vuetifyjs.com/en/components/forms#creating-rules
public componentsLabel = "";
public componentsDate = "";
public showPicker = false;
public componentsDateInput: string = moment().format("MM/DD/YYYY");
public mounted() {
this.componentsLabel = this.label ? this.label : "Date";
this.setDate(this.value);
this.$emit('input', this.value);
}
#Watch("value")
public syncModel() {
if (this.componentsDate != this.value) {
this.setDate(this.value);
}
this.componentsDateInput = this.getDate;
}
#Watch("componentsDate")
public syncDates() {
this.componentsDateInput = this.getDate;
this.$emit('input', this.componentsDate);
}
get getDate() {
return this.componentsDate ? moment(this.componentsDate, DATE_FORMAT_YYYY_MM_DD).format("MM/DD/YYYY") : "";
}
public closePicker() {
this.showPicker = false;
//#ts-ignore
this.$refs.input.focus();
}
public handleEnterKey(event) {
this.setDate(event.target.value);
this.showPicker = false;
}
setDate(dateIn) {
this.componentsDate = dateIn && moment(dateIn).isValid() ? moment(dateIn).format(DATE_FORMAT_YYYY_MM_DD) : null;
}
}
Not Working Test
import Vue from 'vue';
import { Prop, Component, Watch, Inject } from 'vue-property-decorator'
import moment from 'moment';
import ItemService from 'common/items/ItemService';
#Component({
components: {
VendorLink: require("price/components/vendor/vendorLink/VendorLink.vue").default,
}
})
export default class CatalogNumberHistory extends Vue {
#Prop({ required: true })
uin: number;
#Inject("cglItemService")
itemService: ItemService;
public showReorderTooltip = false;
public reorderContainerSize = "";
public moment = moment;
public itemCatalogHistory: CatalogHistory[] = [];
loading: boolean = false;
mounted() {
this.getCatalogHistory();
}
public async getCatalogHistory() {
try {
this.loading = true;
let result = await this.itemService.getv2ItemByUIN(this.uin);
this.loading = false;
if (result.success) {
this.itemCatalogHistory = result.data.expiredCatalogNumbers;
}
}
catch (error) {
this.$snotify.error(error.message);
}
}
}
export interface CatalogHistory {
expireDate: string;
catalogNumber: number;
}
thanks for reading this. I am building a web app using vuejs and flask as server. Do you guys have any recommendation for why it does not recognize "import"? im trying to use this.$http.get . why it is not recognizing it? thanks in advance
import Vue from 'vue'
import VueResource from 'vue-resource'
Vue.component( 'button-labels', {
props : ['labelbtn'],
template : `<div class="button-container"><button class="button-app" v-for="label in labelbtn" v-on:click="clickHandler(label)" >{{label.label}}</button></div>`,
methods : {
clickHandler : function(label) {
if (label.id === 1)
{
this.$emit('event_child', 'search-template')
}
},
}
})
Vue.component( 'search-template', {
props: ['searchdata'],
data : {
entries : []
},
template : `<div><input class="searchBar"><div class="response-list"><button class="entries"></button></div>
<audio class="audio" controls></audio><button class="button-back" v-on:click="backHandler"> Return</button></div>` ,
methods : {
backHandler : function(){
this.$emit('event_child', 'button-labels');
},
},
created : function(){
this.$http.get('https://google.com', (data) => {
console.log( data );
})
.error((err) => console.log(err))
},
})
new Vue({
el: '#app',
data : {
labels : [
{ id : 1, label : "Search" } , { id : 2, label: "Categories" }, { id : 3, label: "Favorites" }, {id : 4, label: "Settings"}
],
currentView : "button-labels",
},
methods : {
eventChild : function(label)
{
this.currentView = label;
}
}
})
this is my package.json
{
"scripts": {
"transpile-es2015": "babel src -d lib"
},
"devDependencies": {
"babel-core": "^6.1.2",
"babel-loader": "^6.1.0",
"babel-plugin-transform-runtime": "^6.1.2",
"babel-preset-es2015": "^6.1.2",
"babel-runtime": "^6.0.14",
"css-loader": "^0.21.0",
"style-loader": "^0.13.0",
"vue-hot-reload-api": "^1.2.1",
"vue-html-loader": "^1.0.0",
"vue-loader": "^7.0.1",
"webpack": "^1.12.3",
"webpack-dev-server": "^1.12.1"
},
"dependencies": {
"bootstrap": "^3.3.5",
"vue-resource": "^0.1.17",
"vue-router": "^0.7.5",
"vue": "^1.0.7"
}
}