【更新中】学习笔记:vue相关知识点

Vuex相关知识点

1、什么是Vuex?

Vuex是Vue的一个全局状态管理模块,它的作用是多个组件共享状态及数据(即当某个组件将全局状态修改时,在绑定了该状态的另一个组件也将响应)。

2、Vuex组成部分

  • state:是存储的基本数据。
  • Getters:对数据获取之前的再次编译,可以理解为state的计算属性
const getters = {
    username: state => state.user.username,
    nickname: state => {state.user.nickname = Vue.ls.get(CONSTANTS.ACCOUNT).nickName; return state.user.nickName},
};
  • Mutations:提交更改数据(使用store.commit方法更改state存储的状态)。
	this.$store.commit('mutations中对应的方法名',e.target.value)
  • Actions:actions 提交的是mutation,不是直接的去变更状态 ,它是专门进行异步操作(使用this.$store.dispatch方法)。
    Actions中的方法有两个默认参数
    context 上下文(相当于箭头函数中的this)对象
    payload 挂载参数
this.$store.dispatch('actions名称',{ XXX:xxx })

PS:因为是异步操作,一般我们在使用的时候会将异步操作封装为一个Promise对象

 editUserInfo(context,payload){
      return new Promise((resolve,reject)=>{
           context.commit('edit',payload)
           resolve()
      })
 }
  • Module:Module是store分割的模块,当状态较多时,会采用模块化管理。每个模块拥有自己的state、getters、mutations、actions。
const app = {
    state: {
        fixSiderbar: false,
        multipage: true //默认多页签模式
    },
    mutations: {
        TOGGLE_FIXED_SIDERBAR: (state, fixed) => {
            Vue.ls.set(CONSTANTS.DEFAULT_FIXED_SIDEMENU, fixed);
            state.fixSiderbar = fixed
        },
        SET_MULTI_PAGE(state, multipageFlag) {
            Vue.ls.set(CONSTANTS.DEFAULT_MULTI_PAGE, multipageFlag);
            state.multipage = multipageFlag
        }
    },
    actions: {
        ToggleFixSiderbar({commit}, fixSiderbar) {
            commit('TOGGLE_FIXED_SIDERBAR', fixSiderbar);
        },
        ToggleMultipage({commit}, multipageFlag) {
            commit('SET_MULTI_PAGE', multipageFlag);
        }
    }
};

export default app

store.js文件中

Vue.use(Vuex);
export default new Vuex.Store({
    modules: {
        app,
        ......
    },
});

PS:模块中mutations中接受的第一个参数是自身局部模块的state

  • 辅助函数:mapState、MapGetters、MapActions、mapMutations等
computed: {
   ...mapState({//相当于把state中的addRouters映射到this.mainRouters中
        mainRouters: state => state.permission.addRouters,
        permissionMenuList: state => state.user.permissionList
   })
},
...mapActions(['setSidebar']),//组件中可直接调用this.setSideBar

3、Vuex的原理:

  • 使用了Vue的混入机制,在Vue的beforeCreate钩子前混入(mixin)vuexInit,并在init中将$store属性注册到Vue中。
  • Vuex的getters:借助vue的计算属性computed实现数据实时监听。
  • Vuex的state:借助vue的data是响应式,将state存入vue实例组件的data中实现。

Vue组件常用通信方式

Vue组件简单常用的通信方式有以下几种:

1、父子通信:

  • 父向子传值:通过props;
  • 子向父传值:通过事件形式
changeMessage() {
    this.$emit("handleChange","向父组件传值");
 }
 //子组件
 <div @handleChange="changeDivMsg" ></div>
  • 父调用子方法:通过ref

    1)在子组件上定义ref=“refName”
    2)父组件的方法中使用

<test-table ref="deployTab" @selectChange="deploySelectChange"></test-table>
script>
  import TestTable from './TestTable ';
  export default {
    components: {
      TestTable
    },
    methods: {
      deploySelectChange() {//调用子组件方法
  		this.$refs.deployTab.batchStopAppDeploys(); 
      }
    }
  }
</script>

  • 子调用父方法:provide / inject; p a r e n t ; 通 过 事 件 形 式 p r o v i d e / i n j e c t : 允 许 一 个 祖 先 组 件 向 其 所 有 子 孙 后 代 注 入 一 个 依 赖 。 作 用 : 主 要 解 决 了 跨 级 组 件 间 的 通 信 问 题 , 一 般 用 于 子 组 件 获 取 父 组 件 的 状 态 。 t h i s . parent;通过事件形式 provide / inject:允许一个祖先组件向其所有子孙后代注入一个依赖。 作用:主要解决了跨级组件间的通信问题,一般用于子组件获取父组件的状态。 this. parentprovide/injectthis.parent.method(在子组件里面 this.$parent 得到的是父组件的实例)
