How would I implement an icon library (Tabler) in Vuetify? - javascript

I am using Vue2 and Vuetify in a project. I would like to be able to use any icon from the Tabler icon library, like so:
<v-icon>custom-icon-name</v-icon
I do not want to use the custom component based system with:
<v-icon>$vuetify.icons.iconName</v-icons>
Conceptually, what would be some possible solutions? Will I need to create a module for this, and if so, what would be a good approach? Thank you for your time.

The option that technically is working for me—but will be tedious to do—is to implement a TablerIcon.vue component:
<template>
<div>
<template v-if="iconName=='Deg360ViewIcon'">
<Deg360ViewIcon :size="size" :stroke-width="strokewidth" />
</template>
<template v-else>
<QuestionMarkIcon :size="size" :stroke-width="strokewidth" />
</template>
</div>
</template>
<style>
</style>
<script>
export default {
name: 'TablerIcon',
props: ['iconName','size','strokewidth'],
data() {
return {
}
},
}
</script>
And then I call this with:
import TablerIcon from './TablerIcon.vue'
...
components: {TablerIcon},
<TablerIcon :iconName="'Deg360ViewIcon'" :size="24" :strokewidth="1.5"/>
This seems to be working with the npm package found here: https://www.npmjs.com/package/vue-tabler-icons

Related

How to dynamically inject components/fields into a dummy page using vue js?

I am trying to create a dummy vue page, were the different components used in the page like b-field ,b-table etc should be injected into the page in order to make things more dynamic. Currently the fields and components are defined in the template section of the .vue page.
<template>
<div class="container is-fluid">
<b-loading :is-full-page="true" :active.sync="this.isLoading"></b-loading>
<p class="subtitle">Business Unit</p>
<b-field label="Business Unit">
<b-input
required
:disabled="this.newRecord ? false : true"
:value="this.objectData.id"
#input="(newValue)=>{updateValue(newValue,'id')}"
></b-input>
</b-field>
<b-field label="Description">
<b-input
:value="this.objectData.description"
#input="(newValue)=>{updateValue(newValue,'description')}"
></b-input>
</b-field>
<b-field label="Short Description">
<b-input
:value="this.objectData.shortdescription"
#input="(newValue)=>{updateValue(newValue,'shortdescription')}"
></b-input>
</b-field>
<b-field label="Status">
<b-autocomplete
:value="this.objectData.status"
:open-on-focus="true"
:keep-first="true"
:data="['Active','InActive']"
#input="(newValue)=>{updateValue(newValue,'status')}"
></b-autocomplete>
</b-field>
<section>
<p class="is-size-7 has-text-danger">{{submitError}}</p>
<b-button #click="submitForm" class="is-radiusless">Submit</b-button>
<b-button type="is-text" #click="$router.go(-1)" class="is-radiusless">Return</b-button>
</section>
</div>
</template>
<script>
import { viewMixin } from "../viewMixin.js";
const ViewName = "BusinessUnitDetail";
export default {
name: "BusinessUnitDetail",
mixins: [viewMixin(ViewName)],
};
</script>
But the components mentioned in the template section should actually be stored as a string and going forward in the future this string will be retrieved from the database instead. But for the time being and as a starting point , this string can be hardcoded in the script section itself. Now i need a solution or guidance on how to achieve this and make the page to actually work..
Note: Please note that in vue js, i know that we could show or hide components based on the application state using Vue conditional structures such as v-if and v-else. But this is not what iam talking about. Instead i want the components (b-field,b-table etc) to be dynamically injected into the DOM. So in future if there will be an extra b-field or any other component, i can simply append the component tag to the string and that new component will be rendered in the frontend successfully.Plz help?
I guess the solution you look for is vue dynamic components.
So you can do this:
<template v-for="(item, index) of components" :key="index">
<component :is="item.name" :any-prop="item.anyProp">
</template>
...
<script>
// ...
data() {
return {
components: [
{ name: 'b-field', anyProp: 'status' }
]
}
}
</script>

v-app not showing page layout using vuetify

