理解vuex的状态管理模式架构

一: 什么是vuex?
官方解释如下:
vuex是一个专为vue.js应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证以一种可预测的方式发生变化。
使用方式有如下2种:
1. 如果直接在浏览器下引用包的话;如下:

<script src="https://unpkg.com/vue@2.5.13/dist/vue.js"></script>
<script src="https://unpkg.com/vuex@3.0.1/dist/vuex.js"></script>

接下来就可以使用了。

2. 使用npm安装
npm install vuex --save
然后在入口文件引入方式如下:

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

首先我们先来看看一个简单的demo,再来对比下vuex到底做了什么事情。具体为我们解决了什么事情?
我们先来实现一个简单的demo,有一个标签显示数字,两个按钮分别做数字的加一和减一的操作;如下使用纯vue的demo如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>vue-demo</title>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<p>{{count}}
<button @click="inc">+</button>
<button @click="dec">-</button>
</p>
</div>
<script>
new Vue({
el:'#app',
data () {
return {
count: 0
}
},
methods: {
inc () {
this.count++
},
dec () {
this.count--
}
}
})
</script>
</body>
</html>

如上的代码的含义是:button的标签内绑定两个函数,当点击的时候 分别调用 inc 和 dec的对应的函数,接着会调用 vue中的methods的对应的方法
。然后会对data中的count属性值发生改变,改变后会把最新值渲染到视图中。

注意:上面的代码直接复制运行下就可以看到效果了。

现在我们来看看使用vuex的方式来实现如上demo。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>vue-demo</title>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vuex@3.0.1/dist/vuex.js"></script>
</head>
<body>
<div id="app">
<p>{{count}}
<button @click="inc">+</button>
<button @click="dec">-</button>
</p>
</div>
<script>
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
inc: state => state.count++,
dec: state => state.count--
}
});
const app = new Vue({
el: '#app',
computed: {
count() {
return store.state.count;
}
},
methods: {
inc() {
store.commit('inc');
},
dec() {
store.commit('dec');
}
}
});
</script>
</body>
</html>

注意:上面的代码直接复制运行下就可以看到效果了。

对比下上面的代码:
1. 引用vuex源码;
2. methods的方法不变,但是方法内的逻辑不在函数内进行,而是让store对象去处理。
3. count数据不再是一个data函数返回的对象的属性了。而是通过store方法内的计算字段返回的。
具体的调用如下:
先view上的元素操作点击事件 -> 调用methods中的对应方法 -> 通过store.commit(type) 触发store中的mutations对应的方法来改变state的属性,值发生改变后,视图就得到更新。
回到store对象上来,store对象是 Vuex.Store的实列。在store内分为state对象和mutations对象,其中state存放的是状态,
比如count属性就是它的状态值,而mutations则是一个会引发状态改变的所有方法。

理解什么是状态管理模式?
状态管理:简单的理解就是统一管理和维护各个vue组件的可变化状态。

我们明白vue是单向数据流的,那么它的状态管理一般包含如下几部分:
1. state; 驱动应用的数据(一般指data中返回的数据)。
2. view; 一般指模板,以声明的方式将state的数据映射到视图。
3. actions: 响应在view上的用户输入导致的状态变化
但是当我们的应用遇到多个组件共享状态时候,那么单向数据流可能不太满足我们的需求:
比如如下几个方面:
1. 多个视图依赖于同一状态。
传参的方法对于多层嵌套的组件将会非常繁琐,并且对于兄弟组件间的状态传递无能为力。

2. 我们经常会采用父子组件直接引用或者通过事件来变更和同步状态的多份拷贝。以上的这些模式非常脆弱,通常会导致无法维护的代码。
因此我们可以把组件的共享状态提取出来,作为全局来管理,因此vuex产生了。

vuex的优点:
最主要解决了组件之间共享同一状态的问题。可以把组件的共享状态提取出来,作为全局来管理。

什么情况下我应该使用 Vuex?

如果不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。确实是如此——如果您的应用够简单,最好不要使用 Vuex。一个简单的 global event bus 就足够您所需了。但是,如果您需要构建是一个中大型单页应用,很可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择。

