PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0
Showing posts with label vue-composition-api. Show all posts
Showing posts with label vue-composition-api. Show all posts

Monday, October 17, 2022

[FIXED] How to use JSDoc to document a Vue component with script setup?

 October 17, 2022     jsdoc, typescript, vue-composition-api, vue.js     No comments   

Issue

I'm building a Vue library with TypeScript. I'd like to export the documentation of the components, like I do with ordinary functions.

Previously we would do this:

<script>
/**
 * This is the documentation of my component.
 */
export default {
}
</script>

<template></template>

But now with script setup:

<script setup lang="ts">
</script>

<template></template>

How do we document the component?


Solution

With <script setup> you can't use JSDoc on the component export.

It's a compiler syntaxic sugar that gets out the export of the setup function, so you obviously can't comment a function that is "generated" by the compiler.

If you really needs JSDoc, you should use a regular <script> with a default export :)

<script>
/** This is my nice component documentation */
export default {
  name: 'MyComponent',
  setup() {
    // your code
  }, 
}
</script>

Also works with the typescript defineComponent wrapper:

<script>
import { defineComponent } from 'vue'

/** This is my nice component documentation */
export default defineComponent({
  name: 'MyComponent',
  setup() {
    // your code
  }
})
</script>

EDIT: as mentionned by @EstusFlask in the comments, you can mix both <script setup> and <script> on a SFC component (see docs) So you can use the regular script to expose your JSDoc.

<script setup>
// component setup. Takes priority over the eventual `setup()` function of the export object in <script>.
</script>

<script>
/** This is my nice component documentation */
export default {
  name: 'MyComponent',
}
</script>


