对Vue组件实现单项数据流而不是双向数据流的困惑?

我有一个分页组件是这样写的:

Vue.component('hawkeye-pager',{
    props: ['pageindex', 'totalpage', 'much'],
    template: '<ul class="pager">\
                <li><a href="#" @click="changePage(1, $event)" id="home">首页</a></li>\
                <li><a href="#" @click="changePage(pageindex - 1, $event)" v-if="pageindex!=1 && totalpage!=1" id="page-up">上一页</a></li>\
                <template v-for="n in much">\
                    <li v-if="pageindex-much-1+n>0 && pageindex-much-1+n!=pageindex">\
                        <a href="#" @click="changePage(pageindex-much-1+n,$event)" >{{pageindex-much-1+n}}</a>\
                    </li>\
                </template>\
                <li><a href="javascript:void(0)" id="page-active">{{pageindex}}</a></li>\
                <template v-for="n in much">\
                    <li v-if="pageindex+n<=totalpage">\
                        <a href="#" @click="changePage(pageindex + n,$event)" >{{pageindex + n}}</a>\
                    </li>\
                </template>\
                <input type="number" v-model="pageindex" min="1" :max="totalpage" step="1">\
                <li><a href="#" @click="changePage(pageindex,$event)" id="skip">跳转</a></li>\
                <li><a href="#" @click="changePage(pageindex + 1,$event)" v-if="pageindex!=totalpage && totalpage!=1" id="page-next">下一页</a></li>\
                <li><a href="#" @click="changePage(totalpage,$event)" id="trailer-page">尾页</a></li>\
            </ul>',
    methods: {
        changePage: function ( page , event) {
            event.preventDefault();
            this.pageindex = page;      // 这条语句vue不允许
            this.$emit('change');
        }
    },
    data: function(){
        return {page: this.pageindex}
    }
});

大概的样子是这样:

调用分页组件是的代码是这样的:

<hawkeye-pager @change="someTestFunction" :much="2" :pageindex="pageindex" :totalpage="totalpage"></hawkeye-pager>

vue在控制台里报了一个警告:

[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "pageindex" 
(found in <HawkeyePager>)

现在我就困惑了:我怎么知道用户点击分页子组件的时候,点击的是哪一页呢?

vue官方介绍,实现父子组件单项数据流的原因有[两个](http://cn.vuejs.org/v2/guide/components.html#单向数据流):

  • prop 作为初始值传入后,子组件想把它当作局部数据来用

  • prop 作为初始值传入,由子组件处理成其它数据输出。

可是我这里就是想把prop当全局数据来用,怎么办呢?

使用vuex来统一存储/管理应用的全局数据.

:sob:还不会用,哭泣哭泣。除了使用vuex还有其它方法吗?

非常惭愧啊,看文档不精,别人有介绍了。

vue老版本中用$dispatch,子组件传递把需要向父组件传递的值通过$dispatch自定义一个事件,并传值,然而在新版中$dispatch也要废弃了。vue2.0中可以使用$emit来向父组件派发事件,父组件中用$on来监听自定义的事件,监听后父组件执行具体的方法,且通过事件传递给父组件的数据,以该方法的参数形式传入,父组件在所要执行的函数中得以使用。

<!-- 子组件test -->
var data = {
	a:11,
	b:22
}
this.$emit("senddata", data);


父组件:

<test v-on:senddata="getData"></test>
methods: {
        getData:function(data){
            console.log("子组件传递的数据:",data);
        }
    }

这样既可在vue中实现基本的父子组件的通信。

详情看这里

http://chayangge.com/2016/11/30/vue父子组件之间通信/

父子组件之间的通信确实用不到vuex,如果是非父子组件之间的通信以及共享全局prop.就要考虑vuex了

1 Like

通过事件的沟通 emit listener. 通常是 同级之间的组件的沟通。

父子组件之间的沟通的话可以可以通过 父组件给子组件传递 callback 的方式.
Parent Component

  html:
  <child :onSubmit="onSubmit" />

  script:
  onSubmit(data){
     ... do some thing with the data.
  }

Child :

 child
 ...
 props :['onSubmit']
 submit(){
  if(this.onSubmit) this.submit(this.data)
 }

我自己的总结是:

父子 prop
子父 prop callback methods
同级&全局 event

引用当时 redux 的一句话 “如果你有疑问你应不应该用 redux 的时候,你就不应该用。”
vuex 同理。 当你有一些 appliaction 级别的数据的时候, 你就不得不用 vuex 来管理了。

你写的是伪代码吗?
这个介绍了父子组件沟通的问题:http://chayangge.com/2016/11/30/vue%E7%88%B6%E5%AD%90%E7%BB%84%E4%BB%B6%E4%B9%8B%E9%97%B4%E9%80%9A%E4%BF%A1/

算是。。 我理解的。。 关键代码
看了这篇文章的。 都可以。

我是之前 react 和 angular 都是这么写的。
Vue 这边我查了下 官方文档 好像是也是建议写成 emit 的方式。
那就写成 emit 的方式好了。

1 Like