Vue3 import variable from laravel to props form - vue.js

Good morning, I'm new to vue3 and I want to understand how I could put a laravel variable in a form props, for example, in my component vue template i have that code
<td>{{works.name}}</td>
And also i have form
setup() {
const form = useForm({
name: 123,
});
And me need instead of '123' insert {{works.name}}, how i can make it ?
I tried like this but it doesn't work
setup() {
const form = useForm({
name: works.name,
});
I receive \works\ in my component like this
return Inertia::render('MyWork',
['works' => $works]);
Sorry for stupid question..

Related

Vue component not showing updated Vuex data

I realise this is a common issue with people new to vue and vuex, but I've been using it for two years now and thought I understood the ins and outs. Yet I'm stumped. There must be something I'm overlooking.
We've got a couple of complex models that used to have layouts hard-coded in the front end, and now some of those come from the backend instead, so I added a store module to handle that:
import { ActionTree } from 'vuex';
import { RootState } from '#/store';
import request from '../../services/request';
import layouts from '../../layouts';
export const types = {
FETCH_LAYOUT: `${MODULE_NAME}${FETCH_LAYOUT}`,
};
const initialState = {
layout: layouts,
};
const actions: ActionTree<LayoutState, RootState> = {
async [FETCH_LAYOUT]({ commit, state }, id) {
if (!state[id]) {
const layout = await request.get(`layout/${id}`);
commit(types.FETCH_LAYOUT, { layout, id });
}
},
};
const mutations = {
[types.FETCH_LAYOUT](state: any, { layout, id }) {
state.layout[id] = layout;
},
};
export default {
namespaced: true,
state: initialState,
getters: {},
actions,
mutations,
};
Everything here seems to work fine: the request goes out, response comes back, state is updated. I've verified that that works. I've got two components using this, one of them the parent of the other (and there's a lot of instances of the child). They're far to big to copy them here, but the import part is simply this:
computed: {
...mapState({
layout: (state: any) => {
console.log('mapState: ', state.layout, state.layout.layout[state.modelName]);
return state.layout.layout[state.modelName];
},
}),
},
This console.log doesn't trigger. Or actually it looks like it does trigger in the parent, but not in the children. If I change anything in the front-end code and it automatically loads those changes, the child components do have the correct layout, which makes sense because it's already in the store when the components are rerendered. But doing a reload of the page, they lose it again, because the components render before the layout returns, and they somehow don't update.
I'm baffled why this doesn't work, especially since it does seem to work in the parent. Both use mapState in the same way. Both instantiate the component with Vue.component(name, definition). I suppose I could pass the layout down as a parameter, but I'd rather not because it's global data, and I want to understand how this can fail. I've considered if maybe the state.layout[id] = layout might not trigger an automatic update, but it looks like it should, and the parent component does receive the update. I originally had state[id] = layout, which also didn't work.
Using Vue 2.6.11 and Vuex 3.3.0

Vue loses prototypes and imported files when creating new component

When extending a Vue component to a modal, a new Vue instance is generated. This leads to losing all pre-imported helpers/ Vuex-stores etc.
Is there a way how to copy all data to the new extended Vue component?
To make it clear, have a look at this jsfiddle.
It confronts you with an alert. When you click on the button, the modal is opened. But if you look at my code, another alert should be fired. But $hi() is not available in the other Vue instance.
I create a component like this:
const createComponent = (props) => {
const wrapper = document.createElement('div');
const Component = Vue.extend(MyComponent);
return new Component({
propsData: {
props,
},
}).$mount(wrapper);
};
I'm using SweetAlert as a modal.
So I add this like:
swal({
content: createComponent(props).$el,
})
If you move the line
Vue.prototype.$hi = () => alert('hi');
above
let component = new TestComponent().$mount(wrapper)
it will work. Your first component references $hi() before it's defined.

Nuxt send data between 2 components

welcome to this topic. i recently tried to use the Nuxt framework to make my web-application but i ran into a problem.
In my default layout i have two components. a header component and a sidebar component. if i click on the hamburger icon in the header component the sidebar needs to get smaller or bigger depending on the hamburger icon state (true or false)
so to make it more complicated i don't want to use a prop to send it through the other component. i want to make it as a template so people can use it easy. can i transform a local component variable to a global variable other components can use?
so the code i have now is like this:
this is the index page
this is the header component
this is the sidebar component
as you can see i trigger the hamburgerstate on the header component page.
i want to access that state in the sidebarcomponent to so i can adjust the sidebar
the one thing that's IMPORTANT is that it needs to be as simple as possible so people who use this template later don't have to add unnecessary work
any possibilities this can work?
The simplest way to achieve a global variable is to set it as a state element and have a mutation for changing it. As your 'hambuger' is a boolean there is no need to pass parameters to the mutation making it all the easier.
You may want to have a named module in you store to handle this but I'll just put it in store/index.js for now.
export const state = () => ({
hamburger: true
})
export const mutations = {
changeHamburger (state) {
state.hamburger = !state.hamburger
}
}
Then in any page or component you can access that state element:
Component.vue
<script>
import { mapMutations } from 'vuex'
export default {
computed: {
hamburger () {
return this.$store.state.hamburger
}
},
methods: {
...mapMutations({
hamburgerChange: 'changeHamburger'
})
}
}
</script>
So this means you can now use the computed property 'hamburger' in your component and can change it by calling 'hamburgerChange', eg <v-btn #click="hamburgerChange">.

How to access props data?

I have an PHP var used in a blade template and want to pass it to a vue's method.
I'm still learning so sorry if it seems obvious but I read the docs but found noting useful.
So I have this piece of code in my HTML
<chat-messages :messages="messages" :surgery_id="{{ $surgery->id }}"></chat-messages>
And in my JS
Vue.component('chat-messages', require('./components/ChatMessages.vue'));
const app = new Vue({
el: '#chat',
methods: {
fetchMessages() {
axios.get('/messages/').then(response => {
this.messages = response.data;
});
},
}
});
And I want to use something like axios.get('/messages/' + surgery_id).then(...)
But I can't figure out how to retrieve this surgery_id variable
In my ChatMessages.vue, I well created the properties
<template>
//Stuff to loop & display
</template>
<script>
export default {
props: ['messages' , 'surgery_id']
};
</script>
Use this as you do normally with the data:
axios.get('/messages/' + this.surgery_id).then(...)
You can access all the property of data option,props, and methods using this as context.
Further, if you want to use ES6, then it's even easier without concatenating them: (using tilde key `)
axios.get(`/messages/${this.surgery_id}`).then(...)
As per your query, you also need to pass props in your instance:
const app = new Vue({
// ...
propsData:{
surgery_id: 'your id value'
}
See my another post for more help.

vuejs handsontable official and calling handsontable method

I'm a beginner, this is probably more of a javascript problem than vue but anyway:
there a plugin for spreadsheet named handsontable and in the normal use you make the table by doing this
hot = new Handsontable(container, {option})
and then you can use the method like hot.loadData() etc..
To use handsontable with vuejs, there a wrapper we can find here https://github.com/handsontable/vue-handsontable-official. With the wrapper you make a table like this :
<template>
<div id="hot-preview">
<HotTable :root="root" :settings="hotSettings"></HotTable>
</div>
</template>
<script>
import HotTable from 'vue-handsontable-official';
import Vue from 'vue';
export default {
data: function() {
return {
root: 'test-hot',
hotSettings: {
data: [['sample', 'data']],
colHeaders: true
}
};
},
components: {
HotTable
}
mounted () {
localforage.config({
driver: localforage.INDEXEDDB,
name: 'matchlist-database'
})
localforage.getItem('DB').then(function (value) {
console.log('then i fetch the DB: ' + JSON.stringify(value))
if (value !== 'null') {
console.log('dB contain something')
**root**.loadData(value)
}
</script>
So it work fine when i give an array but to load the data from a DB you must call the handsontable method hot.loadData(data).
i cannot find how to call this method in vuejs i always get the error
TypeError: root.loadData is not a function
i tried with all i could think of instead of root ex: HotTable.loadData(value)
but to no avail
Can someone point me out how i would call handsontable methods from the vuejs wrapper. Or point me out what kind of reading i should do to understand my mistake. Thank a lot
There are two problems here, not bad ones :)
1st problem:
If you want to refer to your data inside Vue's methods/computed properties/watchers/lifecycle events, you should use the this keyword. If you have data: function() { return { root: "root-value" }} and you would like to console.log that "root-value" string, you should write console.log(this.root) inside your mounted handler.
If you had something like:
data: function() {
return {
hot = new Handsontable(container, {option})
....
};
You could call hot.loadData() like so:
mounted() {
this.hot.loadData();
...
}
So this refers to the Vue instance which exposes your data properties.
2nd problem:
If I understand the component wrapper correctly, you are supposed to pass data to it as props, not call any Handsontable methods directly.
<HotTable :root="root" :settings="hotSettings"></HotTable>
This means that Vue passes whatever you have as root in your data to the HotTable component. It also passes whatever you have as settings in your data. In the example, HotTable receives these:
root: 'test-hot',
hotSettings: {
data: [['sample', 'data']],
colHeaders: true
}
Now if you want to change/update/modify/add data that should be passed to the HotTable component, you should update your data in the Vue instance. You should do something like this.hotSettings = something new and this.root = something else and the HotTable component would receive those.
To understand what's really happnening with the HotTable, read all of the component documentation. Really. You will save lots of time if you read through the documentation. It all makes sense after that!
https://v2.vuejs.org/v2/guide/components.html