Answered By - Kapcash
Answer Checked By - Candace Johnson (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How to annotate types in the template?

 October 17, 2022     typescript, vue-composition-api, vue.js, vuejs3     No comments   

Issue

<template>
                 👇 Parameter 'el' implicitly has an 'any' type. -->
  <v-table :ref="el => (table.ref = el)"></v-table>
</template>

<script lang="ts">
  import { defineComponent, ref } from 'vue'

  export default defineComponent({
    setup() {
      return {
        table: ref({
          ref: null,
        }),
      }
    },
  })
</script>

enter image description here


Solution

Update: it is now supported.


Seems TypeScript support in the template is not available yet, quote from Vue's author Evan You:

This is technically doable:

  1. We use @babel/parser to parse inline expressions, which already comes with TypeScript support for free. I tested by adding typescript to the parser plugin list and your example compiles just fine.
  2. We need to add a pass to strip type annotations, which can be done with esbuild so that will still be reasonably fast.

Obviously this won't work for the in-browser build, but runtime and build-time compilations already have different levels of support.

Still, I'll need to play with this and @vuedx to see whether the benefit justifies the extra cost.

Reference: Support TypeScript in vue template



Answered By - Wenfang Du
Answer Checked By - David Goodson (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Sunday, October 16, 2022

[FIXED] How does Computed work in Vue 3 script setup?

 October 16, 2022     vue-composition-api, vue-script-setup, vue.js, vuejs3     No comments   

Issue

I'm trying to get computed to work in <script setup>:

<template>
  <div>
    <p>{{ whatever.get() }}</p>
  </div>
</template>


<script setup>
import {computed} from "vue";

const whatever = computed({
    get() {
        console.log('check')
        return 'check?';
    }
})
</script>

The console.log() comes through but the return statement seems to throw an error:

check
Vue warn]: Unhandled error during execution of render function 
  at <Cms>
Uncaught TypeError: $setup.whatever.get is not a function
at Proxy.render (app.js?id=d9e007128724c77a8d69ec76c6c081a0:39550:266)
at renderComponentRoot (app.js?id=d9e007128724c77a8d69ec76c6c081a0:25902:44)
at ReactiveEffect.componentUpdateFn [as fn] (app.js?id=d9e007128724c77a8d69ec76c6c081a0:30019:57)
at ReactiveEffect.run (app.js?id=d9e007128724c77a8d69ec76c6c081a0:23830:29)
at setupRenderEffect (app.js?id=d9e007128724c77a8d69ec76c6c081a0:30145:9)
at mountComponent (app.js?id=d9e007128724c77a8d69ec76c6c081a0:29928:9)
at processComponent (app.js?id=d9e007128724c77a8d69ec76c6c081a0:29886:17)
at patch (app.js?id=d9e007128724c77a8d69ec76c6c081a0:29487:21)
at render (app.js?id=d9e007128724c77a8d69ec76c6c081a0:30630:13)
at mount (app.js?id=d9e007128724c77a8d69ec76c6c081a0:28882:25)

What am I doing wrong?


Solution

In <template>:

Getter only:

  • {{ myVal }}
  • <p v-text="myVal" />

Getter and setter:

  • <input v-model="myVal">

Important: Do not use myVal.get() or myVal.set(value)! Use:

  • getting: myVal
  • setting (assignment): myVal = value

In <script setup>:

Getter only:

const someReactiveRef = ref(null)
const myVal = computed(() => someReactiveRef.value)

Getter & setter:

const someReactiveRef = ref(null)

const myVal = computed({
  get() {
    return someReactiveRef.value
  },
  set(val) {
    someReactiveRef.value = val
  }
})
// myVal can now be used in `v-model`

When the reactive ref is coming from a reactive() object's property, you don't need the .value in either the setter or the getter. Example:

const state = reactive({
  someProp: null
})

const myVal = computed({
  get() {
    return store.someProp
  },
  set(val) {
    store.someProp = val
  }
})

Remember you can always use computed inside reactive. Example:

const { createApp, reactive, computed, toRefs } = Vue
createApp({
  setup() {
    const state = reactive({
      firstName: 'John W.',
      lastName: 'Doe',

      // getter + setter
      fullName: computed({
        get() {
          return [state.firstName, state.lastName].join(' ')
        },
        set(val) {
          const [last, ...rest] = val.split(' ').reverse()
          state.firstName = rest.reverse().join(' ')
          state.lastName = last
        }
      }),

      // getter only:
      name: computed(() => state.fullName)
    })
    return toRefs(state)
  }
}).mount('#app')
<script src="https://unpkg.com/vue@3.2.40/dist/vue.global.prod.js"></script>
<div id="app">
  <input v-model="firstName" />
  <input v-model="lastName" />
  <input v-model="fullName" />
  <pre v-text="{ firstName, lastName, fullName, name }"></pre>
</div>

Important notes:

  • when passing a non-reactive reference to a computed, Vue will warn you (the computed wrapper is unnecessary).
  • when passing it a ref which contains a cyclic dependency (e.g: a component instance) Vue will again warn you and advise on using either shallowRef or markRaw.


Answered By - tao
Answer Checked By - Cary Denson (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Saturday, October 15, 2022

[FIXED] How to scrollIntoView in vue composition api that use script setup?

 October 15, 2022     dom, javascript, vue-composition-api, vue-script-setup, vuejs3     No comments   

Issue

I have a parent app(parent.vue) that emit value from child app(MainMenu.vue) that used to scroll in spesific pageview by id in parent app, but when i run it give the error message TypeError: document.getElementById(...) is null.

This is the parent app that i want to scroll in spesific pageview

parent.vue

<template>
  <section>
    <MainCover></MainCover>
    <QuotePage></QuotePage>
    <GroomBride id='1'></GroomBride>
    <TimeLines id='2'></TimeLines>
    <RunDown id='3'></RunDown>
    <SpecialInvitation></SpecialInvitation>
    <LiveStream></LiveStream>
    <OurMoment id='4'></OurMoment>
    <MessageBox id='5'></MessageBox>
    <FooterPage></FooterPage>
    <MainMenu @coba="onCoba" @page="navigation"></MainMenu>
  </section>
</template>

<script setup>
import QuotePage from '@/components/QuotePage.vue'
import MainCover from '@/components/MainCover.vue'
import GroomBride from '@/components/GroomBride.vue'
import TimeLines from '@/components/TimeLines.vue'
import RunDown from '@/components/RunDown.vue'
import SpecialInvitation from '@/components/SpecialInvitation.vue'
import OurMoment from '@/components/OurMoment.vue'
import MessageBox from '@/components/MessageBox.vue'
import FooterPage from '@/components/FooterPage.vue'
import MainMenu from '@/components/MainMenu.vue'
import LiveStream from '@/components/LiveStream.vue'


// Navigation handler
const navigation = val => {
  console.log(val);
  document.getElementById(val).scrollIntoView({
    behavior: 'smooth'
  })
}

</script>

This is the child app that i emit a value to parent,

MainMenu.vue

<template>
  <div class="container">
      <div class="notification is-primary p-2">
              <!-- <span class="mr-4" @click="editEvent(day.id, event.details)"><fa :icon="['fas', 'pencil']" /></span>
              <span @click="deleteEvent(day.id, event.details)"><fa :icon="['fas', 'trash']" /></span> -->
          <span class="icon-text is-paddingless is-marginless">
              <span @click="navPage('1')" class="icon">
                  <font-awesome-icon icon="fa-solid fa-heart" />
              </span>
              <!-- <span>Couple</span> -->
              <span @click="navPage('2')" class="icon">
                  <font-awesome-icon icon="fa-solid fa-calendar-days" />
              </span>
              <!-- <span>Date</span> -->
              <span @click="navPage('3')" class="icon">
                  <font-awesome-icon icon="fa-solid fa-map" />
              </span>
              <!-- <span>Location</span> -->
              <span @click="navPage('4')" class="icon">
                  <font-awesome-icon icon="fa-solid fa-images" />
              </span>
              <!-- <span>Galleries</span> -->
              <span @click="navPage('5')" class="icon">
                  <font-awesome-icon icon="fa-solid fa-pen-to-square" />
              </span>
              <!-- <span>Wishes</span> -->
          </span>
      </div>
  </div>
</template>

<script setup>
import { defineEmits } from "vue";

const emit = defineEmits(['page']);


const navPage = (value) => {
    emit("page", value)
}

</script>

I consider that the error is in the accessing dom from script setup. I have tried but did'nt get solution, please help. Thanks


Solution

Its done, i update my code

MainMenu.vue

<template>
  <div class="container">
      <div class="notification is-primary p-2">
          <span class="icon-text is-paddingless is-marginless">
              <span @click="navPage('groom')" class="icon">
                  <font-awesome-icon icon="fa-solid fa-heart" />
              </span>
              <!-- <span>Couple</span> -->
              <span @click="navPage('time')" class="icon">
                  <font-awesome-icon icon="fa-solid fa-calendar-days" />
              </span>
              <!-- <span>Date</span> -->
              <span @click="navPage('run')" class="icon">
                  <font-awesome-icon icon="fa-solid fa-map" />
              </span>
              <!-- <span>Location</span> -->
              <span @click="navPage('moment')" class="icon">
                  <font-awesome-icon icon="fa-solid fa-images" />
              </span>
              <!-- <span>Galleries</span> -->
              <span @click="navPage('message')" class="icon">
                  <font-awesome-icon icon="fa-solid fa-pen-to-square" />
              </span>
              <!-- <span>Wishes</span> -->
          </span>
      </div>
  </div>
</template>

<script setup>
import { defineEmits } from "vue";

const emit = defineEmits(['page']);


const navPage = (value) => {
    emit("page", value)
}

</script>

parent.vue

<template>
  <section>
    <MainCover></MainCover>
    <QuotePage></QuotePage>
    <div ref="groom">
      <GroomBride></GroomBride>
    </div>
    <div ref="time">
      <TimeLines></TimeLines>
    </div>
    <div ref='run'>
      <RunDown></RunDown>
    </div>
    <SpecialInvitation></SpecialInvitation>
    <LiveStream></LiveStream>
    <div ref='moment'>
      <OurMoment></OurMoment>
    </div>
    <div ref='message'>
      <MessageBox></MessageBox>
    </div>
    <FooterPage></FooterPage>
    <MainMenu @page="navigation"></MainMenu>
  </section>
</template>

<script setup>
import QuotePage from '@/components/QuotePage.vue'
import MainCover from '@/components/MainCover.vue'
import GroomBride from '@/components/GroomBride.vue'
import TimeLines from '@/components/TimeLines.vue'
import RunDown from '@/components/RunDown.vue'
import SpecialInvitation from '@/components/SpecialInvitation.vue'
import OurMoment from '@/components/OurMoment.vue'
import MessageBox from '@/components/MessageBox.vue'
import FooterPage from '@/components/FooterPage.vue'
import MainMenu from '@/components/MainMenu.vue'
import LiveStream from '@/components/LiveStream.vue'

import { ref, onMounted } from "vue";

const groom = ref()
const time = ref()
const run = ref()
const moment = ref()
const message = ref()


// // Navigation handler
const navigation = val => {
  console.log(val)
  if (val == 'groom') {
    groom.value.scrollIntoView({behavior: "smooth"})
  } else if (val == 'time') {
    time.value.scrollIntoView({behavior: "smooth"})
  } else if (val == 'run') {
    run.value.scrollIntoView({behavior: "smooth"})
  } else if (val == 'moment') {
    moment.value.scrollIntoView({behavior: "smooth"})
  } else if (val == 'message') {
    message.value.scrollIntoView({behavior: "smooth"})
  }
}


onMounted( () => {
  navigation();
})

</script>


Answered By - cahya faisal reza
Answer Checked By - Candace Johnson (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Friday, October 14, 2022

[FIXED] How to correctly import Axios in vue 3 after creating new project with CLI?

 October 14, 2022     axios, javascript, vue-composition-api, vue.js, vuejs3     No comments   

Issue

I created a new project using:

vue create hello-world

Generating a new project that includes the HelloWorld.vue, app.vue, main.js (etc ...) files.

Now I install Axios by following the docs Npm vue-axios:

npm install --save axios vue-axios

I import Axios in the main.js file:

import Vue from 'vue'
import axios from 'axios'
import VueAxios from 'vue-axios'

And now I run into a problem that I don't understand. The VueAxios docs say you simply use it like so:

const app = Vue.createApp(...)
app.use(VueAxios, axios)

But the way app is created in Vue 3 is different. I think this is where the problem comes from:

createApp(App).mount('#app')

So, how do I correctly import axios?


Solution

createApp(App).mount('#app') is effectively the same as:

import Vue from 'vue'
const app = Vue.createApp(App)
app.mount('#app')

// or
import { createApp } from 'vue'
const app = createApp(App)
app.mount('#app')

So following Vue Axios's docs, just insert the line for app.use():

import { createApp } from 'vue'
import axios from 'axios'
import VueAxios from 'vue-axios'

const app = createApp(App)
app.use(VueAxios, axios) // 👈
app.mount('#app')

You could also chain it like this:

createApp(App).use(VueAxios, axios).mount('#app')

demo



Answered By - tony19
Answer Checked By - Mildred Charles (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Thursday, October 13, 2022

[FIXED] How to create axios plugin in Vue 3 composition api

 October 13, 2022     axios, typescript, vue-composition-api, vuejs3     No comments   

Issue

I am using Vue 3 composition api and typescript .

I want to make Axios plugin to use in my project .

this is my code

plugins/axios.js

import axios from 'axios'
const axiosInstance = axios.create({
    baseURL: import.meta.env.VITE_API_URL,
})
export default {
    install: (app, options) => {
        app.config.globalProperties.$axios={ ...axiosInstance }
    }
}

main.ts

import { createApp } from 'vue'

import axiosPlugin from '@/plugins/axios.js'


import App from './App.vue'

const app = createApp(App)

app.use(axiosPlugin, {})

app.mount('#app')

my component

<script setup lang="ts">
import { $axios } from 'vue'

But I have error in last code section

Module '"vue"' has no exported member '$axios'.ts(2305)

enter image description here

maybe something is wrong in declaring plugin for axios

what's the problem ?


Solution

Your axios plugin is not exposed in the Vue library, so importing is not going to work. Your plugin is hooked to the Vue instance. In Vue 2 (or options API) you could use this keyword but in the setup method you need to use getCurrentInstance. Try this

<script setup lang='ts'>
    import { getCurrentInstance } from 'vue'

    const app = getCurrentInstance()
    const axios = app.appContext.config.globalProperties.$axios
</script>

Alternatively you can use provide/inject methods.
In your main.ts

app.provide('axios', axiosInstance);

In your component

import { inject } from 'vue';
const axios = inject('axios');


Answered By - Stutje
Answer Checked By - Dawn Plyler (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Sunday, July 10, 2022

[FIXED] How to correctly declare static refs in Composition API using Typescript?

 July 10, 2022     reference, typescript, vue-composition-api, vue.js, vuejs3     No comments   

Issue

I am using the Composition API (with <script setup lang='ts'>) to create a ref, used in my template:

const searchRef = ref(null)
onMounted(() => { searchRef.value.focus() })

It does work and my code compiles without errors. The IDE (JetBrains Goland or Webstorm), however, complains with TS2531: Object is possibly 'null'..

The hardcore solution is to use

// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Object is possibly 'null'.

but I would like to understand if there is a better way.

I was hoping for optional chaining to be a solution:

const searchRef = ref(null)
onMounted(() => { searchRef.value?.focus() })

The code still compiles and the app still works, but I now have TS2339: Property 'focus' does not exist on type 'never'.

What is the correct way to address this problem?


Solution

For template refs, pass a generic type argument to the ref at initialization. The generic type should match the type of the template ref's targeted element.

Here are some examples of template refs on native HTML elements:

const htmlElemRef = ref<HTMLElement>()         // => type: HTMLElement | undefined
const inputRef = ref<HTMLInputElement>()       // => type: HTMLInputElement | undefined
const textareaRef = ref<HTMLTextAreaElement>() // => type: HTMLTextAreaElement | undefined

The null initialization is optional, and I often omit it for slightly more succinct code. The resulting type is <T | undefined>, which is more correct than null because the ref would actually be undefined if the element did not exist in the template. Optional chaining is still needed for the ref's value (given that it's possibly undefined).

Example:

const searchRef = ref<HTMLInputElement>()
onMounted(() => { searchRef.value?.focus() })

As @Kurt pointed out, template refs on Vue components require different typing. The generic type for the ref would be an InstanceType of the component's type (from a .vue import) (docs):

InstanceType<typeof MyComponentDefinition>

Example:

import HelloWorld from '@/components/HelloWorld.vue'

const helloRef = ref<InstanceType<typeof HelloWorld>>()

Note: To use this with Volar in TypeScript files instead of Vue SFCs, make sure to enable Volar's Takeover Mode.

demo



Answered By - tony19
Answer Checked By - Marie Seifert (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Sunday, July 3, 2022

[FIXED] How to integrate paypal Payment Button Vuejs3 Composition API (setup function)

 July 03, 2022     paypal, vue-composition-api, vue.js, vuejs3     No comments   

Issue

I'm trying to integrate PayPal buttons with my Vuejs3 project using Composition API (setup ) but all what i get is errors i try to integrate it without using setup and its working fine i leave the working script down the esseu is i couldent pass data from data to methodes

<script>
import { inject, onMounted, ref } from "vue";
export default {
 
  data() {
    return {
      loaded: false,
      paidFor: false,
      product: {
        price: 15.22,
        description: "leg lamp from that one movie",
        img: "./assets/lamp.jpg",
      },
    };
  },
   setup() {
    const store = inject("store");
    console.log(store.state.prodects_in_cart);
    return { store };
  },methods:{
     setLoaded: function() {
      this.loaded = true;
     paypal_sdk
        .Buttons({
          createOrder: (data, actions) => {
            return actions.order.create({
              purchase_units: [
                {
                  description: this.product.description,
                  amount: {
                    currency_code: "USD",
                    value: this.product.price
                  }
                }
              ]
            });
          },
          onApprove: async (data, actions) => {
            const order = await actions.order.capture();
            this.data;
            this.paidFor = true;
            console.log(order);
          },
          onError: err => {
            console.log(err);
          }
        })
        .render(this.$refs.paypal);
    }
    
  },
  mounted: function() {
    const script = document.createElement("script");
     script.setAttribute('data-namespace',"paypal_sdk");
    script.src ="https://www.paypal.com/sdk/js?client-id=Here i pute my Client Id";
    script.addEventListener("load", this.setLoaded);
   
    document.body.appendChild(script);
  },
};
</script>

the error i get when i use setup() is The error image

my script using setup()

 setup() {
    const store = inject("store");
    const paypal = ref(null);
    let loaded = ref(false);
    let paidFor = ref(false);

    const product = {
      price: 15.22,
      description: "leg lamp from that one movie",
      img: "./assets/lamp.jpg",
    };

    onMounted: {
      const script = document.createElement("script");
      script.setAttribute("data-namespace", "paypal_sdk");
      script.src =
        "https://www.paypal.com/sdk/js?client-id=AXDJPmFjXpXm9HMXK4uZcW3l9XrCL36AxEeWBa4rhV2-xFcVYJrGKvNowY-xf2PitTSkStVNjabZaihe";
      script.addEventListener("load",  ()=>{
          loaded = true;
       console.log('hello adil');
      paypal_sdk
        .Buttons({
          createOrder: (data, actions) => { 
            return actions.order.create({
              purchase_units: [
                {
                  description: 'this is product description',
                  amount: {
                    currency_code: "USD",
                    value: 120.00,
                  },
                },
              ],
            });
          },
          onApprove: async (data, actions) => {
            const order = await actions.order.capture();
            this.data;
            this.paidFor = true;
            console.log(order);
          },
          onError: (err) => {
            console.log(err);
          },
        })
        .render(paypal);
      });
      document.body.appendChild(script);
    }
    return { store ,paypal};
  }

Solution

  1. paypal is a ref. You're currently passing to paypal_sdk the ref itself and not the inner value, which would be the template ref's element. To fix this, pass the ref's .value.

  2. Your onMounted code is not properly invoked, as it must be passed a callback.

import { onMounted, ref }  from 'vue'

export default {
  setup() {
    const paypal = ref(null)

    onMounted(/* 2 */ () => {
      const script = document.createElement('script')
      //...
      script.addEventListener('load', () => {
        paypal_sdk
          .Buttons(/*...*/)
          .render(paypal.value) /* 1 */
      })
    })

    return {
      paypal
    }
  }
}


Answered By - tony19
Answer Checked By - Dawn Plyler (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Older Posts Home
View mobile version

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
All Comments
Atom
All Comments

Copyright © PHPFixing