vuejs - How to concatenate text to named route - vue.js

How can I concatenate named route to router-link tag? My code:
<router-link
:to="'//https://t.me/share/url?url='+{name: Profile, params: {id: user.user_id}}+'&text=Hi I am ' + user.first_name + ' ' + user.last_name + ':'">Click Here</router-link>
The problem is this part:
{name: Profile, params: {id: user.user_id}}
it returns [Object object]. How can I fix it to return correct value of this object which is http://example.com/profile/1 as an example?

There is no need to use router-link for external links, since it's click should not be processed with vue-router.
I'd suggest to create a computed property (or method) that will return a full url with all data included. Which also will remove certain logic from a template, as a good practice.
Template link will look as follow:
<a :href="telegramLink">Open Telegram</a>
And computed property to generate the link:
computed: {
telegramLink () {
const user = this.user
// Get route information by provided parameters
const route = this.$router.resolve({
name: 'Profile',
params: {
id: user.user_id
}
})
// Create full address url
const url = `${window.location.origin}${route.href}`
const text = `Hi I am ${user.first_name} ${user.last_name}:`
return `https://t.me/share/url?url=${url}&text=${text}`
}
}

Related

how to make params that automatically scrolls to a section

I want to have a route like this.
http://localhost:8080/help/category/newuser#1
Therefore, I write this in my template
<router-link
v-bind:to="{
name: 'help',
params: { id: selectedCategory+'#'+eachQuestion.id },
}"
>
But this doesn't work and resulting in
http://localhost:8080/help/category/newuser%231
So the # turns into %23. How to solve this? Thanks!
You can navigate to a route with params by passing the param names as an object:
params: { category: selectedCategory }
If you are also passing a hash value, you're able to declare the hash property as well:
hash: eachQuestion.id

How to build SEO-friendly routes in NuxtJS?

Im a novice in NuxtJS. My page is structured with a navbar/menu, blog page with all articles listed and a couple of mostly static pages.(like most company websites)
I am retrieving my data from a Strapi API, where I can only fetch single entries by their ID.
What I have to do:
When the user clicks on the navbar link, I need to pass the ID of the corresponding article/post to the article component in order to retrieve the article from the API. So far it is working quite well, but doing it via router params, an article will have an URL like https://www.example.com/posts/63ndjk736rmndhjsnk736r
What I would like to do:
I would like to have an URL with a slug https://www.example.com/posts/my-first-Post and still pass the ID to the article component/page.
Whats the best way to do that?
You can use query. Here is some example:
I have some data:
data = [{id: "63ndjk736rmndhjsnk736r", name: "my-first-post"}, {id: "88ndjk736rmndhjsnk736r", name: "my-second-post"}]
In my navbar list:
<template v-for="(item, index) in data" key="index">
<router-link :to="{ path: '/posts/' + item.name, query: { id: 'item.id' }}"
>{{item.name}}</router-link>
</template>
How your routes show:
http://example.com/posts/my-first-post?id=63ndjk736rmndhjsnk736r
What you need:
Create dynamic Route -> https://nuxtjs.org/guide/routing/#dynamic-routes
Pass query named id which is your single entry ID
Get query (id) and fetch your single entry using query id:
const postId = this.$route.query.id
You can use like _slug.vue in pages folder.
and your routes like this;
{
name: 'posts-slug',
path: '/posts/:slug?',
component: 'pages/posts/_slug.vue'
}
then create a new vue file.
export default {
validate ({ params }) {
return /^\d+$/.test(params.id)
}
}
this way you can also access the parameter

Nuxt add parameters without page and without reload the page

I have a page with big list of data and some buttons for filtering.
for example 2 buttons to filter by status:
Complete status
Cancel status
I want when the user clicked on the complete the url to be changed to
http://demo.com/list?filter=complete
the page does not reloading, it just for get specific url foreach filter button.
How can I implement the code in Nuxt application?
You cannot use $route or $router to change url, it set a new html5 history state and reload the page. So, to change url without reloading, history.replaceState do the job. In your page or component:
methods: {
onClickComplete() {
if (!process.server) { // I'm not sure it's necessary
history.replaceState({}, null, window.location + '?filter=complete') // or use your own application logic: globalSiteUrl, $route... or queryString some vars...
}
}
}
At first you should change your route with "$route.push" or click on
these ways change the route without reloading
After than you can use "pages watchquery" to handle event of changing route
https://nuxtjs.org/api/pages-watchquery/
first create this helper function
export function getAbsoluteUrl(to) {
const path = $nuxt.$router.resolve(to).href
return window.location.origin + path
}
this is example for my tabs
watch: {
tab(value) {
if (!process.server) {
const url = getAbsoluteUrl({
params: { ...this.$route.params, activeTab: value }
})
history.replaceState({}, null, url) // or use your own application logic: globalSiteUrl, $route... or queryString some vars...
}
}
},

Dynamic parameter in href option in Aurelia Routing config.map

