vue2中篇

发布于:2025-02-10 ⋅ 阅读:(87) ⋅ 点赞:(0)

今天继续和大家分享Vue2知识点

computed:

computed是 Vue 中的一种响应式特性,用于声明计算属性。它基于已有的响应式数据(如data 或props),计算并返回新的数据,具有缓存能力,从而提高性能。 

  • 性能优化computed 属性的值会被缓存,只有当它依赖的数据发生变化时才会重新计算。
  • 计算属性会缓存结果,只有当依赖的响应式数据发生变化时才会重新计算。
  • 如果依赖数据没有变化,访问计算属性时直接返回缓存值。
  • 代码简洁:避免在模板中直接写复杂的逻辑。
  • 逻辑复用:将数据处理逻辑抽离到计算属性,便于复用和维护。
<template>
  <div>
    <p>原始数据:{
  
  { num }}</p>
    <p>计算属性:{
  
  { doubleNum }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      num: 5,
    };
  },
  computed: {
    // 定义一个计算属性
    doubleNum() {
      return this.num * 2;
    },
  },
};
</script>

计算属性的读写:

计算属性默认只有getter,但也可以定义setter,从而实现双向绑定。

<template>
  <input v-model="fullName" />
</template>

<script>
export default {
  data() {
    return {
      firstName: "John",
      lastName: "Doe",
    };
  },
  computed: {
    fullName: {
      get() {
        return `${this.firstName} ${this.lastName}`;
      },
      set(value) {
        const parts = value.split(" ");
        this.firstName = parts[0] || "";
        this.lastName = parts[1] || "";
      },
    },
  },
};
</script>

watch:

数据监听和响应

最常见的使用场景是当某个数据发生变化时,需要执行一些逻辑,例如发送网络请求、更新另一个数据或执行一些计算操作。

export default {
  data() {
    return {
      searchText: '',
      searchResults: []
    };
  },
  watch: {
    searchText(newValue) {
      // 当 searchText 发生变化时,发起网络请求
      this.fetchSearchResults(newValue);
    }
  },
  methods: {
    async fetchSearchResults(query) {
      // 发送网络请求
      const results = await fetch(`/api/search?query=${query}`);
      this.searchResults = await results.json();
    }
  }
};

深度监听

当要观察的数据是一个对象或数组时,默认情况下,watch 只会观察到对象或数组的引用是否发生变化,而不会观察对象或数组内部元素的变化。如果需要深度观察对象或数组内部元素的变化,可以使用deep:true。

export default {
  data() {
    return {
      user: {
        name: '',
        age: 0
      }
    };
  },
  watch: {
    user: {
      handler(newValue, oldValue) {
        console.log('user 对象发生了变化');
      },
      deep: true
    }
  }
};

 computed和watch的区别: 

computed

  • 主要用于计算属性,根据依赖的数据自动计算出新的值。
  • 计算属性是基于它们的依赖进行缓存的,只有依赖的数据发生变化时才会重新计算。
  • 适合于根据其他数据计算出一个新的值,例如根据 firstName 和 lastName 计算出 fullName。  

watch:

  • 主要用于观察数据的变化并执行相应的操作。
  • 更侧重于执行一些异步或复杂的逻辑,例如发送网络请求、修改其他数据等

store:

store 是 Vuex 的核心概念。它本质上是一个容器,应用里的大部分状态(state)都存于其中。可以把 store 视作一个全局的状态仓库,所有组件都能够对其中的数据进行访问和修改。不过,在进行修改操作时,需要遵循特定的规则和流程,这样做是为了确保状态具备可预测性与可维护性

state: 

state是一个单一的对象,它包含了应用中所有需要共享的状态数据。在 Vuex 的设计理念里,整个应用的状态集中存放在 state 中,使得数据的管理和维护更加方便和可预测。

定义:
 

在创建 Vuex store 时,可以通过 state 选项来定义应用的初始状态。以下是一个简单的示例:

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

// 创建一个新的 store 实例
const store = new Vuex.Store({
  state: {
    count: 0,
    message: 'Hello Vuex!'
  }
});

export default store;
 

在这个例子中, state 对象包含了两个状态属性 :count 和message。

在组件中访问:
 

在 Vue 组件中,可以通过 this.$store.state 来访问 store 中的状态。以下是一个组件中使用state的示例:

<template>
  <div>
    <p>Count: {
   
   { count }}</p>
    <p>Message: {
   
   { message }}</p>
  </div>
