深入探讨Vue.js组件和组件通信
前端之家收集整理的这篇文章主要介绍了
深入探讨Vue.js组件和组件通信,
前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
基本是按照官网的 Guide 全部梳理了一遍: 这里我们以一个 Todo List 应用为例来把相关的只是都串起来,这篇里面的全部代码都在github上
Vue 实例
一个 Vue 应用是由一个 root vue instance 引导启动的,而 Vue instance 是这么创建的:
一个 instance 实际上就是 MVVM 中的一个 VM。 传入的配置对象中data里的所有属性都会被挂载到 instance上,而为了避免命名冲突,Vue 内置方法都会以 $ 开头的属性挂载到 instance 上。
instance 从创建到销毁会经历如下生命周期:
在初始化的时候大致经过三步:
•绑定数据监听,即对 data 的监听
•编译模板
•插入document或者替换对应dom
# Vue 基本语法
数据绑定
Vue 使用的是一种 类 mastache 语法。常用绑定语法分这么几类:
•mastache 语法,比如 {{ data }} {{ data | filter}}
•v-bind 绑定属性,比如 v-bind: href,v-bind:class
•v-on 绑定事件,比如 v-on:click,v-on:submit
其中 v-* 都是 directive
例子:
属性计算
Vue 支持一个很有意思的属性计算语法,可以指定一个属性由其他属性计算出来,这样就不用通过 $watch 来实现了:
## 流程控制和列表相关的语法 包括 `v-if`,`v-show`,`v-else`,`v-for`
表单
双向数据绑定:
Box" id="jack" value="Jack" v-model="checkedNames">
## 动画 动画的实现方式和 Angular 以及 React 都是一样的,都是通过添加和删除 class 来实现的。 # Component
组件的基本用法
Component 的定义包括两部分:
1 创建component类:
Lily
"
});
2 注册一个 tagname:
这样我们就可以通过 tagname 来使用这么组件了:
...
Vue.component("me-profile",Profile); 属于全局注册,如果只是在某一个页面内使用,可以通过局部注册的方式:
其中因为我们的 Vue 实例是绑定在 todo 元素上的,所以如果把 my-profile 放在这个元素外面是无效的,只有放在这个里面才会被 Vue 的这个实例引导初始化。
注意事项:
Vue 构造函数可以传的参数基本都可以用在 Vue.extend 上,但是对 el 和 data 两个参数需要注意,为了避免不同实例间共享同一个对象,总是要通过 function 返回一个新的对象比较靠谱:
因为参数都一样,其实他们俩就是同一个东西,不过一个是组件,一个是用来引导Vue启动的。
模板注意事项
因为 Vue 就是原生的DOM,所以有些自定义标签可能不符合DOM标准,比如想在 table 中自定义一个 tr,如果直接插入 my-component 不符合规范,所以应该这样写:
Props 传递数据
在 Vue 中每个组件都是独立的,不能也不应该直接访问父类的data。所以我们通过 props 来向子组件传递数据,是不是和 React 的方式很像?
不同于 React,在 Vue 中子组件需要先声明自己的 props 才行:
{{name}}'s Todo List
{{name}} is a good girl
`
});
然后我们可以在使用 Profile 的时候这样传递参数:
这种是通过字面量传递参数,所以传递的值一定是字符串。还有一种方式是动态传参,通过 v-bind 来传递参数,可以双向绑定数据或者传非字符串参数:
v-bind 如果是一个字符串,则是绑定父组件的data中对应的字段,比如上面就是双向绑定了 input 的值。如果是一个数字则就是绑定了一个数字。
Vue 还可以显式指定单向还是双向的数据绑定:
<child :msg.sync="parentMsg">
<child :msg.once="parentMsg">
Props 校验
一个好的组件总是应该先验证参数是否正确,另外可能还需要设置一些参数的默认值:
父子组件通信
上面讲到的 props 其实就是父组件向子组件传递消息的一种方式。
在子组件中有一个 this.$parent 和 this.$root 可以用来方法父组件和根实例。不过,现在我们应该避免这么做。因为组件本身就是为了封装独立的逻辑,如果又去直接访问父组件的数据就破坏了组件的封装性。
所以我们应该还是应该通过父组件向子组件传递 props 的方式来通信。
当然 props 其实只能做回调。在 React 中就探讨过这个问题,React 的做法就是通过 props 来做,传一个回调函数给子组件。其实我不是很喜欢这种把回调函数传来传去的方式,我更喜欢的是事件的方式。Vue 中子组件可以通过通过事件和父组件进行通信的。向父组件发消息是通过 this.$dispatch,而向子组件发送消息是通过 this.$boardcast,这里都是向所有的父亲和孩子发送消息,但是一旦执行一个回调之后就会停止,除非这个回调函数显式返回了 true。
我们把之前的Todo List拆成不同的组件来实现,这样可以体验下如何进行组件的双向通信,我们拆分出两个组件,分别是 List 和 Form 。
Form 负责处理用户输入,并在提交表单的时候向父组件发送一个 add 消息,代码如下:
{{username}}'s Todo List
`,methods: {
add: function() {
this.$dispatch("add",this.input); //这里就是向父组件发送消息
this.input = "";
}
}
});
List 只负责展示列表和处理用户勾选操作,它接收到 add 消息之后会在自己上添加一个条目:
`,props: {
initList: {
type: Array
}
},data: function() {
return {
list: []
}
},events: {
add: function(input) {
if(!input) return false;
this.list.unshift({
title: input,done: false
});
}
}
});
然后,因为这是两个组件,当然需要一个 Vue 实例来引导启动,我们的实例如下:
注意,其实 Form 和 List 在逻辑上是平级的组件,所以他们没有父子关系,他们共同都是 vm 的孩子。这里 vm 接到 Form 的消息之后会转发给 List。
html 代码就更简单了: