Vuejs  2.0 教程:使用 vuex 重构项目代码
打赏作者

Vuejs 2.0 教程:使用 vuex 重构项目代码

Vue js 2.0 教程 >> Vuejs 2.0 教程:使用 vuex 重构项目代码 视频发布于 2016-11-30

上个视频我们走完了整个 vuex 的基本流程,这个视频我们主要做的事就是使用 vuex 将之前的项目代码进行重构,比如我们之前实现的方法和一些组件,这样重构完成的项目才是一个常用的 SPA 架构的应用。
liudong0763

Jelly 你视频里的delete方法,后端删除的数据和前端删除的数据不一致

JellyBool 回复 liudong0763

是的,像下面这为仁兄说的一样

博闻慎思

delete那个index 是 前端变量 列表的序号,删除几个之后,列表数量跟todo.id就不一样了,应该让删除按钮的那个index等于todo.id , 删除的时候服务器端是根据todo.id进行删除的

JellyBool 回复 博闻慎思

嗯哼,对的。。我看了一下确实是这样

liudong0763 回复 JellyBool

我是这么弄得:

//Todos.vue
deleteTodo(todo,index){
                this.$store.dispatch('deleteTodo',{todo,index})
            }
//main.js
deleteTodo(store,obj){            
Vue.axios.delete('http://laravel.dev/api/todo/'+obj.todo.id+'/delete').then(response=>{
                store.commit('delete_todo',obj.index)
            })
        }
JellyBool 回复 liudong0763

可以的,你可以考虑这样:

deleteTodo(store,payload){            
Vue.axios.delete('http://laravel.dev/api/todo/'+payload.todo.id+'/delete').then(response=>{
                store.commit('delete_todo',payload.index)
            })
        }

我个人觉得 obj 这种命名简直了

liudong0763 回复 JellyBool

哈哈,简直什么啊,被你站点过滤了么?

JellyBool 回复 liudong0763

没有,我只是不太赞同这种变量命名方式。变量是什么就是什么,按照规范和官方的推荐来就好

liudong0763 回复 JellyBool

好的,这个好习惯要学习

flxxyz 回复 liudong0763

老哥,我们想一起去了XD

zhangbao1992 回复 JellyBool

删除功能不是能正常使用吗?@博闻慎思 说得啥意思

JellyBool 回复 zhangbao1992

嗯哼,你注意 index 是 todo 的 id 就 OK

zhangbao1992 回复 JellyBool

我现在的代码是这样的:

// Todos.vue
<a class="list-group-item" v-bind:class="{ 'completed': todo.completed }" v-for="(todo, index) in todos">
  <button class="btn btn-xs btn-danger pull-right" v-on:click='destroy(todo, index)'title="删除">✘</button>
</a>

destroy(todo, index) {
  this.$store.dispatch('deleteTodo', { todo, index })
},

// main.js
mutations: {
  delete_todo (state, index) {
    state.todos.splice(index, 1)
  },
},
actions: {
  deleteTodo (store, payload) {
      Vue.axios.delete('http://localhost:8000/api/todo/' + payload.todo.id + '/delete')
        .then((response) => {
          store.commit('delete_todo', payload.index)
        });
    },
}

并且测试能正常删除,所以不懂“index 是 todo 的 id”是啥意思,怎样操作会出现 @博闻慎思 说的问题呢?

JellyBool 回复 zhangbao1992

你这个代码是没有什么问题的吧。貌似就是上面我评论说明的情况一样。

大概注意一下视频的操作

zhangbao1992 回复 JellyBool

嗯 我测试没问题的

f4cklangzi 回复 博闻慎思

这个问题其实就是dispatch方法只能传两个参数,第三个参数没有传过去才导致错误的对吧

hard88

终于等到更新啦哈哈

wl876645

辛苦啦。。。。请认真发评论哦,至少 6 个字符

524360073

vuex是不是可以这样理解:定义一个store然后把所有的共享变量存放在里面,并且对外提供读写操作接口。如果共享变量被改变,则通过dispatch通知各个组件。

a119347

可以出一个讲解用vuex设置登录页面的课程么

manpai

好久有空录个 小程序的教程系列嘛 相信这个会很火

JellyBool 回复 manpai

没,因为我不会

chenxin
   deletetodo: function (index,todo) {
              this.$store.dispatch("removetodo",index,todo);
            },

dispatch传递两个参数我试了只能接收第一个,第二个接收不到,就算我换了顺序也一样…

JellyBool 回复 chenxin

写成 es6 的方式试试

chenxin 回复 JellyBool

换了也一样…

JellyBool 回复 chenxin

嗯,你看看上面的评论,应该可以先解决你的问题

chenxin 回复 JellyBool

我都试过了!你们上面写的payload.index中的 payload是一个dispatch传过来的todo,但是用payload.index的时候我输出来直接输一个undefined…

JellyBool 回复 chenxin

怎么会undefined…你仔细看看 liudong0763这个小伙伴的回复

chenxin 回复 JellyBool

我现在的解决办法是将

 this.todos.splice(index,1);

写在了dispatch里面的,虽然也能实现一样的效果,但是 不是vuex的那种顺序了…

zhangbao1992 回复 chenxin

我的也出现了这个问题:

dispatch 传递两个参数我试了只能接收第一个,第二个接收不到,就算我换了顺序也一样…

解决方式就是讨论的那样

// Todos.vue
deleteTodo (todo, index) {
  this.$store.dispatch('deleteTodo', {todo, index})
}

// main.js
deleteTodo (store, payload) {            
Vue.axios.delete('http://laravel.dev/api/todo/' + payload.todo.id + '/delete').then(response => {
    store.commit('delete_todo', payload.index)
  })
}
sfabric2016

感觉略麻烦,没有把vuex的特定或优势说出来

