Vue的核心技术
MVVM思想
-
M->model 模型
- 通过VM绑定视图
-
V->view 视图
- 通过VM监听模型
-
VM-> vue实例对象(模型和视图通过它进行数据的绑定和渲染)
Vue可以访问哪些属性,Vue属性命名规范
-
vue本身属性,data数据
-
命名规范
-
不能以$或者_开头
- $->vue的公开访问属性
- _->vue的(私有)属性一般不访问
-
Vue的数据绑定机制
- 通过代理模式实现,Object.defineProperty()方法给Vue实例对象增加属性;
- 访问时,底层通过get方法访问被代理对象的属性
- 赋值时,底层通过set方法给被代理对象的属性赋值
简单实现Vue的数据绑定机制
-
const vm = new Vue({ data:{ name: '张三', age: 17 } })实例化
-
编写Vue类(ES6新特性)
-
class Vue{ constructor(options){ // 通过Object.keys获取某个对象{}的全部属性名 const propertyNames= Object.keys(options.data); propertyNames.foreach(propertyName=>{ // 给vue 添加属性 // 遍历options中的属性 // 1. this->表示Vue // 2. propertyName ->需要代理的属性 // 3. {}-> get set 当通过vue获取/修改值时,触发的函数 // 注意->读值时,需要用data[key] 类[属性名] Object.defineProperty(this,propertyName,{ get(){ return options.data[propertyName]; }, set(val){ options.data[propertyName] = val; } }) }) } }
-# Vuex插件的使用
-
网址
https://vuex.vuejs.org/zh/ -
用于多个组件之间共享的数据store
-
相当于vm和所有vc共享该属性store
-
安装
-
npm i vuex@3 vue2安装 -
npm i vuex@4 vue3安装
-
核心配置项
- actions
- 用于处理业务逻辑的action
- mutations
- 用于更新state的mutation
- state
- 存储共享属性
- getters
- 相当于计算属性一样使用
- module
入门案例(vue2)
目标:实现一个按钮,点击一次数字加1
1. 安装vuex
npm i vuex@2
2. 创建vuex目录和store.js

3. 编写store.js
// 引入vue插件。使用vuex插件时,需要vue
import Vue from 'vue'
// 引入vuex插件
import Vuex from 'vuex'
Vue.use(Vuex)
// 创建三个对象 actions mutations state
// 处理业务逻辑,一个个回调函数
const actions = {
// context vuex的上下文,相当于一个压缩版的store
// value 组件传递过来的参数
plusOne(context,value){
// 业务逻辑
// ....
// 也可以通过context进行分发
// context.dispatch('otherAction',value);
// 继续下一个环节,action已经完成了自己的工作,下一个工作由其他(人)来做
// 通过context提交数据,由其他人进行更新
// 提交到mutations中的某个mutation,加上value
value = value+1
context.commit('PULS_ONE',value)
}
}
const mutations = {
// state 需要更新的数据,
//value 值
PULS_ONE(state,value){
state.num += value
}
}
// 数据对象,做了响应式处理
const state = {
num:0
}
// 创建store对象
const store = new Vuex.Store({
// 负责执行某个行为的对象
actions:actions,
// 负责更新的对象
mutations:mutations,
// 状态对象
state:state
})
// 暴露Store对象
export default store;
// 简写形式
// export default new Vuex.Store({actions,mutations,state})
4. APP组件中使用
<template>
<div id="app">
<h1>数字:{{$store.state.num}}</h1>
<button @click="plusOne">点我加一</button>
</div>
</template>
<script>
export default {
name: 'App',
components: {
},
data(){
return{
startNum :0
}
},
methods:{
plusOne(){
// 这里,这个函数只需要调用vuex的dispatch分发API,完成代码的复用
// dispatch('action',传递的参数), action--->actions中的某个回调函数
this.$store.dispatch('plusOne',this.startNum)
}
}
}
</script>
<style>
vuex的工作原理
Map简化开发
通过这个可以简化开发
- ...mapState
- ...mapMutations
- ...mapActions
- ...mapGetters
ES6扩展运算符...
... 该运算符可以将一个数组或者对象去掉[]、{}
-
数组
let a =[1,2,3,4,56,7,8] ...a => 1 2 3 4 56 7 8 let b = { x:1, y:2 } // 此时,对象c拥有b中的所有属性,但b和c不是同一个对象 // {...b} 可以构建出一个新的对象 let c = {...b} // 可以给某个对象添加其他对象的属性 let d = { k:3, ...b, v:4, }使用数组时需要方法名一致,对象则不考虑
模块化开发
-
将每个业务分成一个个模块,例如A模块,B模块
-
每个模块都有自己的actions,mutations,state
-
通过mouble配置项完成注册
a模块 export default { // 开启命名空间 namespace: true, acitons:{...}, mutations:{...}, getters:{...} }// 创建store对象 const store = new Vuex.Store({ modules:{ a : aModule, b : bModule } }) -
访问时需要指定模块
- this.$store.state.模块名.属性
-
开启命名空间后,可以访问指定的actions等
['a/dosome'] -
访问getters计算属性时
this.$store.getters['a/reservedName']
注意:使用map简化时,注意一下几点
-
命名空间是否开了?
-
namespaced: true,
-
-
获取对应东西时,要加上命名空间
-
computed:{ ...mapState('a', ['users']), ...mapGetters('a',['userLength']), ...mapGetters('b',['vipLength']) }, methods:{ ...mapActions({addUser:'a/saveUser'}), // 另一种写法,需要回调函数与store中函数名一致 // ...mapActions('a',['saveUser']) } -
两种写法
-
//第一种适用于导入多个 methods:{ ...mapMutations('b',{addVip:'SAVE_VIP'}) } //第二种适用于导入单个 methods:{ ...mapActions({addUser:'a/saveUser'}),