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

Vuex的四大核心

1.state 驱动应用的数据源
2.mutations 基因突变 类如C# 属性get set
3.actions 行为
4.getters 读取器

上图中绿色虚线包裹起来的部分就是Vuex的核心, state中保存的就是公共状态, 改变state的唯一方式就是通过mutations进行更改. 可能你现在看这张图有点不明白, 等经过本文的解释和案例演示, 再回来看这张图, 相信你会有更好的理解.

如何引入Vuex?

1.npm install vuex

2.装好了之后,在全局上去使用你的Vuex

3.创建Store对象,最好在src创建一个store这样的文件夹然后创建index.js

4.在main.js中注册使用

import Vuex from 'vuex'

Vue.use( Vuex );

const store = new Vuex.Store({
//待添加
}) new Vue({
el: '#app',
store,
render: h => h(App)
})

  

为了讲解Vuex,我们做了一个项目,这个项目需要连接apicloud,异步操作使用了axios以及样式bootstrap,其中包括了登录注册以及其中的父组件向子节点传值等,我们给项目安装相关的modules

npm install bootstrap
npm install axios

router.js

import Vue from 'vue'
import Router from 'vue-router' Vue.use(Router) export default new Router({
routes: [
{
path: '/',
name: 'index',
component:()=>import('../views/index.vue')
},
{
path:'/detail/:id',
name:'detail',
component:()=>import ('../views/detail.vue')
},
{
path:'/login',
name:'login',
component:()=>import ('../views/login.vue')
},
{
path:'/register',
name:'register',
component:()=>import ('../views/register.vue')
}
]
})

store.js

 

我们来上述代码中来讲解其中vuex的奥秘,State就是所有组件提出来的data,用于所有组件公共数据,而其中mutations就像C#中get\set,属性赋值器,其中方法的两个参数除了state只能带一个参数。

actions是操作数据的方法,说过说你的actions中需要改变state中的数据,那么必须要通过commit关键字去提交给mutations,还有一点就是actions中很多操作都是关于异步处理的,最关键就是它是操作state数据的,那getters是什么呢?它是组件访问vuex的入口,里面写好了方法去操作,它也是过滤器,就像程序中的三层架构BLL.

main.js

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
import boostrap from 'bootstrap/dist/css/bootstrap.css'
import store from './store/index.js' Vue.config.productionTip = false /* eslint-disable no-new */
new Vue({
el: '#app',
router,
store,//在全局对象上加载仓库
components: { App },
template: '<App/>'
}) 

两个组件

import Vue from 'vue'
import Vuex from 'vuex'
import API from '../utils/api.js' var api = new API('goods')
var userApi = new API('userinfo'); Vue.use(Vuex); const state = {
user: null,
products: []
}
const mutations = {
//加载产品数据
INIT_PRODUCTS(state, data) {
state.products = data;
},
SET_LOGIN_USER(state, u) {
state.user = u;
}
}
const actions = {
LOAD_PRODUCTS({ commit }) {
api.Select().then(res => {
commit('INIT_PRODUCTS', res.data);
})
},
LOGIN({ commit }, user) {
return userApi.Select().then(res => {
let users = res.data;//所有的用户
for (let u of users) {
if (u.name == user.name && u.password == user.password) {
commit('SET_LOGIN_USER', u);
return u;
}
}
})
},
REGISTER({ commit }, user) {
return userApi.Insert(user).then(res => {
console.log(res.data);
return 'OK';
}).catch(err => {
return err;
})
} }
const getters = {
ALL_PRODUCTS(state) {
return state.products;
},
GET_PRODUCT_BYID: (state) => function (id) {
//遍历 is == id
for (let p of state.products) {
if (p.id == id) {
return p;
}
}
return null;
}
} //仓库
const store = new Vuex.Store({
state: state,
mutations: mutations,
actions: actions,
getters: getters
})
export default store;

  

navbar.vue

