- 视图层:vue(html+css+js)
- 网络通信:axios
- 页面跳转:vue-router
- 状态管理:vuex
javascript:原生JS,是按照ECMAScript(简称 ES)标准的开发方式,特点是所有浏览器都支持
- TypeScript:微软的标准。是javascript的i一个超集。运行完它之后会打包将其变成javascript(类似sass编译运行完成css一样)
JavaScript 框架
- jQuery
- Angular:模块化
- React:虚拟DOM(把很多DOM操作放到内存中去做,不用走浏览器,快)
- Vue:模块化+虚拟DOM
- Axios:前端通信框架。因为vue 的边界明确,就是为了处理DOM,所以并不具备通信能力,此时就需要一个特定的通信框架和服务器交互
javascript 构建工具
- babel:JS编译工具,主要用于浏览器不支持的ES新特性,比如用于编译TypeScript
- webpack:模块打包器,主要作用是打包,压缩,合并和按序加载
Node.js:方便前端人员开发后台应用的技术。其框架和项目管理工具如下:
- Express:Node.js框架
- Koa:Node.js简化版
- NPM:项目综合管理工具
- YARN:NPM的替代方案
Web2.0时代:Ajax出来之后网页可以但页面应用了,因为页面不用刷新不用跳转了
大前端:前端为主的MV*
- MVC(同步通信为主):Model,View,Controller
- MVP(异步通信为主):Model,View,Presenter
- MVVM(异步通信为主):Model(JS),View(HTML操作的元素),ViewModel(连接视图和工具的中间层。Vue)
axios 异步通信
vuex
基本使用-1 state
demo1
state 是存储需要用的数据
-
src/store/index.js
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ state: { products: [ {name: "aaa", price: 10}, {name: "bbb", price: 20}, {name: "ccc", price: 30}, {name: "ddd", price: 40}, {name: "eee", price: 50} ] }, mutations: { }, actions: { }, modules: { } }) -
src/main.js
import Vue from 'vue' import App from './App.vue' import router from './router' import store from './store' Vue.config.productionTip = false new Vue({ router, store, render: h => h(App) }).$mount('#app') -
src/components/test1.vue
<template> <div class="hello"> <ul v-for="item in products" :key="item.id"> <li>{{item.name}}</li> <li>{{item.price}}</li> </ul> </div> </template> <script> export default { name: "test1", props: { msg: String }, computed: { products(){ return this.$store.state.products; } } }; </script> <style scoped lang="scss"> ul>li{ list-style-type: none; } </style>
demo2
和基本使用-1里面的store.js、main.js一样,只是改变了vue文件,让price字段的值变为它的一半
<template>
<div>
<ul v-for="item in saleProduct" :key="item.id">
<li>{{item.name}}</li>
<li>{{item.price}}</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {};
},
computed: {
saleProduct() {
var products = this.$store.state.products.map(item => {
return {
name: "hello~ " + item.name,
price: item.price / 2
};
});
return products;
}
}
};
</script>
<style lang="scss" scoped>
ul>li{
list-style-type: none;
}
</style>
基本使用-3 getters
getters 是获取需要的数据
-
store/index.js
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ state: { products: [ {name: "aaa", price: 10}, {name: "bbb", price: 20}, {name: "ccc", price: 30}, {name: "ddd", price: 40}, {name: "eee", price: 50} ] }, getters: { saleProducts: (state) => { var products = state.products.map(item => { return { name: "hello~ " + item.name, price: item.price / 2 }; }); return products; } }, mutations: { }, actions: { }, modules: { } }) -
test3.vue
<template> <div> <ul v-for="item in saleProducts" :key="item.id"> <li>{{item.name}}</li> <li>{{item.price}}</li> </ul> </div> </template> <script> export default { computed: { saleProducts() { return this.$store.getters.saleProducts; } }, } </script> <style lang="scss" scoped> ul>li{ list-style-type: none; } </style>
基本使用-4 mutations
mutations 是当你触发事件去改变数据时使用
这块要实现的功能是:点击按钮之后对应的price会降价
demo1 一般写法
<template>
<div>
<ul v-for="item in saleProducts" :key="item.id">
<li>{{item.price}}</li>
</ul>
<button @click="reduce">reduce price</button>
</div>
</template>
<script>
export default {
computed: {
saleProducts(){
return this.$store.getters.saleProducts;
}
},
methods: {
reduce() {
this.$store.state.products.forEach(item => {
item.price -= 1;
})
}
},
}
</script>
<style lang="scss" scoped>
</style>
点击按钮之前的初始状态
点击按钮之后的降价状态(这里降了0.5而不是1,是因为调用的是this.$store.getters.saleProducts;里面的price,它是按照之前的方式展示,有除以2)
demo2 通过mutations来写
- src/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
products: [
{ name: "aaa", price: 10 },
{ name: "bbb", price: 20 },
{ name: "ccc", price: 30 },
{ name: "ddd", price: 40 },
{ name: "eee", price: 50 }
]
},
getters: {
saleProducts: (state) => {
var products = state.products.map(item => {
return {
name: "hello~ " + item.name,
price: item.price / 2
};
});
return products;
}
},
mutations: {
reducrProducts: state => {
state.products.forEach(item => {
item.price -= 1;
})
}
},
actions: {},
modules: {}
})
- test4.vue
<template>
<div>
<ul v-for="item in saleProducts" :key="item.id">
<li>{{item.price}}</li>
</ul>
<button @click="reduce">reduce price</button>
</div>
</template>
<script>
export default {
computed: {
saleProducts() {
return this.$store.getters.saleProducts;
}
},
methods: {
reduce() {
// this.$store.state.products.forEach(item => {
// item.price -= 1;
// })
this.$store.commit("reducrProducts");
}
}
};
</script>
<style lang="scss" scoped>
</style>
这块出来的效果和上面的一样
基本使用-4 actions
actions 与 mutations 类似,不同在于:
- actions 提交的是 mutation,而不是直接变更状态
- actions 可以包含任意异步操作
这里要实现的就是点击 reduce price 降价按钮,在3秒钟之后显示降价后的price
demo1 直接在mutation中写
- src/store/index.js
给之前的reducePrice中加一个 setTimeOut 定时器
mutations: {
reducrProducts: state => {
setTimeout(() => {
state.products.forEach(item => {
item.price -= 1;
})
}, 3000);
}
},
然后点击reduce price 降价按钮,可以实现3秒钟之后降价
demo2 通过actions 结合 mutations 来实现
- src/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
products: [{
name: "aaa",
price: 10
},
{
name: "bbb",
price: 20
},
{
name: "ccc",
price: 30
},
{
name: "ddd",
price: 40
},
{
name: "eee",
price: 50
}
]
},
getters: {
saleProducts: (state) => {
var products = state.products.map(item => {
return {
name: "hello~ " + item.name,
price: item.price / 2
};
});
return products;
}
},
mutations: {
reduceProducts: state => {
// setTimeout(() => {
state.products.forEach(item => {
item.price -= 1;
})
// }, 3000);
}
},
actions: {
reduceProducts: (context) => {
setTimeout(() => {
context.commit("reduceProducts")
}, 3000);
}
},
modules: {}
})
- test5.vue
<template>
<div>
<ul v-for="item in saleProducts" :key="item.id">
<li>{{item.price}}</li>
</ul>
<button @click="reduce">reduce price</button>
</div>
</template>
<script>
export default {
computed: {
saleProducts() {
return this.$store.getters.saleProducts;
}
},
methods: {
reduce() {
// 这是调用$store里面的mutations中的方法
// this.$store.commit("reduceProducts");
// 这是调用$store里面的actions中的方法
this.$store.dispatch("reduceProducts");
}
}
};
</script>
<style lang="scss" scoped>
</style>
现在的实现效果就和上面的一样了
demo3 通过vue页面传参
比如现在商品降价不让它降价1了,而是降一个自己传递过去的价格
- test5.vue
<template>
<div>
<ul v-for="item in saleProducts" :key="item.id">
<li>{{item.price}}</li>
</ul>
<button @click="reduce(5)">reduce price</button>
</div>
</template>
<script>
export default {
computed: {
saleProducts() {
return this.$store.getters.saleProducts;
}
},
methods: {
reduce(amount) {
// 这是调用$store里面的mutations中的方法
// this.$store.commit("reduceProducts");
// 这是调用$store里面的actions中的方法
this.$store.dispatch("reduceProducts", amount);
}
}
};
</script>
<style lang="scss" scoped>
</style>
- src/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
products: [{
name: "aaa",
price: 10
},
{
name: "bbb",
price: 20
},
{
name: "ccc",
price: 30
},
{
name: "ddd",
price: 40
},
{
name: "eee",
price: 50
}
]
},
getters: {
saleProducts: (state) => {
var products = state.products.map(item => {
return {
name: "hello~ " + item.name,
price: item.price / 2
};
});
return products;
}
},
mutations: {
reduceProducts: (state, disploy) => {
// setTimeout(() => {
state.products.forEach(item => {
item.price -= disploy;
})
// }, 3000);
}
},
actions: {
reduceProducts: (context, disploy) => {
setTimeout(() => {
context.commit("reduceProducts", disploy)
}, 3000);
}
},
modules: {}
})
mapGetters 辅助函数
mapgetters 辅助函数仅仅是将store中的getters 映射到局部计算属性
看一下之前的getters相关写法:
- src/store/index.js
getters: {
saleProducts: (state) => {
var products = state.products.map(item => {
return {
name: "hello~ " + item.name,
price: item.price / 2
};
});
return products;
}
}
- test5.vue
computed: {
saleProducts() {
return this.$store.getters.saleProducts;
}
},
结合代码来说明一下:上面的这段代码是之前的例子中用到的,它的getters 中只有一个 saleProducts 方法,想在vue页面中用的话,就需要在 computed 通过this.$store.getters.xxx进行调用。那么如果在getters中有很多类似saleProducts 的方法的话,按照之前的做法就是需要在vue页面的 computed 通过this.$store.getters.xxx 一个一个进行调用。这样写很麻烦。。所以就有了mapgetters辅助函数
demo1 使用 mapGetters
- src/store/index.js 这个文件内容不变
- test6.vue
<template>
<div>
<ul v-for="item in saleProducts" :key="item.id">
<li>{{item.name}}</li>
<li>{{item.price}}</li>
</ul>
</div>
</template>
<script>
import { mapGetters } from "vuex";
export default {
computed: {
// saleProducts() {
// return this.$store.getters.saleProducts;
// }
...mapGetters([
"saleProducts",
// 如果你想给saleProducts变个名字的话,可以像下面一样做
// product: "saleProducts",
])
}
};
</script>
<style lang="scss" scoped>
ul > li {
list-style-type: none;
}
</style>
出来的效果和之前通过this.$store.getters.saleProducts一样
mapActions 辅助函数
mapActions 的用法基本和 mapGetters 的用法一样,在methods中直接用就行了
<template>
<div>
<ul v-for="item in saleProducts" :key="item.id">
<li>{{item.name}}</li>
<li>{{item.price}}</li>
</ul>
<button @click="reduce(5)">reduce price</button>
</div>
</template>
<script>
import { mapGetters, mapActions } from "vuex";
export default {
computed: {
// saleProducts() {
// return this.$store.getters.saleProducts;
// }
...mapGetters(["saleProducts"])
},
methods: {
...mapActions({
// 这里的 reduce 对应上面 button 方法中的 reduce
reduce: "reduceProducts"
})
}
};
</script>
<style lang="scss" scoped>
ul > li {
list-style-type: none;
}
</style>
module
直接将state/getters/mutations/actions分隔出去
-
src/store/index.js
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ state: { products: [ { name: "aaa", price: 10 }, { name: "bbb", price: 20 }, { name: "ccc", price: 30 }, { name: "ddd", price: 40 }, { name: "eee", price: 50 } ] }, getters: { saleProducts: (state) => { var products = state.products.map(item => { return { name: "hello~ " + item.name, price: item.price / 2 }; }); return products; } }, mutations: { reduceProducts: (state, disploy) => { state.products.forEach(item => { item.price -= disploy; }) } }, actions: { reduceProducts: (context, disploy) => { setTimeout(() => { context.commit("reduceProducts", disploy) }, 3000); } }, modules: {} })
上面的代码中,state/getters/mutations/actions 都是写在一起的。也可以将它们分开写在不同的js文件,然后引入到上面的index.js文件👇
-
index.js
import Vue from 'vue' import Vuex from 'vuex' import state from './state' import getters from './getters' import mutations from './mutations' import actions from './actions' Vue.use(Vuex) export default new Vuex.Store({ state, getters, mutations, actions, modules: {} }) -
src/store/state.js
export default { products: [ { name: "aaa", price: 10 }, { name: "bbb", price: 20 }, { name: "ccc", price: 30 }, { name: "ddd", price: 40 }, { name: "eee", price: 50 } ] } -
src/store/getters.js
export default { saleProducts: (state) => { var products = state.products.map(item => { return { name: "hello~ " + item.name, price: item.price / 2 }; }); return products; } } -
…
上面这样分隔之后,也可以达到之前的效果。下面就开始分模块来写~
modules的应用
-
src/store/partA.js
export default { state: { productNum: 100 }, getters: { brief: function (state) { return state.productNum + "个商品" } }, mutations: { addProNum(state) { state.productNum++ } }, actions: { changeProNum(context) { setTimeout(() => { context.commit("addProNum") }, 2000); } } } -
src/store/index.js
import Vue from 'vue' import Vuex from 'vuex' import state from './state' import getters from './getters' import mutations from './mutations' import actions from './actions' import partA from './partA' Vue.use(Vuex) export default new Vuex.Store({ state, getters, mutations, actions, modules: { partA } }) -
test7.vue
<template> <div> 测试 modules <!-- 下面这两句效果一样 --> <h3>{{$store.state.partA.productNum}}</h3> <h3>{{partA.productNum}}</h3> <!-- 下面是getters --> <h3>{{brief}}</h3> <!-- 下面是mutations --> <button @click="addProNum">test mutations</button> <!-- 下面是actions --> <button @click="changeProNum">test actions</button> </div> </template> <script> import { mapState, mapGetters, mapMutations, mapActions } from "vuex"; let mapStateObj = mapState(["partA"]); let mapGettersObj = mapGetters(["brief"]); let mapMutationsObj = mapMutations(["addProNum"]); let mapActionsObj = mapActions(["changeProNum"]); export default { computed: { // 对mapStateObj进行解构 ...mapStateObj, ...mapGettersObj }, mounted() { console.log(this); }, methods: { ...mapMutationsObj, ...mapActionsObj } }; </script> <style lang="scss" scoped> </style>
这是默认情况下的界面展示
这是点击了test mutations按钮之后的界面展示。可以看到控制台中有出现mutation对应的内容
下面这张图是点击了test actions按钮之后的界面展示
命名空间 namespaced
默认情况下,模块内部的 action、mutation 和 getter 是注册在全局命名空间的——这样使得多个模块能够对同一 mutation 或 action 作出响应。
如果希望你的模块具有更高的封装度和复用性,你可以通过添加 namespaced: true 的方式使其成为带命名空间的模块。当模块被注册后,它的所有 getter、action 及 mutation 都会自动根据模块注册的路径调整命名
-
src/store/pardB.js
export default { namespaced: true, state: { age: 15 }, getters: { info: function (state) { return state.age + "岁" } }, mutations: { addAge(state) { state.age++ } }, actions: { changeAge(context) { setTimeout(() => { context.commit("addAge") }, 2000); } } } -
test8.vue
<template> <div> modules namespaced test <h3>{{partB.age}}</h3> <h3>{{info}}</h3> <button @click="addAge">mutation test</button> <button @click="changeAge">actions test</button> </div> </template> <script> import { mapState, mapGetters, mapMutations, mapActions } from "vuex"; let mapStateObj = mapState(["partB"]); let mapGettersObj = mapGetters('partB', ['info']); let mapMutationsObj = mapMutations('partB', ['addAge']); let mapActionsObj = mapActions('partB', ['changeAge']) export default { mounted() {}, computed: { ...mapStateObj, // 下面的这三种写法出来的效果都是一样的 ...mapGettersObj, // ...mapGetters('partB', [ 'info' ]), // ...mapGetters({ info: "partB/info" }) }, methods: { ...mapMutationsObj, // ...mapMutations('partB', ['addAge']), // ...mapMutations({ addAge: "partB/addAge" }), ...mapActionsObj, // ...mapActions('partB', ['changeAge']) // ...mapActions({ changeAge: "partB/changeAge" }) } }; </script> <style lang="scss" scoped> </style>
当然,除了上面的这些写法之外,还有一种
通过使用 createNamespacedHelpers 创建基于某个命名空间辅助函数。它返回一个对象,对象里有新的绑定在给定命名空间值上的组件绑定辅助函数
-
test8.vue
<template> <div> modules namespaced createNamespacedHelpers test <h3>{{age}}</h3> <h3>{{info}}</h3> <button @click="addAge">mutations test</button> <button @click="changeAge">actions test</button> </div> </template> <script> import { createNamespacedHelpers } from "vuex"; const { mapState, mapGetters, mapMutations, mapActions } = createNamespacedHelpers('partB') export default { computed: { ...mapState({ age: state => state.age }), ...mapGetters([ 'info' ]) }, methods: { ...mapMutations([ 'addAge' ]), ...mapActions([ 'changeAge' ]) } }; </script> <style lang="scss" scoped> </style>
2889

被折叠的 条评论
为什么被折叠?