</template>

<script>
export default {
  computed: {
    count() {
      return this.$store.state.count;
    },
    message() {
      return this.$store.state.message;
    }
  }
};
</script>
 

这里使用计算属性来获取state中的数据,这样可以在数据发生变化时自动更新视图。

使用辅助函数:

为了简化在组件中访问state的代码,Vuex 提供了mapState辅助函数。以下是使用mapState的示例:

<template>
  <div>
    <p>Count: {
   
   { count }}</p>
    <p>Message: {
   
   { message }}</p>
  </div>
</template>

<script>
import { mapState } from 'vuex';

export default {
  computed: {
    ...mapState(['count', 'message'])
  }
};
</script>
 

mapState函数接受一个数组或对象作为参数,返回一个计算属性对象。使用扩展运算符...将其展开到组件的computed选项中。

mutations:

在 Vuex 的架构中,state是存储应用状态的容器,而mutations则是唯一可以修改 state的途径。mutations本质上是一些同步的方法,之所以强调同步,是因为这样可以方便地追踪 state的变化,保证状态修改的可预测性。

定义:

在创建 Vuex store 时,可以通过 mutations选项来定义一系列的 mutations。每个 mutation都是一个函数,它接收两个参数:第一个参数是 state对象,也就是当前的状态;第二个参数是payload,即传递给这个 mutation的额外数据。

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment(state, payload) {
      // 修改 state 中的数据
      state.count += payload || 1; 
    },
    decrement(state) {
      state.count--;
    }
  }
});

export default store;
 

在上述代码中,定义了两个 mutations: increment 用于增加 count 的值,decrement 用于减少 count 的值。increment 函数接收一个可选的 payload 参数,如果传递了该参数,则将 count 增加相应的值;如果没有传递,则默认增加 1。

在组件中访问:

increment可以带参数,但是decrement不可以

<template>
  <div>
    <p>Count: {
   
   { count }}</p>
    <button @click="incrementCount">增加</button>
    <button @click="decrementCount">减少</button>
    <button @click="incrementByFive">增加 5</button>
  </div>
</template>

<script>
export default {
  computed: {
    count() {
      return this.$store.state.count;
    }
  },
  methods: {
    incrementCount() {
      // 触发 increment mutation
      this.$store.commit('increment');
    },
    decrementCount() {
      // 触发 decrement mutation
      this.$store.commit('decrement');
    },
    incrementByFive() {
      // 传递 payload 触发 increment mutation
      this.$store.commit('increment', 5); 
    }
  }
};
</script>
使用辅助函数:

为了简化在组件中触发mutations 的代码,Vuex 提供了mapMutations辅助函数。以下是使用 mapMutations 的示例:

<template>
  <div>
    <p>Count: {
   
   { count }}</p>
    <button @click="increment">增加</button>
    <button @click="decrement">减少</button>
  </div>
</template>

<script>
import { mapMutations } from 'vuex';

export default {
  computed: {
    count() {
      return this.$store.state.count;
    }
  },
  methods: {
    ...mapMutations(['increment', 'decrement'])
  }
};
</script>

在 Vuex 中,action 是用于处理异步操作的重要概念,它和 mutations配合,使得我们可以更灵活地管理应用的状态。下面从多个方面详细介绍 action。

action:

mutations只能进行同步操作,因为只有这样才能保证状态变化的可追踪性。但在实际开发中,很多时候需要进行异步操作,比如发送网络请求、设置定时器等,这时就需要用到 actionaction可以包含任意异步操作,并且通过触发 mutations来间接修改 state。 

定义:

在创建 Vuex store 时,可以通过 actions选项来定义一系列的 actions。每个 action都是一个函数,它接收一个上下文对象 context 作为第一个参数,这个 context 对象包含了和 store 实例几乎相同的方法和属性,例如commit(用于触发mutations)、state(当前状态)、getters等;第二个参数是payload,即传递给这个 action的额外数据。

 
import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment(state) {
      state.count++;
    }
  },
  actions: {
    incrementAsync(context) {
      // 模拟异步操作,例如网络请求
      setTimeout(() => {
        // 触发 mutations 来修改 state
        context.commit('increment');
      }, 1000);
    },
    incrementByAmount(context, payload) {
      setTimeout(() => {
        for (let i = 0; i < payload; i++) {
          context.commit('increment');
        }
      }, 1000);
    }
  }
});