<template>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container">
<a class="navbar-brand" href="#">购物车</a>
<ul class="navbar-nav ml-auto">
<li class="nav-item active dropdown" v-if="user!==null">
<a class="nav-link dropdown-toggle" data-toggle="dropdown" @click="showDropdown=!showDropdown">欢迎你:{{user.name}} </a>
<div class="dropdown-menu show">
<a class="dropdown-item" href="#">我的订单</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" >注销</a>
</div>
</li>
<li class="nav-item active" style="margin-right:5px" v-if="user===null">
<router-link class="nav-link btn btn-warning btn-sm" style="color:#fff" to="/login">登录</router-link>
</li>
<li class="nav-item active" v-if="user===null">
<router-link class="nav-link btn btn-danger btn-sm" style="color:#fff" to="/register">注册</router-link>
</li>
</ul>
</div>
</nav>
</template> <script>
export default {
data(){
return{
showDropdown:false
}
},
computed:{
user(){
return this.$store.state.user;
} }
}
</script>

  

product.vue 该组件用于显示商品的详细信息

<template>
<div class="card">
<img class="card-img-top" src="../../assets/logo.png" alt="Card image cap">
<div class="card-body">
<h5 class="card-title">{{product.name}}</h5>
<p class="card-text">{{product.description===null?"暂无描述":product.description}}</p>
<p>价格: {{product.price}}</p>
<a href="#" class="btn btn-warning float-left" @click="goDetail">查看详情</a>
<a href="#" class="btn btn-primary float-right">加入购物车</a>
</div>
</div>
</template> <script>
export default {
props:['product'],
methods:{
goDetail(){
console.log(this.product.id);
this.$router.push(`/detail/${this.product.id}`);
}
}
}
</script>

  

程序入口APP.vue

<template>
<div id="app">
<nav-bar></nav-bar>
<router-view></router-view>
</div>
</template> <script>
import NavBar from './views/components/navbar'
export default {
name: 'App',
components:{NavBar}
}
</script>

注册:通过this.$store.dispatch去调用actions中的方法,其中有趣的是commit的参数竟然被方法名给..这个以后在思考。。

<template>
<div class="container">
<div class="row">
<div class="card" style="margin:50px auto;width:400px">
<div class="card-body">
<h5 class="card-title">注册</h5>
<hr>
<div class="form-group">
<label for="">用户名</label>
<input type="text" class="form-control" v-model="user.name">
</div>
<div class="form-group">
<label for="">真实姓名</label>
<input type="text" class="form-control" v-model="user.realname">
</div>
<div class="form-group">
<label for="">密码</label>
<input type="password" class="form-control" v-model="user.password">
</div>
<div class="form-group">
<button class="btn btn-primary btn-block" @click="register">注册</button>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data(){
return{
user:{
name:'',
realname:'',
password:''
}
}
},methods:{
register(){
this.$store.dispatch('REGISTER',this.user).then(res=>{
if(res=="OK")
this.$router.push('/index');
})
}
}
}
</script> 

  

 登录

<template>
<div class="container">
<div class="row">
<div class="card" style="margin:50px auto;width:400px">
<div class="card-body">
<h5 class="card-title">登录</h5>
<hr>
<div class="form-group">
<label for="">用户名</label>
<input type="text" class="form-control" v-model="user.name">
</div>
<div class="form-group">
<label for="">密码</label>
<input type="password" class="form-control" v-model="user.password">
</div>
<div class="form-group">
<button class="btn btn-primary btn-block" @click="login">登录</button>
</div>
</div>
</div>
</div>
</div>
</template> <script>
export default {
data(){
return {
user:{
name:'',
password:''
}
}
},
methods:{
login(){
this.$store.dispatch('LOGIN',this.user).then(res=>{
console.log(res);
if (res){
this.$router.push('/')
}
})
}
}
}
</script>
 主页面 <template>
<div class="container">
<h1>商品列表</h1>
<div class="row">
<div class="col-md-4" v-for="p in products" :key="p.id">
<!-- 传递商品信息到子组件 -->
<product-card :product="p"></product-card>
</div>
</div>
</div>
</template> <script>
import ProductCard from './components/product.vue'
export default {
components:{ProductCard},
computed:{
products(){
return this.$store.getters.ALL_PRODUCTS;
}
},
created(){
this.$store.dispatch('LOAD_PRODUCTS');
}
}
</script>

  

本文结语知识总结:

获取url中的参数

let id = this.$route.params.id;
this.details = this.$store.getters.GET_PRODUCT_BYID(id);

有的小伙伴在复制我的代码运行报错,说什么未初始化;一定要在index.vue添加这个代码,LOAD_PRODUCTS给数据初始化

    created(){
this.$store.dispatch('LOAD_PRODUCTS');
}