I am using vuetify version 2.3.10. I have a file with layout somewhat like this
<template>
<v-app>
<div>
<Users />
</div>
</v-app>
</template>
<script>
import Users from 'views/users.vue';
export default {
components: {
Users
},
</script>
But "Hello" doesn't show on the browser. But if I remove the tag something like this.
<template>
<div>
<Users />
</div>
</template>
Then in the browser I am getting this error. Cannot read property 'mobileBreakpoint' of undefined. Please help me resolve this issue.
users.vue(component)
<template>
<div>
<p>Hello</p>
</div>
</template>
index.js
The issue was here. I forgot to add vuetify : new Vuetify(), and the issue is resolved.
import Vue from 'vue';
import Vuetify from 'vuetify';
Vue.use(Vuetify);
new Vue({
vuetify : new Vuetify(),
...
});
In your Users component there should be an export default statement as well (without it you can't import it later) and give it the name: 'Users' for good measure as well. Then it should work as intended. Better also store your components in components. views are meant for everything that has an own route.
Users.vue
<template>
<div><p>Hello</p></div>
</template>
<script>
export default {
name: 'Users',
}
</script>
Other.vue
<template>
<v-app>
<div>
<Users />
</div>
</v-app>
</template>
<script>
import Users from '#/components/users.vue';
export default {
components: {
Users
},
</script>
I am in a process of migration of vuetify version 1.5 to 2.3 like you
in my case,
contains minus z-index
check your style sheet

Using v-edit-dialog with components?

i had a question about the v-edit-dialog component that vuetify offers. So, the way i am rendering my v-data-table is such that i am importing a component with props into a template slot. According to the documentation link, it seems like the data table has to be rendered directly, like this codepen.
So i am not sure how i can make the v-edit-dialog work using my approach.
Here is what my code looks like:-
<template>
<v-data-table>
<template v-slot:items="props">
<my-component
:protein="props.item.protein"
:carbs="props.item.carbs"
:fats = "props.item.fats"
:iron="props.item.iron"/>
</template>
<v-data-table>
</template>
I am sorry guys, i don't know how i can duplicate this issue but i hope you get some idea. Again, thank you in advance.
You should take a look at the documentation for component props.
What you have done by now is correct and should work, only if you have setup your component my-component correctly:
<!-- my-component example -->
<template>
<v-edit-dialog :return-value.sync="protein">
{{ protein }}
<template v-slot:input>
<v-text-field
v-model="protein"
:rules="[max25chars]"
label="Edit"
single-line
counter
/>
</template>
</v-edit-dialog>
</template>
<script>
export default {
name: 'my-component',
props: {
protein: {
type: String,
default: '',
}, //... the rest of the props you want to access
},
}
</script>
In order to make the protein and other props edit/mutate/update your props.item.protein etc, you have to add a sync modifier to the prop.
<template>
<v-data-table>
<template v-slot:items="props">
<my-component
:protein.sync="props.item.protein"
:carbs.sync="props.item.carbs"
:fats.sync="props.item.fats"
:iron.sync="props.item.iron"/>
</template>
<v-data-table>
</template>
Else, you will get a vue error "you should not mutate an prop directly"
<template v-slot:items="props">.
for this eazy right is
<template v-slot:items="{ item }">
<my-component
{{item. protein}}

custom component/template not showing

After playing around with Aurelia for a while, i'm trying to creating a custom component/template. However with below minimal code i still cant seem to show the message that is in testcomponent.html. I see the <testcomponent></testcomponent> in html DOM, however not the message test. What am i doing wrong?
integrationcomponent.html
<template>
<require from="./forms/testcomponent"></require>
<h1>first page</h1>
<testcomponent></testcomponent>
</template>
testcomponent.js
export class TestComponent {
constructor() {
}
}
testcomponent.html
<template>
<p>test</p>
</template>
The classname is TestComponent; this tells Aurelia to look for test-component.html and test-component.js.
I think you can rename the class to 'Testcomponent' as well.
Aurelia is Convention over Configuration so you need to know the conventions.
Aren't there any error messages in the console?

Using a component containing other components within a router-view in Vue.js

I am trying to build a layout using single-file components in Vue.js, with dynamic population and URLs using Vue-router. (I'm using the webpack template via vue-cli as well.)
It works as expected for my app.vue file-- containing the nav, sidebar, page head, and <router-view>-- and the <router-view> content appeared as expected when the correct <router-link> is clicked... until I tried to add subcomponents to the add-load component being called to the <router-view>. Now, nothing appears at all, despite not throwing any errors.
Admittedly, I am not basing my structure on any examples, as I couldn't really find any doing it the way I was hoping to. I wanted to use nested components by calling them like custom elements-- I think this makes the code much easier to read and maintain. I'm not entirely sure how to structure it otherwise, to be honest. Using multiple <router-view>s as siblings to each other seems counterintuitive to me.
I've tried a variety of combinations of how and where to import and call the components, and nothing has worked. The only way I can get any content to load is if I only call a single component for path: '/add-load'. Is it just impossible to use multiple components outside of your base app.vue? I find that hard to believe. Here's what I started with.
From my index.js:
import AddLoad from '#/components/AddLoad'
import AddLoad from '#/components/ProgressSteps'
import Stops from '#/components/Stops'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
components: {
Sidebar,
TopNav,
MobNav,
PageHead
}
},
{
path: '/add-load',
components: {
AddLoad,
ProgressSteps}
}
]
})
From my App.vue file (the multiple component behavior that I'd like to mimic is shown here):
<template>
<div id="app">
<div class="wrapper">
<Sidebar/>
<div class="container-fluid">
<TopNav/>
<MobNav/>
<div class="container-fluid">
<PageHead/>
<router-view></router-view>
</div>
</div>
</div>
</div>
</template>
<script>
import Sidebar from '#/components/Sidebar'
import TopNav from '#/components/TopNav'
import MobNav from '#/components/MobNav'
import PageHead from '#/components/PageHead'
export default {
name: 'App',
components: {
Sidebar,
TopNav,
MobNav,
PageHead
}
}
</script>
From my AddLoad.vue file:
<template>
<div class="add-load">
<div class="content-container container-slim">
<progress-steps/>
<router-link to="#stops">Stops</router-link>
<router-view></router-view>
</div>
</div>
</template>
<script>
import ProgressSteps from '#/components/ProgressSteps'
export default {
name: 'AddLoad',
component: ProgressSteps
}
</script>
Here is a link to a codesandbox, so you can see the full functionality. https://codesandbox.io/s/7k520xk0yq

Categories

Resources