Vue知识概括

Vue 常用指令

组件选项顺序

export default {
  name: '',
  mixins: [],
  components: {},
  props: {},
  data() {},
  computed: {},
  watch: {},
  created() {},
  mounted() {},
  destroyed() {},
  methods: {}
};

v-if 是真正的条件渲染,DOM 元素被切换的过程 被销毁和创建

v-else

v-show 不管你的初始条件是什么,元素总是会被渲染并且只是简单的基于 css 样式切换

  • 2 者比较而言:v-if 有更高的切换开销,v-show 有更高的初始渲染开销

v-text v-text 和{{}}表达式渲染数据,不解析标签

v-html v-html 不仅可以渲染数据,而且可以解析标签


v-on 绑定事件 v-on="fn()" | @click="fn()"

v-once 用来绑定数据,但是绑定之后数据是不会发生改变。更多时候用于,被重复创建的组件


v-bind 单项数据绑定 简写:class="" v-bind:class=""

v-model 双向数据绑定

原理是什么?

  • 只是一个 vue 的语法糖,其实还是依靠 v-bind:绑定响应式数据,v-on 监听 input 事件传递数据,完成了双向绑定!
    为什么时 input 事件,不是 change 事件?change 事件不会起作用

v-for 循环

  • 在使用 v-for 的时候,,key 属性只能使用 number 或 String。 key 在使用的时候,必须使用 v-bind 属性绑定的形式,指定 key 的值,
    :key="唯一标识" 唯一标识可以是 item 里面 id index 等,因为 vue 组件高度复用增加 Key 可以标识组件的唯一性,为了更好地区别各个组件;
  • key 的作用主要是为了高效的更新虚拟 DOM

Vue-自定义指令

当页面加载时,该 input 元素将获得焦点:

  <input v-focus>
// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus',{
               // 当被绑定的元素插入到 DOM 中时……
	inserted: function(el){
               // 聚焦元素
	 el.focus()
	}
})
// 如果想注册局部指令,组件中也接受一个 directives 的选项:
directives: {
  focus: {
    // 指令的定义
    inserted: function (el) {
      el.focus()
    }
  }
}

Vue 生命周期


1、beforeCreate

实例、组件通过 new Vue() 创建出来之后会初始化事件和生命周期,然后就会执行 beforeCreate 钩子函数,这个时候,数据还没有挂载呢,只是一个空壳,无法访问到数据和真实的 dom,一般不做操作。

2、created

挂载数据,绑定事件等等,然后执行 created 函数,这个时候已经可以使用到数据,也可以更改数据,在这里更改数据不会触发 updated 函数,在这里可以在渲染前倒数第二次更改数据的机会,不会触发其他的钩子函数,一般可以在这里做初始数据的获取。

3、beforeMount

接下来开始找实例或者组件对应的模板,编译模板为虚拟 dom 放入到 render 函数中准备渲染,然后执行 beforeMount 钩子函数,在这个函数中虚拟 dom 已经创建完成,马上就要渲染,在这里也可以更改数据,不会触发 updated,在这里可以在渲染前最后一次更改数据的机会,不会触发其他的钩子函数,一般可以在这里做初始数据的获取。

4、mounted

接下来开始 render,渲染出真实 dom,然后执行 mounted 钩子函数,此时,组件已经出现在页面中,数据、真实 dom 都已经处理好了,事件都已经挂载好了,可以在这里操作真实 dom 等事情...

5、beforeUpdate

当组件或实例的数据更改之后,会立即执行 beforeUpdate,然后 vue 的虚拟 dom 机制会重新构建虚拟 dom 与上一次的虚拟 dom 树利用 diff 算法进行对比之后重新渲染,一般不做什么事儿。

6、updated

当更新完成后,执行 updated,数据已经更改完成,dom 也重新 render 完成,可以操作更新后的虚拟 dom。

7、beforeDestroy

当经过某种途径调用$destroy 方法后,立即执行 beforeDestroy,一般在这里做一些善后工作,例如清除计时器、清除非指令绑定的事件等等。

8、destroyed

组件的数据绑定、监听...去掉后只剩下 dom 空壳,这个时候,执行 destroyed,在这里做善后工作也可以


beforeCreate(){
    console.log("创建前:");
},
created(){
    console.log("创建完成:");
},
beforeMount(){
    console.log("挂载前:");
},
mounted(){
    console.log("挂载完成:");
},
beforeUpdate(){
    console.log('即将更新渲染');
},
updated(){
    console.log('=更新成功');
},
beforeDestory(){
    console.log("销毁前:");
},
destoryed(){
    console.log("销毁完成:");
}

