标签: vue-reactivity

与像 React 这样的不可变方法相比,Vue 的反应性的优缺点是什么?

Vue 通过它的反应机制触发组件重新渲染,因此开发人员可以直接改变状态。Vue 会检测状态变化并触发组件重新渲染。

React 手动触发组件重新渲染setState,React 将区分 VDOM 以检查它是否应该重新渲染。建议开发人员不要直接改变状态,而是创建新的状态来替换原始状态,这样可以shallowEqual有效地处理原始状态和新状态。(不可变方法)。

例如,有一个状态如下:

state = { a: 1, b: 2 }

// mutate state in Vue
state.a = 3

// mutate state in React
this.setState({...state, a: 3 })
Run Code Online (Sandbox Code Playgroud)

似乎反应机制更直观,可以编写更少的代码。我想知道这两种方法之间的优缺点是什么?我应该选择哪种场景?

immutability reactjs vue.js vue-reactivity

6
推荐指数
1
解决办法
297
查看次数

Vuejs Es6 类反应性

我试图在 vuejs 中拥有一个与 es6 类关联的计算属性。我的 Vue 实例如下所示:

...
props: ['customClass'],
computed: {
    localClass: {
         get() {
             return this.customClass
         },
         set (value) {
             console.log("changed")
         }
     }
 }
 ...
Run Code Online (Sandbox Code Playgroud)

我的班级看起来像这样

class CustomClass {
    constructor () {
        this.selected = false
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我尝试做这样的事情:

this.localClass.selected = true
Run Code Online (Sandbox Code Playgroud)

但是从来没有调用过二传手,就像反应性已经丢失一样,我不明白为什么。

我也尝试:

Vue.set(this.localClass, 'selected', true)
Run Code Online (Sandbox Code Playgroud)

我将 customClass 作为 prop 传递,但即使直接在组件中创建新实例也不会改变结果。

在 vuejs 文档中,我不记得有一节讨论过 es6 类中的反应性问题,所以我想知道是否有人知道为什么以及如何使我的类具有反应性。

提前致谢

javascript ecmascript-6 vue.js es6-class vue-reactivity

5
推荐指数
1
解决办法
4478
查看次数

如何将项目推送到Vuejs中的数据对象中的数组?Vue似乎没有看到.push()方法

我试图将对象添加到我在Vue实例数据对象中声明的数组中.我可以在州的购买对象中设置值,但是当我将数据推送到订单队列数组时,不会填充空数组.该函数正在被触发,但该数组不会更新.

这是我的表格:

<form
  v-on:submit.prevent="queuePurchase"
  class="form-inline row"
  id="order-creation-form"
  method="POST"
>

  @csrf
  <autocomplete-field
    sizing="col-xs-12 col-sm-3 col-md-3"
    name="customer"
    label="Customer"
    :data="{{ json_encode($customers) }}"
    v-on:setcustomer="setCustomer($event)"
  ></autocomplete-field>

  <div class="col-xs-12 col-sm-3 col-md3 form-group d-flex flex-column align-items-start">
    <label for="phone">Product</label>
    <select
      v-model="purchase.product"
      class="form-control w-100"
      name="product"
      aria-describedby="productHelpBlock"
      required
    >
      @foreach ($products as $product)
        <option :value="{{ json_encode($product) }}">
          {{ $product->name }}
        </option>
      @endforeach
    </select>
    <small id="productHelpBlock" class="form-text text-muted">
      Select a product
    </small>
  </div>

  <div class="col-xs-12 col-sm-3 col-md-3 form-group d-flex flex-column align-items-start">
    <label for="phone">Quantity</label>
    <input
      v-model="purchase.quantity"
      type="number"
      min="1"
      name="product"
      class="form-control w-100"
      aria-describedby="productHelpBlock" …
Run Code Online (Sandbox Code Playgroud)

javascript vue.js laravel-5 vuejs2 vue-reactivity

5
推荐指数
1
解决办法
2万
查看次数

计算属性未随 props 更改而更新

当传递的 prop 对象中的嵌套属性发生更改时,我无法更新计算属性。

this.favourite通过 props 传递,但当this.favourite.selectedChoices.second.idthis.favourite.selectedChoices.first.id更改时,计算属性不会更新。

关于如何使其具有反应性的任何想法?

这是计算的属性:

isDisabled() {
  const hasMultipleChoices = this.favourite.choices.length
    ? this.favourite.choices[0].value.some(value => value.choices.length) : 
    false;

  if (hasMultipleChoices && !this.favourite.selectedChoices.second.id) {
    return true;
  } else if (this.favourite.choices.length && !this.favourite.selectedChoices.first.id) {
    return true;
  }

  return false;
}
Run Code Online (Sandbox Code Playgroud)

vue.js computed-properties vuejs2 vue-reactivity

5
推荐指数
1
解决办法
9451
查看次数

mapGetters 仅在第一次加载时出现反应性问题

我正在使用mapGettersVueX的帮助程序,但我只在页面的第一次加载时遇到了一些问题,它不是反应性的......让我告诉你:

我的 html 模板触发更改:

<input type="number" value="this.inputValue" @change="this.$store.dispatch('setInputValue', $event.target.value)">
Run Code Online (Sandbox Code Playgroud)

我的商店收到价值

{
    state: {
        appValues: {
            inputValue: null
        },
    },
    getters: {
        getInputValue: (state) => {
            return state.appValues.inputValue;
        },
    },
    mutations: {
        setInputValue(state, value) {
            state.appValues.inputValue = value;
        },
    },
    actions: {
        setInputValue(context, payload) {
            return new Promise((resolve, reject) => {
                context.commit('setInputValue', payload);
                resolve();
            });
        },
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我的组件监听商店:

import {mapGetters} from 'vuex';

computed: {
    ...mapGetters({
        inputValue: 'getInputValue',
    }),
}
watch: {
    inputValue: {
        deep: true,
        immediate: true,
        handler(nVal, …
Run Code Online (Sandbox Code Playgroud)

javascript store vue.js vuex vue-reactivity

5
推荐指数
1
解决办法
2802
查看次数

使用 Lodash.remove 通过 Vuex 突变更改状态不会在我的 Vue 组件中触发反应式重新渲染

Villager我有一个组件,它prop从父组件接收一个数组。父组件从 中提取该数组this.$store.state

return this.$store.state.villages.find(value => value.id === 0).villagers
Run Code Online (Sandbox Code Playgroud)

之后我执行this.$store.mutation提交来更改给定的数组。正如您在下面的屏幕截图中看到的那样,突变确实有效。然而,我所在的组件没有重新渲染,并且仍然显示 3 个而不是 2 个项目。

反应链似乎在某个地方被破坏了,但我无法确定到底是哪个恶魔。我认为props价值是一种反应机制。正如您在屏幕截图中看到的,它的值已更改,但 DOM 并未相应更新。

在此输入图像描述

代码摘录

我尝试提取问题的相关部分

商店/index.ts

[...]
export default new Vuex.Store({
  state: {
    villages: [
      {
        id: 0,
        name: 'Peniuli',
        foundingDate: 20,
        villagers: [
          {
            id: '33b07765-0ec6-4600-aeb1-43187c362c5a1',
            name: 'Baltasar',
            bloodline: 'Gent',
            occupation: 'Farmer'
          },
[...]
   mutations: {
       disbandVillager (state, payload) {
         const villagerId = payload.id
         const village = state.villages.find(value => value.id === 0)
         console.debug('disbanding villager:', villagerId)
         if (!_.isNil(village)) …
Run Code Online (Sandbox Code Playgroud)

javascript vue.js vuex vue-reactivity

5
推荐指数
1
解决办法
1175
查看次数

如何使 Vue 3 对象属性响应式

如何创建对象属性reactive

当我运行下面的代码时,导入的内容visible不会更改为true.

导入对象的组件:

<template>
    <div class="context">
        <span v-if="visible"> test </span>
    </div>
</template>
Run Code Online (Sandbox Code Playgroud)
<script>
import { ContextManager } from "./utils.js";
import { ref } from "vue";

export default {
    name: "context",
    setup() {
        const visible = ref(ContextManager.visible);

        return { visible };
    }
};
</script>
Run Code Online (Sandbox Code Playgroud)

向对象添加数据的其他组件:

const openContext = (e) => {
    e.preventDefault();
    ContextManager.add({
        el: e.target,
        items: contextItems
    },e );
};
Run Code Online (Sandbox Code Playgroud)

上下文管理器对象:

import { reactive } from "vue";

export const ContextManager = reactive({
    context: null,
    visible: …
Run Code Online (Sandbox Code Playgroud)

javascript vue.js vue-component vue-reactivity vuejs3

5
推荐指数
1
解决办法
5918
查看次数

使用 Composition API 设置来自 Vue3 列表的反应式表单数据的最佳方法?

在 Vue3(组合 API)中,我有一个表单组件需要填充来自数据列表组件的数据。在表单组件中执行以下操作:

<input
  v-model="formdata.formfields.FirstName"
  type="text"
/>
<input
  v-model="formdata.formfields.LastName"
  type="text"
/>
  ...
  props: {
    fields: {
      type: Object,
      default: () => ({}), 
    },
  },
  setup(props, context) {
    const formdata = reactive({
      formfields: props.fields,
    });
    
    watch(
      () => props.fields,
      (current, previous) => {
        formdata.formfields= current;
      },
      { deep: true, immediate: true }
    );
Run Code Online (Sandbox Code Playgroud)

由于不允许将 props 直接放入 v-model 中,所以我引入了该formdata变量。

然后在数据列表组件中,我将字段传递给此表单组件,如下所示,其中字段来自数据列表中的条目:

    <dataform :fields="listitemfields" />
Run Code Online (Sandbox Code Playgroud)

这可行,但我觉得有点难看。而不是这样做,formdata.formfields.FirstName我宁愿formfields.FirstName只这样做。formfields但那时我似乎无法做出那样的反应。

以下不起作用:

const formfields = reactive({});

watch(
  () => props.fields,
  (current, …
Run Code Online (Sandbox Code Playgroud)

vue.js vue-component vue-reactivity vuejs3

5
推荐指数
1
解决办法
2755
查看次数

为什么 Vue3 中的空对象不是响应式的?

当我从空对象创建 aref并随后添加对象属性时,没有反应性:

<template>
  <p>{{hello}}</p>
  <button @click="add()">Click me</button>
</template>

<script>
import {ref} from 'vue';
export default {
  name: "Test",
  setup(){
    const myData = ref({});
    return {myData}
  },
  methods: {
    add(){
      this.myData["text"] = "Hello";
      console.log(this.myData);
    }
  },
  computed: {
    hello(){
      return this.myData.hasOwnProperty("text")) ? this.myData["text"] : "no text";
    }
  }
}
</script>
Run Code Online (Sandbox Code Playgroud)

单击按钮显示myData 已更改,但计算的属性hello未更新。

也尝试过reactive({})而不是ref({})没有成功。

当我们使用诸如 之类的属性初始化 ref 时,它会起作用const myData = ref({"text": "no text"});

但为什么空对象不起作用呢?

编辑:
终于找到了问题到底是什么以及如何解决:Vue3 的反应性核心不警惕属性的Object.keys()值,而仅警惕属性的值,而空对象没有任何属性值。但是,如果计算属性定义如下,则可以使 Vue3 发出警报 …

javascript vue.js vue-reactivity vuejs3

5
推荐指数
1
解决办法
5654
查看次数

为什么当 pinia 中的状态发生变化时我的 vue 组件不更新?

我正在开发一个使用 vue 和 firebase 的网站。在身份验证部分之后,用户进入仪表板,其中有他的项目列表,这些项目是 firestore 中用户文档的子集合。

我创建了一个 pinia 存储来管理这些数据,每次使用表单创建项目或删除项目时,都会state.projects使用新的项目数组进行更新,这些项目会循环显示视图中的列表。

在视图中,我可以访问store.projects应该是反应性的吸气剂,但当我添加或删除项目时,视图中没有任何反应,但仍然会state.projects更新。

这是DashboardView.vue的代码:

 <template>
  <MainHeader mode="dashboard" />

  <main class="main">
    <div class="main__container">
      <section class="main__section">
        <div class="section__header">
          <h1 class="header__title">Projects</h1>
          <!-- <TextInput type="text" placeholder="Search" v-model="filter" /> -->
        </div>
        <div class="section__content">
          <ul class="content__list">
            <li
              v-for="project in projects"
              :key="project.id"
              class="content__item"
            >
              {{ project.id }}
              <!-- <router-link
                :to="{ name: 'ProjectView', params: { id: project.id} }">
              </router-link> -->
              <SimpleButton @click="deleteProject(project.id)" type="button" text="delete" />
            </li>
          </ul>
        </div>
        <div class="section__footer">
          <form @submit.prevent="createProject">
            <TextInput …
Run Code Online (Sandbox Code Playgroud)

vue.js vue-reactivity pinia

5
推荐指数
1
解决办法
8248
查看次数