二: Vuex状态管理的demo学习
每一个Vuex应用的核心就是store(仓库), store是保存应用中大部分的状态。
Vuex 和一般的全局对象有以下几点不同:
1. Vuex的状态存储是响应性的。
   当vue组件从store中读取状态的时候,若store中的状态发生变化,那么相对应的组件也就会得到相应的更新。
2. 我们不能直接修改store中的状态。
   改变store中的状态的唯一途径是显示地提交(commit)mutations.

2-1 单一状态树
Vuex使用的是单一状态树,用一个对象就包含了全部的应用层级状态。这也意味着每个应用将仅仅包含一个store的实列。
Vuex的状态存储是响应性的,因此从store实列中读取一个状态的最简单的方法是在计算属性返回某个状态。
比如demo2的代码:

<div id="app">
<p>{{count}}
<button @click="inc">+</button>
<button @click="dec">-</button>
</p>
</div>
<script>
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
inc: state => state.count++,
dec: state => state.count--
}
});
const app = new Vue({
el: '#app',
computed: {
count() {
return store.state.count;
}
},
methods: {
inc() {
store.commit('inc');
},
dec() {
store.commit('dec');
}
}
});
</script>

如上代码,从store中读取一个状态可以从 computed中的count方法内就可以读取到了。当 store.state.count变化的时候,都会重新求取计算属性,并且触发相关联的DOM更新。
但是这种模式导致组件依赖的全局状态单列,在模块构建系统中,在每个需要使用state的组件中需要频繁的导入(因为每个页面都需要
导入 new Vuex.Store这样的,但是一个应用系统仅仅包含一个store实列),并且在测试组件的时候需要模拟状态。
因此vuex通过store选项,提供了一种机制将状态从根组件注入到每一个子组件中。

使用vuex的示列:

new Vuex.Store({
state: {
// code
},
mutations: {
// code ....
}
});

state是用来存储初始化的数据的。如果要读取数据使用 $store.state.数据变量。
修改数据使用mutations,它保存的需要改变数据的所有方法,改变mutations里的数据需要使用 $store.commit();

还是需要 vue-cli 中的项目来说明下:
1. 在scr目录下新建一个vuex文件夹,在该文件夹下 新建 mystore.js文件,代码如下:

import Vue from 'vue';
import Vuex from 'vuex'; Vue.use(Vuex); export default new Vuex.Store({
state: {
count: 1
},
// 需要修改stats的数据的话,需要使用$store.commit()方法
mutations: {
add(state) {
return state.count++;
},
reduce(state) {
return state.count--;
}
}
});

2. 在src/views文件夹下 新建一个 count.vue,代码如下:

<template>
<div>
<p>{{ msg }}
<!-- 获取vuex文件的mystore.js中的 state中的count的值 -->
{{ $store.state.count }}
</p>
<p>
<button @click="$store.commit('add')"> + </button>
<button @click="$store.commit('reduce')"> - </button>
</p>
</div>
</template> <script>
import mystore from '@/vuex/mystore';
export default {
data () {
return {
msg: 'Hello world'
}
},
/*
引用mystore.js,store为数据仓库
*/
store: mystore
}
</script>

3、在 src/router/index.js 路由配置文件中配置 count.vue 的路由, 代码如下:

import Vue from 'vue';
import Router from 'vue-router';
// import HelloWorld from '@/views/HelloWorld'; Vue.use(Router); const router = new Router({
mode: 'history', // 访问路径不带井号 需要使用 history模式,才能使用 scrollBehavior
routes: [
{
path: '/count',
name: 'count',
component: resolve => require(['@/views/count'], resolve) // 使用懒加载
}
]
});
export default router;

直接在浏览器访问 http://localhost:8080/count 即可了。

三:学习Vuex state访问状态对象
上面我们的代码是访问状态对象的,是单页应用程序中的共享值,现在我们再来看看状态对象如何赋值给内部对象,也就是
把mystore.js中的值,赋值给模板里data的值,也就是想直接在template中用 {{xxx}}直接调用数据。

我们知道vuex的状态存储是响应性的,从store实列中读取状态最简单的方式是在计算属性中返回某个状态。

3-1 通过computed的计算属性直接赋值
在src/views文件夹下新建 count2.vue, 代码如下:

<template>
<div>
<p>{{ msg }}
<!-- 获取vuex文件的mystore.js中的 state中的count的值 -->
{{ $store.state.count }}
</p>
<p>computed计算赋值结果是:{{ count }}</p>
<p>
<button @click="$store.commit('add')"> + </button>
<button @click="$store.commit('reduce')"> - </button>
</p>
</div>
</template> <script>
import mystore from '@/vuex/mystore';
export default {
data () {
return {
msg: 'Hello world'
}
},
computed: {
count () {
return this.$store.state.count
}
},
/*
引用mystore.js,store为数据仓库
*/
store: mystore
}
</script>

在浏览中访问 http://localhost:8080/count2 可以看到。

3-2 通过mapState的对象来赋值
当一个组件需要获取多个状态的时候,将这些状态都声明为计算属性会有些重复和冗余,为了解决这个问题,可以使用
mapState辅助函数来帮助我们生成计算属性。

在src/views文件夹下新建 count3.vue, 代码如下:

<template>
<div>
<p>{{ msg }}
<!-- 获取vuex文件的mystore.js中的 state中的count的值 -->
{{ $store.state.count }}
</p>
<p>computed计算赋值结果是:{{ count }}</p>
<p>
<button @click="$store.commit('add')"> + </button>
<button @click="$store.commit('reduce')"> - </button>
</p>
</div>
</template> <script>
import mystore from '@/vuex/mystore';
// 引入mapState
import { mapState } from 'vuex'; export default {
data () {
return {
msg: 'Hello world'
}
},
computed: mapState({
count: function(state) {
return state.count;
}
}),
/*
引用mystore.js,store为数据仓库
*/
store: mystore
}
</script>

在浏览中访问 http://localhost:8080/count3 可以看到。

3-3 通过mapState的数组来赋值,
在src/views 下 新建 count4.vue, 代码如下:

<template>
<div>
<p>{{ msg }}
<!-- 获取vuex文件的mystore.js中的 state中的count的值 -->
{{ $store.state.count }}
</p>
<p>computed计算赋值结果是:{{ count }}</p>
<p>
<button @click="$store.commit('add')"> + </button>
<button @click="$store.commit('reduce')"> - </button>
</p>
</div>
</template> <script>
import mystore from '@/vuex/mystore';
// 引入mapState
import { mapState } from 'vuex'; export default {
data () {
return {
msg: 'Hello world'
}
},
/*
* 数组中的count 必须和 mystore.js定义的常量 mystate 中的 count同名,
因为这是直接访问mystate的count
*/
computed: mapState(['count']),
/*
引用mystore.js,store为数据仓库
*/
store: mystore
}
</script>

在浏览中访问 http://localhost:8080/count4 可以看到。

四: getters计算过滤操作
    有时候我们需要从store中的state中派生出一些状态,比如在使用store中的state之前,我们会对state中的某些字段进行过滤一下,比如对state中的count字段都进行加10这样的数据;但是如果有多个组件需要用到这个操作的话,那么我们就需要复制这个函数,或者抽取到一个共享函数内,
然后多处导入这个函数,但是这上面两种方式都不是太好,因为我们现在有更好的方式来解决它。
Vuex中允许我们在store中定义 getters,getters的返回值会根据它的依赖被缓存起来,且只有当他的依赖值发生改变了
才会重新计算。
现在我们需要对mystore.js文件中的count进行一个计算属性的操作,在它输出之前,加上10的操作。
如下代码有两个按钮,一个加5,一个减5,那么在加5或者减5之前,先加20,然后再进行加5或者5操作。代码如下:
在文件夹 src/vuex/mystore.js代码如下:

import Vue from 'vue';
import Vuex from 'vuex'; Vue.use(Vuex); // 增加一个常量对象 state
const mystate = {
count: 0
};
// mutations 保存所有的方法,该方法可以改变state数据
const mymutations = {
// 增加
add(state, num) {
const count = state.count += num;
return count;
},
// 减少
reduce(state, num) {
const count = state.count -= num;
return count;
}
}; // 增加一个getters对象
const mygetters = {
mycount: function(state) {
const count = state.count += 20;
return count;
}
}; // 封装代码,让外部可见
export default new Vuex.Store({
state: mystate, // state的固定写法 保存数据的状态值
mutations: mymutations, // mutations的固定写法 改变数据的所有方法
getters: mygetters
});