跳转路由

this.$router.push('/')

ApiClound万能帮助类

import crypto from 'crypto'     // 加密
import axios from 'axios'
class API {
constructor(classname){
this.api = `https://d.apicloud.com/mcm/api/${classname}`;
let ID = '';
let KEY = '';
let now = Date.now(); //当前时间
let sha1 = crypto.createHash('sha1');
sha1.update(ID + "UZ" + KEY + "UZ" + now);
axios.defaults.headers["X-APICloud-AppId"] = ID;
axios.defaults.headers["X-APICloud-AppKey"] = sha1.digest('hex') + "." + now;
} Select(){
return axios.get(this.api);
}
Insert(obj){
return axios.post(this.api,obj);
}
Update(id,obj){
// RESTFUL API
return axios.put(this.api+`/${id}`,obj);
}
Delete(id){
return axios.delete(this.api + `/${id}`);
}
} export default API;

  

 还有同学问我父组件和子组件如何传值?

在父页面引用的地方以":"表示的值都可以在子页面的props获取到

<template>
<div>
<h3>图书管理</h3><hr>
<div class="row">
<div class="col-md-4 col-sm-4" v-for="b in books" :key="b.id">
<book-detail @abc="xyz" :Book="b" :MSG="abc"></book-detail>
</div>
</div>
</div>
</template>
<script>
import BookDetail from './components/BookDetails.vue'
export default{
components:{BookDetail},
data(){
return {
abc:'heheda',
books:[{
id:1,
name:'7天 JAVA 从入门到放弃',
text:'到底是人性的扭曲,还是道德的沦丧. 青年男子为何突然脱发,中年男人为何删库跑路。',
price:20,
img:'img2.jpg',
showHehe:true
},{
id:2,
name:'7天 C# 从入门到自杀',
text:'到底是人性的扭曲啊,还是道德的沦丧啊. 祖国的花朵为何自杀。',
price:20,
img:'../../static/img2.jpg',
showHehe:false
}]
}
},
methods:{
xyz(bid){
alert(bid);
}
}
}
</script>

  

在子页面中可以这么搞

<script>
export default{
props:["Book","MSG"],
created(){
console.log(this.Book.name);
},
methods:{
select(id){
this.$emit('abc',id);
},
detail(bid){
this.$router.push(`/admin/Details/${bid}`);
}
}
}
</script>

 而其中的$emit是可以调用父页面的方法的。

谢谢大家收看!!!

Vuex的基本概念、项目搭建、入坑点的更多相关文章

  1. IDEA下Maven项目搭建踩坑记----2.项目编译之后 在service层运行时找不到 com.dao.CarDao

    项目写的差不多 想运行一下,然后发现运行到Service层的时候报错说找不到Dao层文件 ,纠结半天之后看了下编译好的项目文件,发现mapper文件下边是空的, 于是就百度找一下原因,结果说是IDEA ...

  2. IDEA下Maven项目搭建踩坑记----1.pom,xml文件下${spring-version}不能用

    因为pom.xml文件是直接复制别人配好的web环境,所以在粘贴进去的之后有一部分没有粘贴到,因此出现爆红 解决方法:↓↓↓↓ 代码: <project.build.sourceEncoding ...

  3. IDEA下Maven项目搭建踩坑记----3.最长的bug,最简单的错误。同一类中,部分函数的@AutoWired注入的对象失效

    这个错误绝对是我写到现在为止最傻X的一个错误,先上图 问题: 出了一个特别长的错误,大致的意思就是mapper.xml文件注入Dao层的时候失败. 解决: 查看一下错误的位置→ 找到Dao层 找到错误 ...

  4. 入坑cordova

    原文:入坑cordova 因项目需要入坑cordova,奔跑吧骚年,目前只是要求安卓平台,下面都是以安卓为例 最好的学习资料还是官网. https://cordova.apache.org/ http ...

  5. SpringBoot入坑-项目搭建

    对于学过三大框架的小童鞋,从今天开始给大家带来一套新的框架学习,相信对于做程序的小童鞋一定有所耳闻,作为下一代java开发框架springboot,减去了繁琐的xml配置,相信用过spring.sta ...

  6. 《Asp.Net Core3 + Vue3入坑教程》-Net Core项目搭建与Swagger配置步骤

    简介 <Asp.Net Core3 + Vue3入坑教程> 此教程仅适合新手入门或者前后端分离尝试者.可以根据图文一步一步进操作编码也可以选择直接查看源码.每一篇文章都有对应的源码 教程后 ...

  7. Vue入坑教程(二)——项目结构详情介绍

    之前已经介绍了关于Vue的脚手架vue-cli的安装,以及一些文件目录介绍.具体可以查看<vue 入坑教程(一)--搭建vue-cli脚手架> 下面简单说一下具体的文件介绍 (一) pac ...

  8. 《Asp.Net Core3 + Vue3入坑教程》 - Vue 1.使用vue-cli创建vue项目

    简介 <Asp.Net Core3 + Vue3入坑教程> 此教程适合新手入门或者前后端分离尝试者.可以根据图文一步一步进操作编码也可以选择直接查看源码.每一篇文章都有对应的源码 目录 & ...

  9. 初入angular4——实际项目搭建总结

    前言 接到一个pc端后台项目,还会加入两个安卓同事一起学习和做这个项目,需要带一下他们. 既ng1之后,我就没怎么有过其它后台框架的实际项目经验了,期间用的移动端框架也并非vue.angular系列. ...

  10. 1、 小白带你入坑xamarin系列之环境搭建和准备

    重点提示 由于xamarin发展更新很快 目前教程部分内容已经过时 请注意下载最新版本   2018.05.23 www.xamarin.com 1. 小白带你入坑xamarin系列之环境搭建和准备 ...

