How to pass parameter down into tab components - ionic4

I am able to use a parameterized route with the simple example from the Ionic PWA like this:
render() {
return (
<ion-app>
<ion-router useHash={false}>
<ion-route url="/" component="app-home" />
<ion-route url="/profile/:name" component="app-profile" />
</ion-router>
<ion-nav />
</ion-app>
);
This is picked up in the corresponding profile page with a simple #Prop like this:
#Prop() name: string;
But when I try to use a tab setup, I can't seem to get access to the parameter. This does not work:
renderRouter() {
return (
<ion-router useHash={false}>
<ion-route-redirect from="/" to='/blog' />
<ion-route component="page-tabs">
<ion-route url="/blog" component="tab-blog">
<ion-route component="page-blog"></ion-route>
</ion-route>
<ion-route url="/photos/:name" component="tab-books">
<ion-route component="page-photos"></ion-route>
</ion-route>
</ion-route>
</ion-router>
);
}
How can I get access to the parameter from down in the page-photos component that is loaded in the tab-books tab? I am not using any framework other than Ionic / Stencil PWA (no Angular, React, or anything else). I'm trying to create a pure web component solution with no framework use. Can Ionic support this use case?

The solution, I found, was to set the url to the tab component to be only the base of the full URL (/photos/:name). Then, set the page component's url to be just the parameter part as follows:
<ion-route url="/photos" component="tab-books">
<ion-route url="/:name" component="page-photos"></ion-route>
</ion-route>
With this setup, /photos/name, will navigate to the 'tab-books' tab, which will load up 'page-photos', which will properly obtain the name parameter via the following in the page-photos component:
#Prop() name: string;

Related

What is the point of app directory inside next.js 13?

I am trying to set up next-auth inside next.js 13. In order to be able to use the useSession in app directory, I have to convert the page to a client page by using use client.
Then I need to wrap _app.js with SessionProvider and layout file in app directory
export default function App({
Component,
pageProps: { session, ...pageProps },
}) {
return (
<SessionProvider session={session}>
<Component {...pageProps} />
</SessionProvider>
)
}
and RootLayout in app component
export default function RootLayout({ children }) {
return (
<html>
<head />
<body>
<SessionProvider>{children}</SessionProvider>
</body>
</html>
);
}
Now I am repeating myself twice and I have to convert server page to a client if I want to use next-auth. Is there still any benefit of using app directory in this project? In the future, I might have a similar setup for different purposes.

Nuxt not automatically importing components from nested directory

In my nuxt app, components in nested directories are not automatically importing as expected. For some of my components i have something like the following:
vue 2.6.12, nuxt 2.15.0
components\ Directory structure
TopArea\
--SomeComponent.vue
<template>
<header class="header">
<div>Hello</div>
<SomeComponent />
</header>
</template>
No other component in the application has the name SomeComponent. In the example above i get the error: Unknown custom element: <SomeComponent> - did you register the component correctly? For recursive components, make sure to provide the "name" option.. I can get around the issue by specifying the directory name before the component filename (TopAreaSomeComponent), use the prefix option in nuxt.config, or by manually importing the component. This is confusing because the docs state:
Nested Directories
If you have components in nested directories such as:
components/baseButton.vue
The component name will be based on its own filename. Therefore, the component will be:
<button />
It goes on to say "We recommend you use the directory name in the filename for clarity". But that seems like a rule than a recommendation. If i don't use the directory name as part of the filename, dynamic imports are not working for components in nested directories.
Is this an error in the docs or am I reading it wrong?
Since Nuxt 2.15.0, components changed in the way they work as stated in this github issue.
Depending of you structure and how you want to handle your organization, you may edit your configuration accordingly to the migration guide available here: https://github.com/nuxt/components#v1-to-v2
Or you could also simply set the pathPrefix option to have all your components available without any prefix at all.
nuxt.config.js/ts
components: [
{
path: '~/components', // will get any components nested in let's say /components/test too
pathPrefix: false,
},
]
PS: this solution also works with Nuxt3.
This documentation actually do need an update, indeed: https://nuxtjs.org/docs/2.x/directory-structure/components#components-discovery
This is how it works: for a given page
<template>
<div>
<yolo-swag /> <!-- no need for <nested-yolo-swag /> here -->
</div>
</template>
And with the following file tree
Update for Nuxt3
Looks like this is the new official syntax
import { defineNuxtConfig } from 'nuxt'
export default defineNuxtConfig({
components: {
global: true,
dirs: ['~/components']
},
})
This may answered already. But to illustrate the solution to comers here here's the way according to docs:
<TopAreaSomeComponent />
if your components is nested deeply:
components / TopArea / SomeComponent.vue
https://nuxtjs.org/docs/directory-structure/components/#nested-directories

How to layout Vue so pages include header/nav but ability to display stand alone pages such as registration

My current Vue app is laid out as follows:
Such that login Vue would be live under VContent, and aspects of the header and nav are be disabled based on auth state. For example, logout button if store.isAuthenticaaed. See below:
If a Register exists on the login page leading to a registration Vue, how would I break that Vue out of the parent App.vue as to not display the header or nav at all? Should I move my header/wrapper down a level and if so how?
The below answer is totally based on how I understand your requirement, happy to correct if the assumptions are wrong.
Redirecting to which page can be handled at the router configuration.
As per your layout, I can see you have
<VApp>
<VBar />
<VContent >
<router-view />
</VContent>
<VNavigationDrawer />
</VApp>
Now, your store knows whether the user is authenticated or not.
So Why not simply remove <VBar /> and <VNavigation /> using v-if. However, you need to make sure that your state is having the correct state at the initial render.
I can simply create a computed property stating
showBarAndNavigation () {
return store.isAuthenticated && this.$route.name === 'Login' && // anymore handlers
}
<VApp>
<VBar v-if="showBarAndNavigation" />
<VContent >
<router-view />
</VContent>
<VNavigationDrawer v-if="showBarAndNavigation" />
</VApp>

How to insert content inside tinymce editor using vue js?

I want to insert content like <span class="some-class">text</span> inside tinymce editor using a button in vue js template. How could I accomplish that using the tinymce-vue wrapper?
Here's the code:
<template>
<tinymce-editor
api-key="my-api-key-here"
/>
<button #click="addContent">button</button>
</template>
import Editor from '#tinymce/tinymce-vue'
export default {
components: {
tinymceEditor: Editor
},
methods: {
addContent () {
tinymce.activeEditor.setContent('<span class="some-class">text</span>');
}
}
}
Edit:
I also installed tinymce using npm i tinymce --save and added the import import tinymce from 'tinymce/tinymce to the code above. Now I don't get the error 'tinymce' is not defined anymore, but the editor doesn't appear either.
If you want to use tinymce in vue with typscritt to set up your content and avoid the undefined error you need to import tinyMCE as
import { getTinymce } from '#tinymce/tinymce-vue/lib/cjs/main/ts/TinyMCE';
Then you can set your content
getTinymce().activeEditor.setContent('coucou');
In your event handler for the button click, you can call TinyMCE's .setContent() method to set editor content.
Here is a demo:
https://codesandbox.io/s/set-content-in-tinymce-in-vue-jzciu
Don't forget, tinymce-vue doesn't include the code for TinyMCE itself. You'll either have to use an API key (which you can get for free at tiny.cloud) or use a self-hosted installation of TinyMCE. (For more info, see Step 6, here: https://www.tiny.cloud/docs/integrations/vue/#procedure)
I finally gave up trying to get access to tinymce in Vue 3 component. It either undefined or if it is not undefined - setContent command just do nothing - no errors but still no content inserted.
I just used recommended for "#tinymce/tinymce-vue" way of data binding using v-model
It looks like this:
<Editor
v-model="someLocalVar"
api-key="no-api-key"
:init="{
plugins: 'lists link image table code help wordcount',
}"
/>
then
watch(someLocalVar, () => {
//do whatever you like with your someLocalVar
});
If you want to insert content into TinyMCE you should use its APIs to do so:
https://www.tiny.cloud/docs/api/tinymce/tinymce.editor/#setcontent
https://www.tiny.cloud/docs/api/tinymce/tinymce.editor/#insertcontent
For example:
tinymce.activeEditor.setContent('<span class="some-class">text</span>');
tinymce.activeEditor.insertContent('<span class="some-class">text</span>');

Load a different page in nuxt at runtime based on the parameters in the route

We have a scenario in which a different page is required to be loaded based on whether parts of the route has parameters that are valid and that can be determined at run-time.
Consider the following example:
Request to http://example.com/param1/param2
If param1 is a valid product identifier (can be determined by an API call to another service) the product page loads or its considered a category and Category Page is loaded.
Considering Nuxt uses static routes mostly and the list of products are dynamic, is there a hook where you can execute custom code to load a different page ?
Cant you create _product page
like described in nuxt docs:
https://nuxtjs.org/guide/routing/#dynamic-routes
And in your code make something like:
<template>
<div>
<nuxt-child />
</div>
</template>
<script>
export default {
asyncData({route, params, redirect}) {
//use route
console.log(route.params.slug)
//directly use params
console.log(params.slug)
redirect(`/`);
},
};
</script>
or use mounted() hook if you are creating SPA