摘要:我在中写了这段代码在组件被创建时候将会执行此函数相当于进入页面的自执行使用方法监听属性并执行一个回调函数按道理在元素被创建的时候,会将监听到的值赋给并且打印。
天地不仁以万物为刍狗,宇宙无义视众生如蝼蚁
——萧鼎和我
上一节列出了5个关键点,第一个路由已经解决了,接下来解决第二个问题:
组件的通信问题
一、组件的关系
组件之间的关系无非就是两种父子关系和没有父子关系。为什么我这样说呢?
按道理应该还有兄弟关系(也就是并列的组件,比如一个组件中引用了hreder和footer组件。),还有爷孙关系(比如我有七个Calabash Brothers组件,放在的HanHan组件下,而HanHan组件放在了Chairman Mao组件下)
那么不应该是父子、爷孙、兄弟关系吗?
然而并不是,因为我看了vue的文档。他的意思就是父子通信和非父子通信。
二、父子之间的通信——Prop和自定义事件
组件实例的作用域是孤立的。这意味着不能并且不应该在子组件的模板内直接引用父组件的数据。
prop 是父组件用来传递数据的一个自定义属性。子组件需要显式地用 props 选项声明 “prop”。
将我们的App.vue当作父组件,将test当作子组件(什么当作,本来就是)。
在App.vue中修改我们的
在Test.vue中接收,并在页面中显示:
我是全英雄联盟最骚的骚猪
说: {{say}}
然后在浏览器的显示效果如下:
综上所述可以看出,其实所谓的prop就是在
上面的例子很漂亮的把父传子的通信方式展现出来了。但是子传父呢?
vue文档中使用的自定义事件。
使用 $on(eventName) 监听事件
使用 $emit(eventName) 触发事件
我们还是用APP.vue作为父组件,Test.vue作为子组件
App.vue
... /*增加一个位置来显示子组件传过来的值*/我儿子对我说: {{noSay}}
/* 增加一个自定义的事件mychild,并给他指定触发的方法*/... data () { return { noSay: "" // 用来接收子组件穿过来的数据 } }, methods: { toFatherSay: function(massage) { // mychlid事件触发调用的方法 this.noSay = massage // massage就是子组件穿过来的内容 } }
Test.vue
.... /*增加一个按钮,一点击就向父组件传值*/ .... data() { return { massage: "我才不说呢" // 定义一个向父组件传递的值 } }, methods: { toFather: function() { // 按钮点击触发的方法 this.$emit("myChild",this.massage)// 使用$emit来向父组件传播 } }, ....
做完以上操作之后在浏览器上测试:
三、非父子关系之间的通信——eventBus
在veu文档上,非父子之间的通信是通过使用一个空的Vue实例作为中央事件总线。
空的Vue实例? and 中央事件总线?
空的Vue实例也就是说
var bus = new Vue(); // 的确是一个空的
中央事件总线,难道组件通信要通过全局的事件来进行?
的确是这样,vue提供了$emit和$on方法来进行参数监听(其实就是个发布订阅模式)。
创建一个空的Vue实例 Bus.js:
import Vue from "vue" export default new Vue();
将我们的Apart.vue和Bpart.vue当作非父子关系组件:
Apart.vue
我是Apart
点我切换
Bpart.vue
然后在浏览器中测试一下:
有问题!!!无论怎么点击我们发现Bpart中定义的whiteSay并没有改变,并且第一次点击控制台没有打印。我在Bpart中写了这段代码:
data () { return { whiteSay: "nihao" } }, created: function() { // 在组件被创建时候将会执行此函数 相当于进入页面的自执行 Bus.$on("whiteSay", function(data) { // 使用$on方法监听white属性并执行一个回调函数 this.whiteSay = data console.log(this.whiteSay) }); }
按道理在元素被创建的时候,会将监听到的值赋给whiteSay并且打印。但是我们注意到第一次点击,两个操作都没有执行,也就是说没有监听到whiteSay值的变化。而第二次之后都监听到了。这是为什么?为什么把值赋给data中定义的whiteSay之后没有网页没有更新?
带着这两个问题我去问了度娘和股哥。一下是答案:
第一个为什么: 项目中使用了vue-router,会先加載新的組件,等新的組件渲染好但是還沒掛載前,銷毀舊組件,在掛載新組件。将Apart.vue的代码修改为:
... methods: { goPage: function () { this.$router.push("/bb") } }, /*Vue 实例销毁后调用 就是所谓的生命周期钩子*/ destroyed() { Bus.$emit("whiteSay", "克里斯,关下门") // 使用$emit方法创建一个键值对 }, ...
这样第一个问题就解决了。附上找到的答案连接:https://segmentfault.com/q/10...
第二个为什么:这个是我自己代码有问题,问了隔壁大神。说是我的作用域有问题,将Bpart.vue中的代码改为:
··· created: function() { // 在组件被创建时候将会执行此函数 相当于进入页面的自执行 var _self = this; // 将当前作用域保存在变量中,和$on()的作用域区分开来 Bus.$on("whiteSay", function(data) { // 使用$on方法监听white属性并执行一个回调函数 _self.whiteSay = data console.log(_self.whiteSay) }); } ···
这样所有的问题就都解决了。
四、Vuex
当我使用了上面几种方法来实现组件的通信存在着一些缺陷。比如父组件向子组件传一个值,子组件将值处理完了返回给父组件,这将同时用到prop和自定义事件。还不如直接写一个所有组件都可以访问的变量呢来得方便呢。比如:
/*这是vuex文档中的例子*/ const sourceOfTruth = {} const vmA = new Vue({ data: sourceOfTruth }) const vmB = new Vue({ data: sourceOfTruth })
再比如当项目过大,组件之间的通信将变得难以管理。veux的初衷就是为何更好的管理组件的状态。一下是vuex文档对vuex的定义:
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到 Vue 的官方调试工具 devtools extension,提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。
写得好累,还好最近没事做,不会被boss骂。
接下来直接开始使用vuex。
先下载
在根目录下打开cmd:
npm install vuex -save
下载成功看到一下数据:
C:Users59227Desktopx-chat>npm install vuex --save x-chat@1.0.0 C:Users59227Desktopx-chat `-- vuex@2.1.1 npm WARN optional Skipping failed optional dependency /chokidar/fsevents: npm WARN notsup Not compatible with your operating system or architecture: fsevents@1.0.15
然后在main.js中引用,并安装到Vue上面
import Vuex from "vuex" Vue.use(Vuex)
前面两步将Vuex引入到了项目当中,接下来如何使用Vuex。
Vuex的核心是一个store(仓库)这个仓库的作用就是用来管理应用中的state(状态)。这里状态该怎么理解?
我个人的理解是:所有组件共享的并可以进行更改的对象。
除了state的,store还有getter、Mutations、Actions以及Modules。在vuex文档中都有非常详细的说明:http://vuex.vuejs.org/zh-cn/s...
笼统的说:
组件获取 state 用 vuex 的 getter
组件触发动作用 vuex 的 action
修改 state 用 vuex 的 mutation
知乎上看到的,说得很贴切易懂。
直接上代码,建议撸完代码,再去看一遍vuex的文档。
main.js
.... const store = new Vuex.Store({ //创建一个仓库 state: { showDagger: true, // 定义一个状态 }, mutations: {// 定义 mutation ,更改 Vuex 的 store 中的状态的唯一方法是提交mutation daggerCtrl (state) { // 一定要传入state,并且是第一个参数 state.showDagger = !state.showDagger // 将showDagger值取反 } } }) /* eslint-disable no-new */ new Vue({ el: "#app", router, // 将router对象传给vue,这样就可以通过this.$router获取到router对象了 store, // 将store对象传给vue,这样就可以通过this.$store获取到store对象了 template: "", components: { App } })
然后更改App.vue:
我儿子对我说: {{noSay}}
1.添加按钮和组件
dagger.vue
Dagger
打开浏览器 看效果:
使用vuex实现组件通信就搞定了,更多的用法请参考vuex文档。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/86718.html
摘要:在离开过渡被触发时生效,在完成之后移除。可以链式的多次使用和用法相同,但是的元素会始终渲染并保存在中,只是改变值。用法如下对应前面的数据 在我一生的黄金时代,我有好多奢望。我想爱,想吃,还想在一瞬间变成天上半明半暗的云。 ——王小波上一章研究了vue中组件的通信,算是对vue的组件通信有了大致的了解。综合上三章对搭建项...
摘要:用法如下注册全局的指令注册一个全局自定义指令当绑定元素插入到中。具体代码如下当组件中需要用到其他的组件时,需要使用属性去创建一个哈希表。具体用法如下包含组件引入组件在中添加组件的哈希表收尾除了上面这些属性,还有一些杂项详情请看官网 后来我才知道,生活就是个缓慢受锤的过程,人一天天老下去,奢望也一天天消失,最后变得像挨了锤的牛一样。 ...
摘要:借我杀死庸碌的情怀,借我纵容的悲怆与哭喊谢知非上一节已经把架子搭好了,接下来就要开始真正的使用进行开发了。一启动原理打开我们的目录,能看到这样的结构很简单有木有,存放资源。一个字符串模板作为实例的标识使用。模板将会替换挂载的元素。 借我杀死庸碌的情怀,借我纵容的悲怆与哭喊 - 谢知非 上一节已经把架子搭好了,接下来就要开始真正的使用vue2.0进行开...
摘要:先看看兼容性创建连接构造函数接收两个参数这里的不能是或者而是对应的或者和是定义的两种方案,类似于类似于协议名称,是可选的。服务端和客户端的协议名称必须一致。协议有三种注册协议,开放协议,自定义协议。限制以内就是在构造函数中选传的参数。 愿天下所有的情侣,都是失散多年的兄妹 ——好妹妹webScoket是html5提出的一个协议,咱们用的http是无状态...
摘要:主要表现在复杂的语句事务支持等。仅支持,在等浏览器中,会出现样式布局混乱的情况。将群群对应的聊天记录保存在数据库。用户进入群聊,则将其加入到对应的中。文件大小不能超过通过模块操作登录注册将用户名作为唯一值。登录支持自动登录,将密码保存在中。 showImg(https://segmentfault.com/img/bV4jYr?w=402&h=710);showImg(https://...
阅读 2892·2021-11-25 09:43
阅读 3593·2021-08-31 09:41
阅读 1197·2019-08-30 15:56
阅读 2072·2019-08-30 15:55
阅读 2895·2019-08-30 13:48
阅读 2781·2019-08-29 15:15
阅读 916·2019-08-29 15:14
阅读 2615·2019-08-28 18:26