//父组件
provide: function() {
    return {
      //给addTab定义一个getAdd的调用名称
      getParentMsg: this.getMessage,
    };
},
getMessage(id){
  if(id != null){
	console.log("调用父方法并传值:"+id)
  }
}
//子组件:
inject: ["getParentMsg"],
//子组件调用父组件的方法
<span @click="getParentMsg(1)">点击获取父组件Msg信息</span>

2、兄弟通信:eventBus(事件总线)

 EventBus:相当于所有组件共用相同的事件中心,可以向该中心发送或接收事件。

使用:
1)main.js初始化EventBus

Vue.prototype.$EventBus = new Vue()

2)通信

this.$eventBus.$emit('changeVal',value)
this.$eventBus.$on('changeVal', (e) => {
    this.val = e
})

3、跨级嵌套通信:eventBus;provide / inject等。

provide/inject

//父组件
export default {
  provide: {
    test: '测试'
  }
}
// 子组件
export default {
  inject: ['test'],
  mounted () {
    console.log(this.test);
  }
}

4、其他非父子组件传参方式

  • 使用路由:< router-link >中在query/params中传值,子组件使用this.$route.query获取
  • 本地存储localStorage
  • 状态管理Vuex

vue中computed和watch的区别

1、computed:计算属性

  • 支持缓存,只有当计算属性中依赖的一个或多个数据发生改变,才会重新进行计算。否则读取缓存中的数据。
  • 不支持异步,当computed内有异步操作时无效,无法监听数据的变化。
  • 在computed中的,属性都有一个get和一个set方法。
    当数据变化时,调用set方法。
    当需要读取当前数据时,调用get方法。
  • 监听对象可以是data和props中的属性
computed: {//进行一些简单的计算
    getMessage () {
      return this.message+'||'+this.number
    }
  }

2.watch:监听属性,一般用来监听属性的变化(也可用来监听计算属性)

  • 不支持缓存,数据发生变化会直接触发相应的操作。
  • watch支持异步
  • 监听的函数接收两个参数,第一个参数是最新的值;第二个参数是输入之前的值;
  • 监听对象可以是data、props、computed
  • 监听数据必须是data中声明过或者父组件传递过来的props中的数据,当数据变化时,触发其他操作,函数有两个参数,
      immediate:组件加载立即触发 回调函数执行,
      deep: 深度监听,为了发现对象内部值的变化,复杂类型的数据时使用,例如数组中的对象内容的改变,注意监听数组的变动不需要这么做。
      注意:deep无法监听到数组的变动和对象的新增,参考vue数组变异,只有以响应式的方式触发才会被监听到。
 watch: {
    number (newVal, oldVal) {
      console.log('number has changed: ', newVal)
    }
  }

总结:computed的话是通过几个数据的变化,来影响一个数据,而watch,则是可以一个数据的变化,去影响多个数据。

Vue生命周期钩子函数

1、什么是生命周期钩子函数

组件创建、更新、销毁三个阶段 所触发执行的函数。
在这里插入图片描述

2、Vue提供的生命周期钩子
在这里插入图片描述

  • beforeCreate: 在实例初始化之后,数据观测(data observer)和初始化事件(init event,Vue内部初始化事件)之前被调用。(el和data并未初始化)
  • created:在实例已经创建完成之后被调用。(完成了data数据的初始化,el没有)
  1. 数据观测
  2. 属性和方法的运算
  3. watch/event事件回调
  4. DOM还未生成,挂载阶段还未开始,$el 属性不可见。
  • beforeMount: 在挂载开始之前被调用(完成了el和data的初始化)
  1. 相关的render函数首次被调用。
  2. $el属性已经可见
    PS:在这时,其实el中还是显示的{{}},这里应用的虚拟DOM技术,先把坑占住了。到后面mounted挂载的时候再把值渲染进去。
  • mounted :el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。(完成了挂载)
    PS:注意mounted只会执行一次。

存在期生命周期函数:beforeUpdate、updated

只有在Vue需要改变数据时才会触发存在期的钩子函数

  • beforeUpdate: 在数据更新之前调用,虚拟DOM变化之前调用。可以在该钩子中进一步地更改状态,不会触发附加的重渲染过程。
  • updated :在数据更新和虚拟DOM重新渲染后调用。调用时,组件DOM已经更新
  • beforeDestroy:在实例销毁之前调用。实例仍然完全可用。(一般用于移除事件监听器、定时器等,避免内存泄露)
  • destroyed:在实例销毁之后调用。调用后,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用。

var、let 和const的区别

区别varletconst
是否具备块级作用域×
是否存在变量提升××
是否添加全局属性××
能否重复声明变量××
是否存在暂时性死区×
是否必须设置初始值××
能否改变指针指向×