This seems like a really simple issue, but it's driving me crazy...
Does anyone know how I can specify a dynamic :id parameter in the href routing configuration option?
The following unfortunately doesn't work:
config.map([
// ... default parameterless routing here
{
route:[':id/request'],
moduleId:'processes/bdd/request/request',
name:'Request', title:'Request', href:`#/bdd/request/${id}/request`, settings:{type:'Request', icon:''}, nav:true,
},
{
route:[':id/requestAuth'],
moduleId:'processes/bdd/request/requestauthorization',
name:'RequestAuthorization', title:'Request Authorization', href:`#/bdd/request/${id}/requestAuth`, settings:{type:'Request', icon:''}, nav:true,
},
// ... some additional mappings here
]);
The href property is static. If you want to generate a route for a link using this route, you could use the route-href custom attribute like this:
route-href="route: request; params.bind: { id: someProp }"
Note that I changed the route name to be camelCase (all lowercase since it is one word here) to match the route naming convention.
I had a similar use case and I was able to get this to work by adding a pipeline step to the router that alters the config on the fly.
My use case may be a little different in that I only want the item to appear in the nav bar when the route is active -- say I have routes /abc, /def/:id, and /ghi -- when the active route is ABC or GHI, only those items will appear in the nav bar, but when the active route is DEF, it should appear in the nav bar, and clicking it should lead to the same DEF ID you're currently looking at. So my route configuration includes a setting that indicates the route should only appear in the nav bar when it's the active route.
Here are the interesting parts of my actual configureRouter function:
configureRouter(config, router) {
config.addPreActivateStep(Preactivate); // explained below
config.map([
// some routes
{ route: 'patients/:patientId', name: 'patient-master',
moduleId: 'patients-and-cases/patient-master/patient-master',
title: 'Patient', nav: true, settings: { renderOnlyWhenActive: true },
href: '#' // it doesn't matter what this is
},
// more routes
]);
}
And here is the Preactivate class that sets the href on preactivate:
class Preactivate {
run(routingContext, next) {
routingContext.config.href = routingContext.fragment;
return next();
}
}
If, unlike me, you want this to display in a nav bar all the time, this will still work -- the href will simply remain set to the last thing it was set to when the route was active. In that case you'd probably want to initialize it to some default value that makes sense.

Sharing data from a VueJS component

I have a VueJS address lookup component.
Vue.component('address-lookup',
{
template: '#address-lookup-template',
data: function()
{
return {
address: {'name': '', 'town:': '', 'postcode': ''},
errors: {'name': false, 'town': false, 'postcode': false},
states: {'busy': false, 'found': false},
result: {}
}
},
methods:
{
findAddress: function(event)
{
if( typeof event === 'object' && typeof event.target === 'object' )
{
event.target.blur();
}
$.ajax(
{
context: this,
url: '/lookup',
data:
{
'name': this.address.name,
'town': this.address.town,
'postcode': this.address.postcode
},
success: function(data)
{
this.states.busy = false;
this.states.found = true;
this.address.name = data.name;
this.result = data;
}
});
},
reset: function()
{
this.states.found = false;
this.result = {};
}
}
});
Inside my template I've then bound the result like so:
<p>{{ result.formatted_address }}</p>
There is some extra data returned within the result (like a twitter handle) that isn't part of the address lookup template, and occurs on a separate part of the form. For reasons relating to how my form is structured I can't include these inputs within the same template.
I found a way to bind those inputs, although it felt somewhat 'hacky'.
<input type="text" name="twitter" v-model="$refs.lookupResult._data.result.twitter">
That all works fine.
My problem is that the form is included as part of a larger template sometimes in the context of creating a new record, sometimes in the context of editing. When editing a record, the lookup component is removed (using an if server-side, so the template is no longer loaded at all) and when that happens I get this error.
$refs.lookupResult._data.result.twitter": TypeError: Cannot read property '_data' of undefined
This makes sense. lookupResult is defined when I include the template, and when editing I am removing this line:
<address-lookup v-ref:lookup-result></address-lookup>
I've worked around it by including a version of each extra input without the v-model attribute, again using a server-side if. But there are quite a few of these and it's getting a bit messy.
Is there a cleaner approach I could be using to better achieve this?
So I don't know the hierarchy of your layout, it isn't indicated above, but assuming that address-lookup component is a child of your parent, and you in fact need the results of address lookup in that parent, eg:
<parent-component> <!-- where you need the data -->
<address-lookup></address-lookup> <!-- where you lookup the data -->
</parent-component>
then you can simply pass the data props, either top-down only (default) or bidirectionally by defining 'address' for example on your parent's vue data hook:
// parent's data() function
data = function () {
return {
address: {}
}
}
// parent template, passed address with .sync modifier (to make it bi-directional)
<parent-component>
<address-lookup :address.sync='address'></address-lookup>
</parent-component>
// have the props accepted in the address look up component
var addressComponent = Vue.extend({
props: ['address']
})
Now in your $.ajax success function, simply set the props you need on this.address. Of course you can do this with all the props you need: errors, results, state etc. Even better, if you can nest them into a single key on the parent, you can pass the single key for the object containing all four elements instead of all four separately.