Задать вопрос
  • Почему не добавляется новое свойство экземпляра vue?

    ShadowOfCasper
    @ShadowOfCasper Автор вопроса
    0xD34F, кроме того, открой документацию, работать должно и через свойство, и через прототип
  • Почему не добавляется новое свойство экземпляра vue?

    ShadowOfCasper
    @ShadowOfCasper Автор вопроса
    0xD34F, да кидал я его в прототип, вот, наглядно:
    точка входа
    import Vue from 'vue'
    import App from './App.vue'
    import router from './router'
    import store from './store'
    import ElementUI from 'element-ui'
    import i18n from './utilities/i18n'
    import ajax from './utilities/ajax'
    import locale from 'element-ui/lib/locale/lang/ru-RU'
    import 'element-ui/lib/theme-chalk/index.css'
    import './assets/fonts.scss'
    import './assets/tailwind.css'
    Vue.config.productionTip = false
    Vue.use(ajax)
    Vue.use(ElementUI, { locale })
    
    const app = new Vue({
      router,
      store,
      i18n,
      render: h => h(App)
    }).$mount('#app')
    // app.$ajax = new Ajax()
    store.$app = app
    
    console.log(app)


    Плагин
    import axios from 'axios'
    class Ajax {
      constructor () {
        console.log('ok')
        this.baseURL = 'http://localhost:3000/'
        this.token = ''
        const token = localStorage.getItem('token')
        if (token && token.length) this.setToken(token)
      }
    
      setToken (value = '') {
        this.token = value
      }
    
      get (url, params, onSuccess, onError, onFinish) {
        axios({
          baseURL: this.baseURL,
          url,
          method: 'GET',
          data: params,
          headers: { token: this.token }
        }).then((resp) => {
          if (typeof onSuccess === 'function') onSuccess(resp)
        }).catch(error => {
          if (typeof onError === 'function') onError(error)
        }).finally(() => {
          if (typeof onFinish === 'function') onFinish()
        })
      }
    
      post (url, params, onSuccess, onError, onFinish) {
        axios({
          baseURL: this.baseURL,
          url,
          method: 'POST',
          data: params,
          headers: { token: this.token }
        }).then((resp) => {
          if (typeof onSuccess === 'function') onSuccess(resp)
        }).catch(error => {
          if (typeof onError === 'function') onError(error)
        }).finally(() => {
          if (typeof onFinish === 'function') onFinish()
        })
      }
    }
    export default {
      install (Vue, options) {
        console.log('Installing the plugin!')
        Vue.prototype.$ajax = function () {
          return new Ajax()
        }
        // Object.defineProperty(Vue, '$ajax', new Ajax())
      }
    }
    
    // export default Ajax

    НЕ РАБОТАЕТ ДАЖЕ ЧЕРЕЗ ПРОТОТИП!
    Будь всё так просто я бы не задавал тупых вопросов
    Как будто я просто так выбрал тип вопроса сложный, и ни разу до этого плагин не создавал. Хватит меня за идиота держать. Не знаешь ответ - иди по своим делам
  • Почему не добавляется новое свойство экземпляра vue?

    ShadowOfCasper
    @ShadowOfCasper Автор вопроса
    0xD34F, естественно, если ты знаешь javascript, то должен понимать, что дальнейшие попытки вызова методов инстанса класса аякса приведут к ошибкам, откуда бы я его ни вызывал - это не важно
  • Почему не добавляется новое свойство экземпляра vue?

    ShadowOfCasper
    @ShadowOfCasper Автор вопроса
    0xD34F, вообще-то показал. В main.js в конце файла лог инстанса приложения. Там должен быть $ajax в свойствах / прототипе (смотря куда положил), но его нет
  • Почему не добавляется новое свойство экземпляра vue?

    ShadowOfCasper
    @ShadowOfCasper Автор вопроса
    Работает, если объявить свойство после создания инстанса приложение, а из плагина экспортировать класс вместо инстанса плагина.
    const app = new Vue({
      router,
      store,
      i18n,
      render: h => h(App)
    }).$mount('#app')
    app.$ajax = new Ajax()
    store.$app = app


    Но это быдлокод, меня такое не устраивает
  • Почему не добавляется новое свойство экземпляра vue?

    ShadowOfCasper
    @ShadowOfCasper Автор вопроса
    Не работает. И через defineProperty не работает
  • Что-то типо phpMyAdmin для node.js и mysql?

    ShadowOfCasper
    @ShadowOfCasper
    лол конечно, но если сейчас погуглить nodejs myadmin - первая страница выдачи - именно эта страница с твоим перенаправлением на запрос, где первая страница выдачи - требуемый npm пакет
  • Почему при обновлении стейта родителя дочка ререндерится вместо обновления?

    ShadowOfCasper
    @ShadowOfCasper Автор вопроса
    camelCaseVlad, просто я к чему это всё - описание этого антипаттерна не говорит ни о каких технических накладках, которые могут всплыть в результате образования ссылки в state на props и тому подобное. Оно просто выразило мнение разработчиков реакта, почему вот именно они не хотят чтоб так делали. Мне глубоко похер на их мнение - мне нужно сделать работу и я делаю её так, как умею и привык. Уже битый час я ковыряю гугл чтоб понять есть ли какие-то технические накладки с такого подхода. Потому что мои common компоненты полны такой логики и без неё в некоторых местах (один я описал выше) работают криво. Возможно ли что эти ре-рендеры связаны с этим подходом
  • Почему при обновлении стейта родителя дочка ререндерится вместо обновления?

    ShadowOfCasper
    @ShadowOfCasper Автор вопроса
    camelCaseVlad, о том что это нереальный бред

    Using props to generate state in getInitialState often leads to duplication of “source of truth”, i.e. where the real data is. This is because getInitialState is only invoked when the component is first created.

    можно описывать часами. Я в корне не согласен с разработчиками реакта. С Vue пропы для меня никогда не были source of truth - лишь изначальной - default value. Что если ты сам для себя в голове воспринимаешь state как единственный источник правды? У меня уже были кейсы, при которых, к примеру инпуты в модалке не работали то тех пор, пока я не сколотил из props initial state и не эмитил его из инпута. Ах да у вас в реакте нет эмиттера. Ну вы поняли о чем я. По итогу антипаттерн спас от бага, который всплыл когда я всё сделал казалось бы правильно.
    Короче я буду критичен - реакт говно. Это мой первый последний проект на нём. Скорость разработки настолько медлительна и нервозна, что меня посещает научный интерес, не проще ли было описать интерфейс ванильным js...
  • Почему при обновлении стейта родителя дочка ререндерится вместо обновления?

    ShadowOfCasper
    @ShadowOfCasper Автор вопроса
    camelCaseVlad, блин а я так делаю. Но что если ты пропами суёшь в дочу здоровенный объект, изменений в котором не избежать и эти изменения нужно вносить методами дочки? Как тогда быть? Всё равно придётся как-то из пропы при инициализации сколотить стейт
  • Почему при обновлении стейта родителя дочка ререндерится вместо обновления?

    ShadowOfCasper
    @ShadowOfCasper Автор вопроса
    camelCaseVlad,
    Сорри, начальную стейт как проп в чайлд - это антипатерн

    Какие есть варианты? И странно - я не читал ничего такого когда готовился к писанине на этой упоротой либе. Ну слышал про defaultProps - я прокидываю пустые объекты и начальные значения если стейт в null или undefined и это выглядит как
    <Component prop={this.state.key || {}} .../>
    Это правильно? Может в этом косяк?
  • Почему при обновлении стейта родителя дочка ререндерится вместо обновления?

    ShadowOfCasper
    @ShadowOfCasper Автор вопроса
    camelCaseVlad, ну вот я сократил,
    setWizardState(data) {
            Object.keys(data.steps).forEach(stepKey => {
                data.steps[stepKey]['forcedOpen'] = false;
            });
            this.setState({wizard: {active: true, steps: data.steps}}, () => {
                if (this.state.wizard.steps.company.status === 'next') {
                    this.lockTab('company')
                };
                this.requestDataByRoute();
            })
        }

    Ну и что что выглядит это приятнее. Работает оно всё равно паршиво
  • Почему при обновлении стейта родителя дочка ререндерится вместо обновления?

    ShadowOfCasper
    @ShadowOfCasper Автор вопроса
    camelCaseVlad, не, PureComponents точно не вариант. Уже пытался. Всё стало только хуже
  • Почему при обновлении стейта родителя дочка ререндерится вместо обновления?

    ShadowOfCasper
    @ShadowOfCasper Автор вопроса
    camelCaseVlad, то есть передавать стейт из родителя как проп в дочь - это антипаттерн? Стоп, а как надо?
  • Почему при обновлении стейта родителя дочка ререндерится вместо обновления?

    ShadowOfCasper
    @ShadowOfCasper Автор вопроса
    Ещё интереснее, я начал сетстейтать, закидывая в функцию вместо колбэка готовый новый объект. why did you render перестал сообщать о ре-рендере, но логи компонента маркетплейса - первый таб настроек - всё равно говорят о том, что компонент ре-рендерится каждый раз при сетстейте в родителе
  • Почему при обновлении стейта родителя дочка ререндерится вместо обновления?

    ShadowOfCasper
    @ShadowOfCasper Автор вопроса
    camelCaseVlad Значит я просто не понимаю как сетстейтить в реакте. Я постоянно спотыкаюсь на то что у меня каких-то хуках prev с текущим стейты с пропами одинаковы и вот эта лажа тоже говорит о кривых сетстейтах.
    Компоненты у меня здоровые, я использую как правило колбэк для изменения стейта, забираю этот стейт в колбэке, как-то видоизменяю и возвращаю его заассайненую версию.
    Вот, к примеру метод сета состояния визарта после запроса с сервера:
    setWizardState(data) {
            // выставил доп ключи, которые не нужны на сервере
            Object.keys(data.steps).forEach(stepKey => {
                data.steps[stepKey]['forcedOpen'] = false;
            });
            console.log('old state: ', Object.assign({}, this.state))
            if (this.state.wizard.steps !== data.steps) {
                this.setState(state => {
                    state.wizard.steps = data.steps;
                    state.wizard.active = true;
                    return Object.assign({}, {wizard: state.wizard})
                }, () => {
                    console.log('new state: ', Object.assign({}, this.state))
                    if (this.state.wizard.steps.company.status === 'next') {
                        // если следующий таб в визарде next, я лочу ссылку на него
                        this.lockTab('company')
                    };
                    // запрос к настройкам текущего таба, которые попадут в его компонент пропсом
                    this.requestDataByRoute();
                })
            }
        }

    Интересно что несмотря на assign логи возвращают мне ссылки на текущий стейт.
    Но блин, как тогда скопировать объект возвращаемый из setState полностью? Там же туча вложенностей.
    Ну или вот к примеру, закрытие и открытие окна визарда - я возвращаю только wizard в сетстейте. Какого он мне обновил весь текущий компонент включая те что получают пропы из табов (которые пососедству с wizard)
    toggleWizard(value) {
            this.setState(state => {
                state.wizard.active = value;
                return {wizard: state.wizard}
            })
        }

    Писал на вью беды не знал, дёрнул меня чорт подписаться на проект на реакте......
  • Где двусторонний дата-биндинг?

    ShadowOfCasper
    @ShadowOfCasper Автор вопроса
    Дольше писать компоненты. Много "лишнего" кода. Но и проще тоже становится


    Сергей Сунцев, вы сами себе противоречите. В большой команде и сложных проектах простота и читаемость кода превыше всего - а реакт крайне свободомысленный фрейм. Большие команды - я убедился на собственном опыте - всегда выбирают ангуляр. Ибо на каждый чих своя строго задекларированная салфетка, ещё и полная поддержка ts из коробки. А чем шаблоннее прогры больших проектов пишут код, тем легче искать им замену, подхватывать эстафету ну и так далее
  • Можно ли отрендерить реакт-компонент императивно?

    ShadowOfCasper
    @ShadowOfCasper Автор вопроса
    Роман Александрович, Bingo!
    https://ru.reactjs.org/blog/2015/10/01/react-rende...
    И это работает. Для императивного вызова пришлось создать отдельный класс, который как я и думал не будет наследовать реакт. Его основное отличие в том, что рендер вызывается в конце конструктора. Объединить их уже не выйдет, но и не страшно. Всё равно у обоих обёрток разная цель применения
    class AlertCaller {
        constructor(options) {
            this.state = {
                children: options.textError
            }
            this._render();
        }
        
        _render() {
            console.log(this.state)
            ReactDOM.render(
            <Alert {...this.state} />,
            document.getElementById("alerts")
            );
        }
        destroy() {
            ReactDOM.unmountComponentAtNode(this._container);
        }
    }

    Ну и AlertRenderer остался для вызова алертов, завязаных на стейт приложения.
  • Можно ли отрендерить реакт-компонент императивно?

    ShadowOfCasper
    @ShadowOfCasper Автор вопроса
    Роман Александрович, реакт вставил палку в колесо.
    Запорталить можно только в рендер-функции. Если я сохраняю new AlertRenderer в переменную, он не вызывает render-функцию, и forceUpdate я выполнить не могу.
    // тот самый
    class AlertRenderer extends React.Component {
        constructor(props) {
            super(props)
            this.state = {...props}
        }
        /*
        options
            errorText - string
        */
        setNewAlert(options) {
            this.setState(state => {
                state.children = options.errorText
                state.warning = true;
                return Object.assign({}, state)
            }, () => {
                this.forceUpdate()
            })
        }
        render() {
            return ReactDOM.createPortal(<Alert {...this.props}/>, document.getElementById("alerts"));
        }
    }

    Я попытался вручную его зарендерить, но реактДОМ жалуется
    const alert = new AlertRenderer();
    document.getElementById('alerts').innerHTML = alert.render();
    // получил Uncaught Invariant Violation: Target container is not a DOM element. от reactDOM
  • Можно ли отрендерить реакт-компонент императивно?

    ShadowOfCasper
    @ShadowOfCasper Автор вопроса
    Роман Александрович, ну это какой-то лихой топорик, но можно копнуть и в его сторону. Попробую создать метод в рендерере алерта, через который прокину в алерт нужные пропы и вызову этот forceUpdate. Отпишусь как получится