Vuex 全局状态管理

概念:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

应用场景:Vue多个组件之间需要共享数据或状态。

Vuex有几个核心概念:State、Getter、Mutation、Action、Module。

State:存储状态数据

Getter:从状态数据派生数据,相当于State的计算属性。

Mutation:存储用于同步更改状态数据的方法,默认传入的参数为state。

Action:存储用于异步更改状态数据,但不是直接更改,而是通过触发Mutation方法实现,默认参数为context。

Module:Vuex模块化。

它们之间的交互关系如下图(来源于官方文档)所示:

接下来先看一个Vuex应用的简单实例,新建store.js文件并添加如下代码:

import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);

const store = new Vuex.Store({
  state: {
    name: ''
  },
  getters: {
    getName(state) {
      return 'hello ' + state.name;
    }
  },
  mutations: {
    mutationSetName(state, name) {
      state.name = name;
    }
  },
  actions: {
    actionSetName(context, name) {
      setTimeout(() => {
        context.commit('mutationSetName', name);
      }, 1000);
    }
  }
});
export default store;

然后将该store实例注入到所有子组件,方法如下:

import store from './store.js';
new Vue({
  el: '#app',
  router,
  // 把 store 对象提供给 “store” 选项,这可以把 store 的实例注入所有的子组件
  store,
  components: { App },
  template: '<App/>'
});

接下来就可以在vue的各个子组件中通过下面的方式访问vuex对象实例。

this.$store.state.name;
this.$store.getters.getName;
this.$store.commit('mutationSetName', 'zhangsan');
this.$store.dispatch('actionSetName', 'lisi');

1、或者也可以通过辅助函数的方式访问

import { mapState, mapGetters, mapMutations, mapActions } from 'vuex'

2、在计算属性computed中注入state和getters

computed: {
    ...mapState({
      // 把 `this.name` 映射为 `this.$store.state.name`
      name: state => state.name
    }),
    ...mapGetters({
      // 把 `this.getName` 映射为 `this.$store.getters.getName`
      getName: getName
    })
}

3、在methods中注入mutations和actions

methods: {
    ...mapMutations([
      // 将 `this.mutationSetName()` 映射为 `this.$store.commit('mutationSetName')`
      'mutationSetName'
    ]),
    ...mapActions([
      // 将 `this.actionSetName()` 映射为 `this.$store.dispatch('actionSetName')`
      'actionSetName'
    ])
}

模块化

由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store对象就有可能变得相当臃肿。
为了解决以上问题,Vuex允许我们将store分割成模块。每个模块拥有自己的state、getter、mutation、action、甚至是嵌套子模块-从上到下进行同样的分割。

下面新建moduleA和moduleB两个js文件,分别添加如下代码:

const moduleA = {
  namespaced: true,
  state: {
    name: ''
  },
  getters: {},
  mutations: {},
  actions: {}
}
export default moduleA;
const moduleB = {
  namespaced: true,
  state: {
    name: ''
  },
  getters: {},
  mutations: {},
  actions: {}
}
export default moduleB;

然后新建store.js文件并引入上述两个模块文件,代码如下:

import moduleA from './moduleA.js';
import moduleB from './moduleB.js';
const store = new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB
  }
})
export default store;

其中a、b为自定义的模块别名,接下来按前文同样的方式将store对象注入vue。

访问方式如下:

this.$store.state.a.name // -> moduleA 的状态name
this.$store.state.b.name // -> moduleB 的状态name

辅助函数访问方式和前文所讲区别不大,只是多了模块名称字段:

computed: {
    ...mapState('a', {
      name: state => state.name
    }),
    ...mapState('b', {
      name: state => state.name
    })
}

其他几个对象getter、mutation、action的访问方式类似,都要加上模块名称字段。


注意:

1、是否使用Vuex要根据项目的实际规模,在简单的应用中使用 Vuex 可能会显得繁琐冗余;对于中大型的单页应用,Vuex在状态管理方面才是最好的选择。

2、Vuex和单纯的全局对象不同。Vuex 的状态存储是响应式的,当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。

3、不能直接改变 store 中的状态,改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation,这样有利于跟踪每一个状态的变化。

原文地址:https://www.cnblogs.com/suni1024/p/12518584.html