前言: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. Solr的配置和在java中的使用

    Solr是一个全局站内搜索引擎,可以快速的搜索出结果. Solr依赖于tomcat,把Solr的war包放到tomcat中即可运行. 使用solr,需要在solr的schema.xml中配置solr与 ...

  2. AddIn 中当前完整文件名的获取

    Me.Application.ActiveWorkbook.Name 需要注意的是:只有当前文件已经存档的情况下,才能获得后缀名.

  3. java 堆、栈、方法区/ 类变量、成员变量、局部变量

    方法区:类信息.类变量(静态变量和常量).方法 堆:对象.成员变量 栈:局部变量 (1)当程序运行时,首先通过类装载器加载字节码文件,经过解析后装入方法区!在方法区中存了类的各种信息,包括类变量.类常 ...

  4. Flink解析kafka canal未压平数据为message报错

    canal使用非flatmessage方式获取mysql bin log日志发至kafka比直接发送json效率要高很多,数据发到kafka后需要实时解析为json,这里可以使用strom或者flin ...

  5. Logstash 6.4.3 导入 csv 数据到 ElasticSearch 6.4.3

    本文实践最新版的Logstash从csv文件导入数据到ElasticSearch. 本文目录: 1.初始化ES.Kibana.Logstash 2.安装logstash文件导入.过滤器等插件 3.配置 ...

  6. 读 Spring实战 遇到的问题记录(一)

    package soundsystem; import beanConfig.CDPlayerConfig; import org.junit.Rule; import org.junit.Test; ...

  7. 如何解决PeopleSoft Process Scheduler发布问题

    常见PeopleSoft进程调度程序发布问题 此发布问题中遇到的一些常见错误是: 将HTTP响应转换为UCS2时出错 XML文档对象创建失败. 无法处理来自Report Repository的HTTP ...

  8. 微信小程序之canvas绘制海报分享到朋友圈

    绘制canvas内容 首先,需要写一个canvas标签,给canvas-id命名为shareBox <canvas canvas-id="shareBox"></ ...

  9. 如何把if-else代码重构成高质量代码

    原文:https://blog.csdn.net/qq_35440678/article/details/77939999 本文提纲: 为什么我们写的代码都是if-else? 这样的代码有什么缺点? ...

  10. Servlet 过滤器Filter

    特点 1)Filter是依赖于Servlet容器,属于Servlet规范的一部分,在Servlet API中定义了三个接口类:Filter, FilterChain, FilterConfig. 2) ...