总结:

  • var允许在声明之前使用,let和const不能在声明之前使用(变量提升)。
    PS:变量提升—无论声明在何处,都会被提升至所在作用域的顶部
console.log(a) // 正常运行,打印出 undefined
var a = 1
------------------------
console.log(b) // 报错,Uncaught ReferenceError: b is not defined
let b = 1
------------------------
console.log(c) // 报错,Uncaught ReferenceError: b is not defined
const c = 1
  • var变量可以重复声明,cost和let不能重复声明
if (true) {
    var c;
    let c; // Uncaught SyntaxError: Identifier 'c' has already been declared
}
if (true) {
    let d;
    var d; // Uncaught SyntaxError: Identifier 'd' has already been declared
}
  • 如果区块中存在let和const,则使用let、const 命令声明变量之前,该变量都是不可用的。
var tmp = 123;
if (true) {
	// TDZ 开始
	tmp = 'abc';   // ReferenceError
	let tmp;   // TDZ 结束
}
  • var和let在声明变量时,可以不用设置初始值,const必须设置。
  • var不存在块级作用域,let和const具有块级作用域。
{
    let a =10;
    var b= 8;
}
console.log(a);//ReferenceError: a is not defined
console.log(b);//1
  • const用来声明只读常量,声明的变量不可随意修改,否则会导致SyntaxError(语法错误)。

     1) 简单数据类型(数值,字符串,布尔值):值保存在变量指向的那个内存地址,因此等同于常量。
     2) 复合类型的数据(对象和数组):变量指向的是内存地址,保存的是一个指针,const只能保存这个指针地址是固定的,至于他指向的数据结构是不是可变的,就完全不能控制了。
      PS:所以说const只是保证变量名指向的地址不变,并不保证该地址的数据不变
    
const PI = 3.1415
PI = 3 // 报错,Uncaught TypeError: Assignment to constant variable.
/*不会报错,因为names1指向的地址不变,改变的只是内部数据*/
const names1 = [];
names1[0] = 1;
names1[1] = 2;
console.log(names1);
/*出错,因为变量names2指向的地址不能发生改变,应始终指向[]所在的地址,[1,4]与[6,7]不是同一个地址*/
const names2=[1,4];
names2=[6,7];   //报错
  • ES6中使用 var 和 function 声明的全局变量依旧作为全局对象的属性,使用 let, const 命令声明的全局变量不属于全局对象的属性。
var a = 10;
console.log(window.a); //10
console.log(this.a) //10
let b = 20;
console.log(window.b); // undefined
console.log(this.b) // undefined

async/await 异步操作

1、async和await介绍—基于Promise解决异步

  • async:用于申明一个function是异步的
  • await:用于等待一个异步方法执行完成

2、async的返回值

async函数返回的是一个Promise对象。

PS:

  • 由于Promise的特点是无等待,所以在没有await的情况下,会立即执行async函数并返回一个Promise
  • 如果在函数中return一个直接量,async会通过Promise.resolve( )封装成Promise对象
  • 如果函数内部抛出错误,async会通过Promise.reject()返回一个promise对象
async function timeout(flag) {
    if (flag) {
        return 'hello world'
    } else {
        throw 'my god, failure'
    }
}
console.log(timeout(true))  // 调用Promise.resolve() 返回promise 对象。
console.log(timeout(false)); // 调用Promise.reject() 返回promise 对象。

3、await的使用

1)await只能在async函数内部使用
2)await关键字后面跟Promise对象

  • await实际上等待的是一个返回值。不仅可以等待async函数返回的Promise对象,还可以是任意表达式的结果。
function getSomething() {  return "something"; }
async function testAsync() {
    return Promise.resolve("hello async");
}
async function test() {
    const v1 = await getSomething();
    const v2 = await testAsync();
    console.log(v1, v2);
}
test();
  • 如果await等待的是Promise,则await会进行阻塞,并等待Promise对象resolve,然后得到resolve的值。(这就是await必须用在async函数中的原因,因为async内部所用的阻塞都封在了一个Promise对象中异步执行)
  • await只关心异步成功的消息resove(data),拿到对应的数据信息data。至于失败消息reject(error)不进行处理(可让await后的Promise对象catch或使用try…catch统一处理)
 async getFaceResult () {
     try {
        let location = await this.getLocation(this.phoneNum);
        if (location.data.success) {
            let info= location.data.obj.info;
            let result = await this.getFaceList(province, city);
            if (result.data.success) {
               this.list = result.data.obj;
            }
          }
      } catch(err) {
           console.log(err);
      }
}

参考资料:

https://blog.csdn.net/time_____/article/details/114980805?spm=1001.2014.3001.5501

https://blog.csdn.net/u011423258/article/details/88641870

https://blog.csdn.net/time_____/article/details/110185339?spm=1001.2014.3001.5501

https://blog.csdn.net/qq_42033567/article/details/107162586

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值