在src/views/下新建 count5.vue 代码如下:

<template>
<div>
<p>{{ msg }}
<!-- 获取vuex文件的mystore.js中的 state中的count的值 -->
{{ $store.state.count }}
</p>
<p>computed计算赋值结果是:{{ mycount }}</p>
<p>
<!--
$store.commit('add', 5) 第一个参数是方法名,第二个是参数
-->
<button @click="$store.commit('add', 5)"> + </button>
<button @click="$store.commit('reduce', 5)"> - </button>
</p>
<div>
<p>使用mapMutations修改状态:</p>
<p>
<button @click="add(10)">+</button>
<button @click="reduce(10)">-</button>
</p>
</div>
</div>
</template> <script>
import mystore from '@/vuex/mystore';
// 引入mapState
import { mapState, mapMutations, mapGetters } from 'vuex'; export default {
data () {
return {
msg: 'Hello world'
}
},
computed: {
// mapState(['count']) 此处的count必须和store.js定义的常量 mystate中的count同名,因为这是直接访问 mystate的count
...mapState(['count']),
// mapGetters 辅助函数,可以将store中的getter映射到局部计算属性mycount
...mapGetters(['mycount'])
},
methods: mapMutations(['add', 'reduce']),
/*
引用mystore.js,store为数据仓库
*/
store: mystore
}
</script>

在浏览器下 访问 http://localhost:8080/count5 即可。

五:Mutations修改状态
Mutations是修改vuex中的store的唯一方法。每个mutations都有一个字符串的事件类型(type)和一个回调函数(handler)。这个回调函数就是
我们进行更改的地方。它也会接受state作为第一个参数。

打开上面src/vuex/mystore.js 代码中的 mutations 可以看到如下:

// mutations 保存所有的方法,该方法可以改变state数据
const mymutations = {
// 增加
add(state, num) {
const count = state.count += num;
return count;
},
// 减少
reduce(state, num) {
const count = state.count -= num;
return count;
}
};

我们之前调用 mutations的方法是这样的 $store.commit()即可调用方法来改变state数据,现在我们想使用 @click="add()"来调用。
1. 我们在src/views/ 下新建一个count6.vue, 先导入我们的 mapMutations方法

import { mapState, mapMutations } from 'vuex'; 

2. 使用methods属性,并加入 mapMutations

methods: mapMutations(['add', 'reduce']); 

3. 在template中使用 @click="", 如下代码:

<button @click="add(5)">+</button>
<button @click="reduce(5)">-</button>

count6.vue 代码如下:

<template>
<div>
<p>{{ msg }}
<!-- 获取vuex文件的mystore.js中的 state中的count的值 -->
{{ $store.state.count }}
</p>
<p>computed计算赋值结果是:{{ count }}</p>
<p>
<!--
$store.commit('add', 5) 第一个参数是方法名,第二个是参数
-->
<button @click="$store.commit('add', 5)"> + </button>
<button @click="$store.commit('reduce', 5)"> - </button>
</p>
<div>
<p>使用mapMutations修改状态:</p>
<p>
<button @click="add(10)">+</button>
<button @click="reduce(10)">-</button>
</p>
</div>
</div>
</template> <script>
import mystore from '@/vuex/mystore';
// 引入mapState
import { mapState, mapMutations } from 'vuex'; export default {
data () {
return {
msg: 'Hello world'
}
},
computed: {
// mapState(['count']) 此处的count必须和store.js定义的常量 mystate中的count同名,因为这是直接访问 mystate的count
...mapState(['count'])
},
methods: mapMutations(['add', 'reduce']),
/*
引用mystore.js,store为数据仓库
*/
store: mystore
}
</script>

src/vuex/mystore.js代码修改如下:

import Vue from 'vue';
import Vuex from 'vuex'; Vue.use(Vuex); // 增加一个常量对象 state
const mystate = {
count: 0
};
// mutations 保存所有的方法,该方法可以改变state数据
const mymutations = {
// 增加
add(state, num) {
const count = state.count += num;
return count;
},
// 减少
reduce(state, num) {
const count = state.count -= num;
return count;
}
}; // 封装代码,让外部可见
export default new Vuex.Store({
state: mystate, // state的固定写法 保存数据的状态值
mutations: mymutations // mutations的固定写法 改变数据的所有方法
});

