vue.js的总结
从初识Vue.js—>vue.js的基础知识—>Vue.js 的组件—>Vue Router(路由)构建单页程序—>使用脚手架搭建单页程序—>Ajax vue-axios—>vuex状态管理
1.初识Vue.js
为什么用Vue.js?
Vue.js是一个强大的数据处理框架,能够很好的提升前端的开发效率
在国内很多企业都用vue.js开发前端项目,需求量非常大。
Vue.js的文档非常详细,生态也非常丰富,要找到的资料也非常多、全,容易学习。遇到的问题也很容易在网上查到。
2.vue.js的基础知识
Vue.js 使用了基于 HTML 的模板语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据。
3.Vue.js 的组件
基本概念
组件是一个可复用的Vue实例,需要挂载到Vue的实例
组件除了el选项外,同样包括有data、computed、watch、methods 以及生命周期钩子等。
4.Vue Router(路由)构建单页程序
Vue Router是什么?
是Vue.js的核心组件,由Vue.js官方维护的路由管理器
通过路由器可以构建用户体验较高的单页应用程序
5.使用脚手架搭建单页程序
为什么使用脚手架
为了使用更先进的技术例如 es5或是es6。都需要借助功能才能够在现有的浏览器运行
需要使用很多工具,例如webpack、babel做编译等工具,配置起来非常繁琐
vue.js 官方为了减轻这些繁琐的配置,将vue.js环境需要的配置配好,方便vue.js项目的开发
脚手架:是一种基于node.js的工具,作用是开发中用到的工具、环境都配置好了。不用在为这些复杂的配置花时间,专注业务开发就好了。
6.Ajax vue-axios官方文档
https://www.npmjs.com/package/axios
使用的步骤
vue-axios是官方推荐的插件
安装文件 npm install --save axios vue-axios
引入文件
import Vue from 'vue'
import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(VueAxios, axios)
使用的基本格式
//全局使用
Vue.axios.get(api).then((response) => {
console.log(response.data)
})
//组件内使用
this.axios.get(api).then((response) => {
console.log(response.data)
})
//组件内使用$http
this.$http.get(api).then((response) => {
console.log(response.data)
})
7.vuex状态管理
7.1.vuex概述
vuex是什么?是状态管理模式,用于组件于组件之间的通信
应用场景:大型的单页应用程序
7.2.安装环境
引入文件方式(初学用)
引入脚本
<script src="/path/to/vue.js"></script>
<script src="/path/to/vuex.js"></script>
vuex.js地址:
https://unpkg.com/vuex
npm方式
npm install vuex --save
main.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
7.3.基本案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>数组的操作</title>
<script src="../js/vue.js"></script>
<script src="../js/vuex.js"></script>
</head>
<body>
<div id="app">
{{count}} <button @click="increament">计数</button>
</div>
<script>
//定义存储的仓库
var store = new Vuex.Store({
state: { //状态管理的数据,类似data
count: 0,
},
mutations: { //对数据改变的操作
increament(state) { //定义方法,参数一传递state对象
state.count++;
}
},
});
var vm = new Vue({
el: "#app",
store, //状态管理对象
computed: { //计算属性
count() {
return this.$store.state.count;
}
},
methods: {
increament() {
//提交状态管理
this.$store.commit("increament");
}
},
});
</script>
</body>
</html>
注意:默认可以直接修改state的数据,如果不允许可以做如下设置
strict: true
下面的赋值方式,将会抛出异常
this.$store.state.count++;
7. 4.State 状态数据作用:用来存储共享的数据,类似data数据也是响应式的
如何定义
var store = new Vuex.Store({
strict: true,
state: {//状态管理的数据,类似data
count: 0,
},
});
如何使用
基本的使用方式
在组件上的使用
this.$store.state.count
mapState 辅助函数
var mapState = Vuex.mapState;
在计算属性上使用
方式1 数组(最简洁)
computed: mapState(["count"])
方式2 自定义别名:
computed: mapState({count2:"count"})
方式3 箭头函数
computed: mapState({count2:state=>state.count})
方式4: 普通函数
computed: mapState({
getCount(state){
return state.count+this.count;
// this指向组件对象,不能使用箭头函数,箭头函数this==undefined
}
})
定义mapState 与组件的属性
computed: mapState(["count"]) 一个mapState返回的对象占用了整个computed,如果想定义其它的计算属性怎么办?
使用对象展开符... 将mapState函数返回的对象的属性,向外面的对象展开,这是es6的语法
var obj={name:"小智",age:20}
var stu={address:'深圳市',...obj}
stu;//{address: "深圳市", name: "小智", age: 20}
计算属§的代码如下:
computed: {
//本地计算属性
localComputed () { /* ... */ },
// 使用对象展开运算符将此对象混入到外部对象中
...mapState({
// ...
})
}
7.5.Getter 作用:增强对state数据处理,例如过滤,计算。类似计算属性,具有缓存作用。
定义getter
const store = new Vuex.Store({
state: {
todos: [
{ id: 1, text: '...', done: true },
{ id: 2, text: '...', done: false }
]
},
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
}
}
})
如何使用
基本的使用方式
this.$store.getters.doneTodos
通过方法访问
让 getter 返回一个函数,来实现给 getter 传参
getters: {
// ...
getTodoById: (state) => (id) => {
return state.todos.find(todo => todo.id === id)
}
}
使用
this.$store.getters.getTodoById(1)
mapGetters 辅助函数
mapGetters 辅助函数仅仅是将 store 中的 getter 映射到局部计算属性:
var mapGetters = Vuex.mapGetters;
computed: {
// 使用对象展开运算符将 getter 混入 computed 对象中
...mapGetters([
'doneTodosCount',
'anotherGetter',
// ...
])
}
7.6.Mutation作用:更改 Vuex 的 store 中的状态的唯一方法,类似自定义事件。
如何定义
const store = new Vuex.Store({
state: {
count: 1
},
mutations: {
//参数1就是state对象
increment (state) {
// 变更状态
state.count++
}
}
})
如何使用
store.commit('increment')
提交载荷(额外参数)
// ...
mutations: {
increment (state, n) {
state.count += n
}
}
store.commit('increment', 10)
参数作为对象
// ...
mutations: {
increment (state, payload) {
state.count += payload.amount
}
}
store.commit('increment', {
amount: 10
})
对象风格的提交方式
store.commit({
type: 'increment',
amount: 10
})
使用常量替代 Mutation 事件类型
// mutation-types.js
export const SOME_MUTATION = 'SOME_MUTATION'
// store.js
import Vuex from 'vuex'
import { SOME_MUTATION } from './mutation-types'
const store = new Vuex.Store({
state: { ... },
mutations: {
// 我们可以使用 ES2015 风格的计算属性命名功能来使用一个常量作为函数名
[SOME_MUTATION] (state) {
// mutate state
}
}
})
mapMutations 辅助函数
var mapMutations = Vuex.mapMutations ;
export default {
// ...
methods: {
...mapMutations([
'increment', // 将 `this.increment()` 映射为 `this.$store.commit('increment')`
// `mapMutations` 也支持载荷:
'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.commit('incrementBy', amount)`
]),
...mapMutations({
add: 'increment' // 将 `this.add()` 映射为 `this.$store.commit('increment')`
})
}
}
注意:Mutation 必须是同步函数,便于跟踪状态信息
7.7.Action:作用:类似于 mutation,用于异步处理状态的更改。
如何定义
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (context) {
context.commit('increment') //改变状态唯途径就是mutation
}
}
})
context对象
context.commit 提交一个 mutation,或者通过 context.state 和 context.getters 来获取 state 和 getters。
简化代码
actions: {
increment ({ commit }) {//解构对象
commit('increment')
}
}
分发 Action
store.dispatch('increment')
支持同样的载÷方式和对象方式进行分发:
// 以载荷形式分发
store.dispatch('incrementAsync', {
amount: 10
})
// 以对象形式分发
store.dispatch({
type: 'incrementAsync',
amount: 10
})
mapActions 辅助函数
export default {
// ...
methods: {
...mapActions([
'increment', // 将 `this.increment()` 映射为 `this.$store.dispatch('increment')`
// `mapActions` 也支持载荷:
'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.dispatch('incrementBy', amount)`
]),
...mapActions({
add: 'increment' // 将 `this.add()` 映射为 `this.$store.dispatch('increment')`
})
}
}
结合Promise
actions: {
actionA ({ commit }) {
return new Promise((resolve, reject) => {
setTimeout(() => {
commit('someMutation')
resolve()
}, 1000)
})
}
}
使用
store.dispatch('actionA').then(() => {
// ...
})
7.8.Module:作用:可以根据功能划分多个模块来管理状态,避免臃肿。
如何定义
const moduleA = {
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: { ... },
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态
如何使用Module的state
const moduleA = {
state: { age:18 },
}
const store = new Vuex.Store({
modules: {
moduleA,
}
})
需要使用模×名来调用
store.state.moduleA.age // -> moduleA 的状态
使用mapState
var mapState = Vuex.mapState;
var vm = new Vue({
el: "#app",
store,//状态管理对象
computed: mapState({
age: state => state.moduleA.age,//箭头函数
age2(state) {//普通方法
return state.moduleA.age;
},
})
});
如何使用Module的getter
var moduleA = {
state: {
age: 18
},
getters:{
getAge(state){
return state.age+2;
}
}
}
//定义模块
var moduleA = {
state: {
age: 18
},
getters: {
getAge(state) {
return state.age + 2;
}
}
}
var moduleB = {
getters: {
getAge(state) {
return 0;
}
}
}
--------------------------------------------------
var store = new Vuex.Store({
modules: {
moduleA,
moduleB
}
});
如何使用Module的mutation和action
//定义模块
var moduleA = {
mutations: {
addAge() {
console.log("mduleA mutations addAge")
}
},
actions: {
addAge() {
console.log("mduleA actions addAge")
}
}
}
//定É存储的仓库
var store = new Vuex.Store({
modules: {
moduleA,
}
});
var vm = new Vue({
el: "#app",
store,//状态管理对象
created() {
this.$store.commit("addAge");
this.$store.dispatch("addAge");
}
});
问题:这里依然不用指定模块,像以前那样使用,如果模块B也有相同的会做什么样的处理?
var moduleB = {
mutations: {
addAge() {
console.log("mduleB mutations addAge")
}
},
actions: {
addAge() {
console.log("mduleB actions addAge")
}
}
}
var store = new Vuex.Store({
modules: {
moduleA,
moduleB,
}
});
created() {
this.$store.commit("addAge");
this.$store.dispatch("addAge");
}
输出结果
说明:可以定义相同的action和mutation,并且都会执行。
问题:多个模块有相同的action或mutation如何执行其中的一个了?
使用命名空间å划分,也就是像state那样指定模块的名称å使用
namespaced的使用
var moduleA = {
namespaced: true,
state:{
age:18
},
getters: {
getAge() {
console.log("mduleA getters getAge")
return 20;
}
},
mutations: {
addAge() {
console.log("mduleA mutations addAge")
}
},
actions: {
addAge() {
console.log("mduleA actions addAge")
}
}
}
具体的使用方式
created() {
this.$store.state.moduleA.age; //
this.$store.getters['moduleA/getAge'];//使用模块名称
this.$store.commit("moduleA/addAge");//使用模块名称
this.$store.dispatch("moduleA/addAge");//使用模块名称
}
使用mapxxx的方式
computed: {
//state的映射
...mapState({ age: state => state.moduleA.age }),// 使用 this.age
//getter的映射1
...mapGetters({ getAge: 'moduleA/getAge' }),//使用 this.getAge
//getter的映射2
//...mapGetters(['moduleA/getAge']),//使用 this['moduleA/getAge']
},
methods: {
//mutation映射
...mapMutations({ add: 'moduleA/addAge' }),//使用 this.add()
//这种方式不推荐使用
...mapMutations(['moduleA/addAge']), //使用 this["moduleA/addAge"]()
//action 映射
...mapActions({ aAddAge: 'moduleA/addAge' }),//使用 this.aAddAge()
//这种方式不推荐使用
//...mapActions(['moduleA/addAge']),//使用 this["moduleA/addAge"]()
},
7.9.项目结构
7.9.1Vuex 项目结构的一些基本规则