随机推荐

  1. Codeforces 959F Mahmoud and Ehab and yet another xor task 线性基 (看题解)

    Mahmoud and Ehab and yet another xor task 存在的元素的方案数都是一样的, 啊, 我好菜啊. 离线之后用线性基取check存不存在,然后计算答案. #inclu ...

  2. 今天分享三种方法实现Linux系统调用,感兴趣的朋友可以参考一下

    系统调用(System Call)是操作系统为在用户态运行的进程与硬件设备(如CPU.磁盘.打印机等)进行交互提供的一组接口.当用户进程需要发生系统调用时,CPU 通过软中断切换到内核态开始执行内核系 ...

  3. Pycharm 项目无法导入自己写的模块(问题记录贴)

    问题背景: 从外部导入一个Python项目后,发现包错误,如图: 解决步骤: 1.将目录下的"5-6——apriori.py"复制一份,重命名为”apriori.py": ...

  4. python基础day1

    一.python介绍 1.1简介 Python  (英国发音:/ˈpaɪθən/ 美国发音:/ˈpaɪθɑːn/), 是一种面向对象的解释型计算机程序设计语言,由荷兰人Guido van Rossum ...

  5. Flask速成项目:Flask实现计算机资源的实时监控

    很多人都说使用Python开发WEB应用非常方便,那么对于WEB新手来说,到底有多方便呢?本文即将展示给你Python的魔法. 本文将通过一个实例:Flask实现计算机资源的实时监控,迅速带你入门Fl ...

  6. ISP PIPLINE (十二) Sharpening

    什么是sharpening? 不解释,从左到右为sharpen , 从右到左为blur. 简单理解为边缘增强,使得轮廓清晰.增强对比度. 如何进行sharpening? 下面是实际sharpen的过程 ...

  7. POJ3436 Command Network [最小树形图]

    POJ3436 Command Network 最小树形图裸题 傻逼poj回我青春 wa wa wa 的原因竟然是需要%.2f而不是.2lf 我还有英语作业音乐作业写不完了啊啊啊啊啊啊啊啊啊 #inc ...

  8. ESP-01S刷ESPEasy固件,接入HA

    首先下载ESPEasy最新版 https://github.com/letscontrolit/ESPEasy/releases 准备接线从ESP01S到USB-TTL TTL——ESP01S 3.3 ...

  9. Python算术运算

    一.算术运算1.四则运算1+(100-20)/4+5*22.乘方运算2**103.求摸运算7%5 4.取整运算  7//5 = 1 5.绝对值函数  abs(-100) 6.导入数学函数后才能执行类似 ...

  10. LoadRunner(四)——深度了解LR相关功能

    参考学习感谢:<精通软件性能测试与LoadRunner实战> 相关功能: 1 无工具情况下的性能测试 2性能测试工具LoadRunner的工作原理 3 VuGen应用介绍 4 协议的类型及 ...