六: actions异步修改状态
actions是异步修改state的状态的。但是Mutations是同步改变状态的。

6-1 在mystore.js中声明actions
actions是可以调用Mutations的方法的。如下代码:

// 增加一个 actions
const myactions = {
addAction(context) {
console.log(context);
context.commit('add', 5); // 调用mymutations 中的 add方法,并传参数5
},
reduceAction(context) {
context.commit('reduce', 5); // 调用mymutations中的reduce方法,并传参数5
}
};

myactions 里有两个方法 addAction 和 reduceAction , 在方法体内,我们都用 commit 调用了 Mutations
里面的方法。
其中context,是上下文对象,在这边可以理解为store本身。

在Vuex.store()中封装

// 封装代码,让外部可见
export default new Vuex.Store({
state: mystate, // state的固定写法 保存数据的状态值
mutations: mymutations, // mutations的固定写法 改变数据的所有方法
getters: mygetters,
actions: myactions
});

在conut7.vue中调用,代码如下:

<p>
actions的异步操作<br/>
<button @click="addAction"> + </button>
<button @click="reduceAction"> - </button>
</p>

import引用如下:

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

添加methods方法,代码如下:

methods: {
...mapMutations(['add', 'reduce']),
...mapActions(['addAction', 'reduceAction'])
}

下面是全部代码:

mystore.js代码如下:

import Vue from 'vue';
import Vuex from 'vuex'; Vue.use(Vuex); // 增加一个常量对象 state
const mystate = {
count: 0
};
// mutations 保存所有的方法,该方法可以改变state数据
const mymutations = {
// 增加
add(state, num) {
const count = state.count += num;
return count;
},
// 减少
reduce(state, num) {
const count = state.count -= num;
return count;
}
}; // 增加一个getters对象
const mygetters = {
mycount: function(state) {
const count = state.count += 20;
return count;
}
};
// 增加一个 actions
const myactions = {
addAction(context) {
console.log(context);
context.commit('add', 5); // 调用mymutations 中的 add方法,并传参数5
},
reduceAction(context) {
context.commit('reduce', 5); // 调用mymutations中的reduce方法,并传参数5
}
};
// 封装代码,让外部可见
export default new Vuex.Store({
state: mystate, // state的固定写法 保存数据的状态值
mutations: mymutations, // mutations的固定写法 改变数据的所有方法
getters: mygetters,
actions: myactions
});

count7.vue代码如下:

<template>
<div>
<p>{{ msg }}
<!-- 获取vuex文件的mystore.js中的 state中的count的值 -->
{{ $store.state.count }}
</p>
<p>computed计算赋值结果是:{{ mycount }}</p>
<p>
<!--
$store.commit('add', 5) 第一个参数是方法名,第二个是参数
-->
<button @click="$store.commit('add', 5)"> + </button>
<button @click="$store.commit('reduce', 5)"> - </button>
</p>
<div>
<p>使用mapMutations修改状态:</p>
<p>
<button @click="add(10)">+</button>
<button @click="reduce(10)">-</button>
</p>
<p>
actions的异步操作<br/>
<button @click="addAction"> + </button>
<button @click="reduceAction"> - </button>
</p>
</div>
</div>
</template> <script>
import mystore from '@/vuex/mystore';
// 引入mapState
import { mapState, mapMutations, mapGetters, mapActions } from 'vuex'; export default {
data () {
return {
msg: 'Hello world'
}
},
computed: {
// mapState(['count']) 此处的count必须和store.js定义的常量 mystate中的count同名,因为这是直接访问 mystate的count
...mapState(['count']),
...mapGetters(['mycount'])
},
methods: {
...mapMutations(['add', 'reduce']),
...mapActions(['addAction', 'reduceAction'])
},
/*
引用mystore.js,store为数据仓库
*/
store: mystore
}
</script>

可以查看github上的代码