export default store;
 

在上述代码中,定义了两个 actions:incrementAsync用于异步增加 count 的值,通过setTimeout 模拟了一个 1 秒后的异步操作,然后触发 increment mutation;incrementByAmout 接收一个 payload 参数,用于指定要增加的次数,同样在 1 秒后多次触发increment mutation

在组件中访问:

在组件中,可以使用 this.$store.dispatch 方法来触发 actions。

 
<template>
  <div>
    <p>Count: {
   
   { count }}</p>
    <button @click="incrementAsync">异步增加</button>
    <button @click="incrementByAmount">异步增加 5</button>
  </div>
</template>

<script>
export default {
  computed: {
    count() {
      return this.$store.state.count;
    }
  },
  methods: {
    incrementAsync() {
      // 触发 incrementAsync action
      this.$store.dispatch('incrementAsync');
    },
    incrementByAmount() {
      // 传递 payload 触发 incrementByAmount action
      this.$store.dispatch('incrementByAmount', 5);
    }
  }
};
</script>
 

在这个组件中,通过点击不同的按钮来触发不同的 actions:incrementAsync方法触发 incrementAsync action;incrementByAmout 方法触发 incrementByAmout action并传递payload为 5。

使用辅助函数:

为了简化在组件中触发 actions的代码,Vuex 提供了mapActions 辅助函数。

 
<template>
  <div>
    <p>Count: {
   
   { count }}</p>
    <button @click="incrementAsync">异步增加</button>
    <button @click="incrementByAmount(5)">异步增加 5</button>
  </div>
</template>

<script>
import { mapActions } from 'vuex';

export default {
  computed: {
    count() {
      return this.$store.state.count;
    }
  },
  methods: {
    ...mapActions(['incrementAsync', 'incrementByAmount'])
  }
};
</script>
getter:

state存储着应用的状态数据,但有时候我们需要对这些数据进行一些处理或计算后再使用,这时就可以使用 getter。getter会根据 state的数据计算出一个新的值,并且具有缓存特性,只有当依赖的 state数据发生变化时,getter才会重新计算。

定义:

在创建 Vuex store 时,可以通过 getters  选项来定义一系列的 getters 。每个 getter都是一个函数,它接收 state作为第一个参数,还可以接收其他 getters 作为第二个参数,方便在 getter之间进行相互调用。

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

const store = new Vuex.Store({
  state: {
    todos: [
      { id: 1, text: '学习 Vuex', done: true },
      { id: 2, text: '练习项目', done: false }
    ]
  },
  getters: {
    // 获取已完成的 todos
    finishedTodos(state) {
      return state.todos.filter(todo => todo.done);
    },
    // 获取已完成 todos 的数量,这里使用了其他 getter
    finishedTodosCount(state, getters) {
      return getters.finishedTodos.length;
    }
  }
});

export default store;
在组件中访问:
 

在 Vue 组件中,可以通过this.$store.getters 来访问 store 中的 getters 。

 
<template>
  <div>
    <p>已完成的 todos 数量: {
   
   { finishedTodosCount }}</p>
    <ul>
      <li v-for="todo in finishedTodos" :key="todo.id">{
   
   { todo.text }}</li>
    </ul>
  </div>
</template>

<script>
export default {
  computed: {
    finishedTodos() {
      return this.$store.getters.finishedTodos;
    },
    finishedTodosCount() {
      return this.$store.getters.finishedTodosCount;
    }
  }
};
</script>
 

这里使用计算属性来获取 getters 中的数据,这样可以在数据发生变化时自动更新视图。

使用辅助函数:
 

为了简化在组件中访问getters 的代码,Vuex 提供了mapGetters 辅助函数。

<template>
  <div>
    <p>已完成的 todos 数量: {
   
   { finishedTodosCount }}</p>
    <ul>
      <li v-for="todo in finishedTodos" :key="todo.id">{
   
   { todo.text }}</li>
    </ul>
  </div>
</template>

<script>
import { mapGetters } from 'vuex';

export default {
  computed: {
    ...mapGetters(['finishedTodos', 'finishedTodosCount'])
  }
};
</script>
 

mapGetters 函数接受一个数组或对象作为参数,返回一个计算属性对象。使用扩展运算符 ... 将其展开到组件的 computed 选项中。


网站公告

今日签到

点亮在社区的每一天
去签到