Немного мыслей об управлении состоянием Vue

внешний интерфейс JavaScript Vue.js Vuex
Немного мыслей об управлении состоянием Vue

Когда недавно писал проект, наткнулся на сцену: приложение карты с сайдбаром.В сайдбаре много опций.При изменении опций приложение будет запрашивать данные по условиям сайдбара,а потом отобразить его на карте Поставить маркеры. Страница может быть просто абстрагирована в следующую структуру:

// App.vue

<div>
  <sidebar></sidebar>
  <map></map>
</div>

Есть много способов выполнить вышеуказанные требования, я сначала представлю два общих метода и, наконец, дам альтернативное, но очень интересное решение.

1. Перейти непосредственно к vuex

Вообще говоря, когда есть несколько компонентов, совместно использующих состояние, хорошим решением будет оставить общее состояние vuex для обработки. Но при рассмотрении описанного выше сценария он будет казаться немного «неуклюжим», потому что боковая панель на самом деле является формой,Если вы используете vuex, вам нужно определить набор мутаций для каждой опции, теряя удобство прямого использования v-model..

Привязать параметр напрямую, используя состояние компонента

// sidebar.vue

<input v-model="message">
// ...
data () {
  return {
    message: ''
  }
} 

Когда vuex является опцией привязки, гораздо больше «шаблонного» кода

// 定义 state, mutation

state: {
  message: ''
},
mutations: {
  updateMessage (state, message) {
    state.message = message
  }
}

// sidebar.vue

<input :value="message" @input="updateMessage">
// ...
computed: {
  ...mapState({
    message: state => state.message
  })
},
methods: {
  updateMessage (e) {
    this.$store.commit('updateMessage', e.target.value)
  }
}

2. Ставим статус на родительский компонент

Если боковая панель и карта имеют общего родителя, то работать с этим способом будет гораздо проще, чем с описанным выше. Но когда наше приложение становится все больше и больше, мы, как правило, разбиваем боковую панель и карту на более мелкие компоненты, поэтому будет очень сложно передавать реквизиты подкомпонентам слой за слоем.

3. «Поделиться» состоянием компонента

Обычно мы записываем состояние в компоненте следующим образом:

// ...
data () {
  return {
     message: ''
  }
}

На самом деле мы можем отдельно извлечь объект, возвращаемый в data(){}, наружу как переменную, вот так:

const state = { message: '' }
// ...
data () {
  return state
}

Тогда при инициализации этого компонента состояние Объекты будут «реактивными» для vue, что приводит к интересной вещи: любой компонент, пока он используется в шаблоне. state.message ,когда state.message При изменении страница будет обновляться синхронно.

Зная это, мы можем записать статус сайдбара в отдельный файл и внедрить его в другие компоненты в виде модуля.Структура такая:

// state.js
export default { message: '' }


// sidebar.vue
<input v-model="state.message" />

import state from 'path/to/state.js'
// ...
data () {
  return { state }
}


// map.vue
// 在模版中使用侧边栏的状态
<div>{{ state.message }}</div>

import state from 'path/to/state.js'
// ...
data () {
  return { state }
},
created () {
  // 将侧边栏的状态作为参数去请求数据
  axios.get('/xxxx', { params: state })
}

Одним из преимуществ этого является то, что вы можете использовать состояние как «внутреннее» состояние в sidebar.vue и использовать v-модель для счастливой привязки данных.Вы также можете легко получить состояние как запрос параметра в map.vue и в В то же время вы также можете использовать `state.message` непосредственно в шаблоне map.vue.

Сделайте еще один шаг вперед

В приведенной выше схеме состояние «отзывчивости» возникает во время инициализации подкомпонентов, я надеюсь активно завершить этот шаг в какой-то момент при запуске приложения. В настоящее время вы можете использовать конструктор Vue, например:

// store.js

import state from 'path/to/state.js'

new Vue({
  data: {
    state
  }
})

Затем импортируйте store.js в основной файл main.js, и состояние будет «отзывчивым».

Суммировать

В этой статье описаны некоторые мысли о том, как управлять статусом боковой панели в этом конкретном случае, надеюсь, вы что-то для себя почерпнете после прочтения :)