理解vuex的状态管理模式架构的更多相关文章

  1. 理解Vue的状态管理模式Vuex

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

  2. 举个例子去理解vuex(状态管理),通俗理解vuex原理,通过vue例子类比

    通俗理解vuex原理---通过vue例子类比   本文主要通过简单的理解来解释下vuex的基本流程,而这也是vuex难点之一. 首先我们先了解下vuex的作用vuex其实是集中的数据管理仓库,相当于数 ...

  3. 关于vuex状态管理模式架构

    一. 什么是vuex 集中存储管理所有组件的状态 并以相应的规则保证以一种可预测的方式发生变化. 例子: 实现加减 <p>{{count}} <button @click=" ...

  4. Vuex,状态管理模式

    对于 Vue 本人目前接触不深,只得浅层分析,Vue 是单向数据流, state,驱动应用的数据源: view,以声明方式将 state 映射到视图: actions,响应在 view 上的用户输入导 ...

  5. vuex的状态管理模式

    1.store.js Vuex 通过 store 选项,提供了一种机制将状态从根组件“注入”到每一个子组件中(需调用 Vue.use(Vuex)) state:存放数据. mutations:提交状态 ...

  6. 转 理解vuex -- vue的状态管理模式

    转自:https://segmentfault.com/a/1190000012015742 vuex是什么? 先引用vuex官网的话: Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 ...

  7. 了解Vuex状态管理模式的理解强化指南

    1 Vuex是什么呢?它是Vue的状态管理模式,在使用vue的时候,需要在vue中各个组件之间传递值是很痛苦的,在vue中我们可以使用vuex来保存我们需要管理的状态值,值一旦被改变,所有引用该值的地 ...

  8. Vuex(一)——vuejs的状态管理模式

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

  9. Vue状态管理模式---Vuex

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

随机推荐

  1. 集合&gt;哈希表类Hashtable和SortedList排序列表类

    集合>哈希表类Hashtable Hashtable一种键值对的集合 ,哈希表内部的排列是无序的,而且哈希表没有提供排序方法. 集合>哈希表类Hashtable>构造普通哈希表 代码 ...

  2. Android Testing Point

    The test application demonstrates these key points: An Android test is itself an Android application ...

  3. django之第二天

    今天学习目标: 一,路由系统 1,默认处理函数 2,动态URL 3,分级匹配 4,反射实现动态路由 二.中间件 三.Model(重点) 1,创建表 2,操作表数据 四.Form (重点) 1,用户提交 ...

  4. python3学习笔记(1)

    一.模块初识(接上篇)模块(库)分为两种:1.标准库:不需要安装直接可以导入的库,例:getpass.2.第三方库:必须要下载安装才可以使用.注:编辑的模块文件名不能与导入的模块名重复. 在模块文件中 ...

  5. Luogu P1073 最优贸易

    题目描述 C 国有 n 个大城市和 m 条道路,每条道路连接这 n 个城市中的某两个城市.任意两个城市之间最多只有一条道路直接相连.这 m 条道路中有一部分为单向通行的道路,一部分为双向通行的道路,双 ...

  6. 学习MySQL(上)

    具体实例 1.PHP 服务器组件 对于初学者建议使用集成的服务器组件,它已经包含了 PHP.Apache.Mysql 等服务,免去了开发人员将时间花费在繁琐的配置环境过程. Window 系统可以使用 ...

  7. Git命令行对照表

    git init # 初始化本地git仓库(创建新仓库) git config --global user.name "xxx" # 配置用户名 git config --glob ...

  8. openvpn技术实现客户端直接访问远程机器中docker内容器的实现与原理

    传统开发中如果要从开发机中访问服务器中的docker中的服务可能可能需要如下方案: 利用docker run的-p属性直接映射端口到服务器中 优点:客户端直接访问服务器就可以访问到docker容器. ...

  9. webpack中实现按需加载

    webpack中的require.ensure()可以实现按需加载资源包括js,css等,它会给里面require的文件单独打包,不和主文件打包在一起,webpack会自动配置名字,如0.js,1.j ...

  10. ##6.1 Neutron控制节点-- openstack pike

    ##6.1 Neutron控制节点 openstack pike 安装 目录汇总 http://www.cnblogs.com/elvi/p/7613861.html ##6.1 Neutron控制节 ...