aviouy

不发源码上来看看么

julian1009

Jelly 我想问一下,我是打算用cordova把laravel+vue的SPA项目打包成iOS和Android端,其实需要做的就是把index.html文件和生成的app.js文件引入到Cordova的编译的目录下面就可以吗?也就是说实际上最终SPA在页面呈现出来的就是index.html + app.js,可以这样理解吗?

JellyBool 回复 julian1009

我没试过 打包成iOS和Android端 ,要这种的话,参考 weex 解决方案吧

julian1009 回复 JellyBool

嗯,好的,我去看一下。

假如_丶

怎么去创建新的流程么?
比如现在Todos我想加一个Lists,怎么去操作?

JellyBool 回复 假如_丶

没理解错的话,你直接加进去,你取出来的时候对应一下就好了

假如_丶 回复 JellyBool

就是我的所有东西都要写在main.js->App.vue->components->Todos.vue吗?
我要新做一个Lists.vue : main.js->App.vue->components->Lists.vue?但是他也加载Todos的数据了…
没有理解这个东西的流程 - -

JellyBool 回复 假如_丶

多看几遍视频吧。。。。

假如_丶 回复 JellyBool

我的main.js

import Todo from './components/List'

路由也定义了,但是List加载Todo的数据啊

HideStone

在本地开发的时候,用axios,那后端的接口是需要怎么处理一下才能在本地获取到的吗?

JellyBool 回复 HideStone

这是什么意思?

后端的接口是需要怎么处理一下才能在本地获取到的吗
HideStone 回复 JellyBool

已经解决,是因为后端没有解决跨域的问题

leec

后端的代码 可以提供下吗?

JellyBool 回复 leec

稍等,我看看我的代码还在不在,如果在的话,我直接放 Github 吧

leec 回复 JellyBool

谢谢!!感谢!

JellyBool 回复 leec

找了好久。。。貌似找不到了

asion

this.store.dispatch('deleteTodo',{todo,index}) index是作为对象属性传递的,this.store.dispatch(‘deleteTodo’,todo,index})作为变量的形式却获取,这是为什么

asion

作为变量的形式却获取不到

sinchangwen

感谢教程,之前对于 vuex 的理解还不够透彻,看了视频之后把之前使用 vuex 写的项目重构了下。

Alex

按照这个视频一直做,一直有个bug没能解决,就是add todo后,点击complete,必须刷新才能改变其dom状态,很奇怪,不知道什么原因

JellyBool 回复 Alex

新增加的 Task 的 complete 状态,在刚添加的时候点击 complete ,这时的 complete 状态又是什么?

Alex 回复 JellyBool

使用vue的调试工具显示是completed的值是改变的,获取也是正确,就是bind:class和三元判断没起作用,刷新和点击其他非新添加的task的complete,状态又改变了

JellyBool 回复 Alex

这么奇怪,基本就是逻辑上有一丢丢没修正吧

Alex 回复 JellyBool

我在我自己项目上面写了下,结果没出问题,太奇葩了!!!!!!话说vuex这坑踩了1个月,感觉蛮好

vue619

我在win7系统环境下,执行命令npm run dev 的时候 报了 这个错误:(node:740) Unhandled PromiseRejectionWarning: Unhandled promise rejection (rejection id:1): Error: spawn cmd ENOENT 请问这是什么情况啊?

zhangbao1992

@JellyBool 在 main.js 中,complete_todo mutation 有个问题,就是当你新增一个 Todo,然后点击“done” 的时候,按钮样式和文字不会发生改变。

我看了下,这个问题和 @Alex 遇到的问题一样,我是在 Windows 7 系统中写的。

---- 优雅的分割线 ----

我找到原因了,是因为 Laravel Api 创建 Todo 的时候,返回的 $todo 对象里没有 completed 字段!将

Route::post('/todos/create', function (Request $request) {
  $data = $request->only('title', 'desc');
  $todo = Todo::create($data);
  return $todo;
});

// 改为
Route::post('/todos/create', function (Request $request) {
  $data = $request->only('title', 'desc');
  $data = array_merge($data, [
    'completed' => false,
  ]);

  $todo = Todo::create($data);

   return $todo;
});

即可。

JellyBool 回复 zhangbao1992

这个没有改变的话,基本上就是注意 class 的绑定和 text 的渲染。而且很有可能也是这些单引号或者双引号的问题

zhangbao1992 回复 JellyBool

@JellyBool 我找到是上面↑的原因

Young

我也发现了删除的问题,只要修改前端的语法就解决了,修改如下两个文件:

main.js
removeTodo (store, {todo, index}) {
  		Vue.axios.delete('http://laravel-vue.app/api/todo/'+ todo.id + '/delete').then(response => {
  			 console.log(response.data)
  			store.commit('delete_todo',index)
  		
  		})
  	},

todos.vue
  deleteTodo (todo, index){
              this.$store.dispatch('removeTodo', {todo, index})
          },
liujun

Computed property “newTodo” was assigned to but it has no setter.
这?

JellyBool 回复 liujun

新的版本之后,computed 需要设置一下 setter,你直接 google : vuejs was assigned to but it has no sette 应该就有了

liujun

@JellyBool 对比一下之前的做法,在methods方法中可以先操作dom再去axios,这样用户能感觉到操作立刻生效了,体验比较好。但是换成vuex之后,都必须先axios之后才能mutate数据进而操作dom,这样的异步操作感觉慢了很多,总要等response之后才能反映在dom上。
有什么办法能让用户立刻感知response吗?

liujun

newtodo初始化那句,为什么我写在mutation里面就不行呢,mutation也是最后一步啊。报错说加上去的newtodo没有id

liujun

mutations和actions里面的方法名可以写一样的,官方示例也是这样的,个人觉得这样更清晰