Android组件间通信--深入理解Intent与IntentFilter

Understanding Intent and IntentFilter--理解Intent和IntentFilter
Intent(意图)在Android中是一个十分重要的组件,它是连接不同应用的桥梁和纽带,也是让组件级复用(Activity和 Service)成为可能的一个重要原因。Intent的使用分为二个方面一个是发出Intent,另一个则是接收Intent用官方的说法就是Intent Resolving。本主将对Intent和IntentFilter进行一些介绍。
Intent和IntentFilter是Android和一种消息通信机制,可以让系统的组件之间进行通信。信息的载体就是Intent,它可以是一个要完成的动作请求,也可以一般性的消息广播,它可以由任意一个组件发出。消息,也就是Intent,最终也是要被组件来进行处理和消化。消息由组件发出,通常在消息的里面也会有会标记有目标组件的相关信息,另外目标组件也需要告诉系统,哪些消息是它所感兴趣的,它需要设置一些过滤器,以过滤掉无关的消息。

其实这里就好比学校里的广播,广播有时会播放通知,但有时也会播放要执行的动作,比如打扫卫生。消息中通常都会说明消息的目标对象,可能是计算机学院,可能是老师,也可能是英语系的人才需要关注。而每个人,或是学院组织,也只关心与他们有关的消息,当然这里就要他们自己去判断哪些是与他们有关的消息了。在Android当中消息就是Intent,过滤器就是IntentFilter。发出消息的组件可以在消息中设置目标组件的相关信息,目标组件也可以设置过滤器,然后系统会进行过滤,只把组件所感兴趣的消息,传递给组件。这里假设读者已经了解Intent和IntentFilter的基本使用方法,且并不会进行全面的介绍,如果不了解,可以先读读官方文档,这里重点讲讲IntentFilter在使用时的一些注意事项。
Intent消息机制通常有二种,一个是显式Intent(Explicit Intent),另一个是隐式Intent(Implicit Intent)。
•显式Intent--需要在Intent中明确指定目标组件,也就是在Intent中明确写明目标组件的名称(Component name),需要指定完整的包名和类名。因为对于本程序以外的其他应用程序,你很难知道它的组件名字,所以显式的Intent通常用于应用程序内部通信,更确切的说,显示Intent是用于应用程序内部启动组件,通常又是Activity或Service。还没有见用显式Intent来给BroadcastReceiver发送广播的。
•隐式Intent--也就是不在Intent中指定目标组件,在Intent中不能含有目标的名字。系统是根据其他的信息,比如Data,Type和Category去寻找目标组件。
隐式Intent通常用于与应用程序外部的组件进行通信。应用程序级别的组件复用也主要是靠隐式Intent来完成的。而IntentFilter也是只有隐式Intent才用的着,显式Intent都是直接把Intent传递给目标组件,根本不会理会组件的IntentFilter。
显式Intent(Explicit Intent)
显示Intent使用起来比较简单,只需要在Intent中指定目标组件的名字即可,也就是通过Intent的方法设置Component属性。如前所述,显式Intent通常用于应用程序内部启动Activity或Service。事实上,并不完全局限在应用程序内部,对于外部应用的Activity和Service,也可以用显式Intent来启动,但你必须知道它们的名字。
设置组件的名字的方法有:


代码如下:

public Intent setComponent(ComponentName component);
public Intent setClass(Context packageContext, Class<?> cls);
public Intent setClassName (Context packageContext, String className);
public Intent setClassName (String packageName, String className);

事实上虽然设置的方法有这么多,但Intent内部标识目标组件的属性只有一个Component,所以这么设置方法的目的也只是设置目标组件的Component,事实上有这么多的方法原因在于ComponentName的构造是多重载了的。在解析Intent时,系统也是取得这个Component属性,然后去启动它。
ComponentName Intent.getComponent();
对于应用程序内部启动Activity通常是这样子设置Intent:


代码如下:

Intent i = new Intent();
       // Select one of them
       i.setComponent(new ComponentName(getApplication(), ViewStubDemoActivity.class));
       i.setComponent(new ComponentName(getApplication(), ViewStubDemoActivity.class.getName()));
       i.setComponent(new ComponentName(getApplication().getPackageName(), ViewStubDemoActivity.class.getName()));
       i.setClass(getApplication(), ViewStubDemoActivity.class);
       i.setClassName(getApplication(), ViewStubDemoActivity.class.getName());
       i.setClassName(getApplication().getPackageName(), ViewStubDemoActivity.class.getName());
       startActivity(i);

因为应用程序内部的组件类,都是可以访问到的,所以要尽可能少写字串常量,以减少拼写错误,如果一定要使用包名和类名,也要注意,类名必须是全称,也就是从包名开始,如“com.hilton.networks.WifiManagerActivity"。
但是对于外部应用程序的Activity,通常只能通过以下方法:


代码如下:

Intent i = new Intent();
       // select one of them
       i.setComponent(new ComponentName("com.hilton.networks", "com.hilton.networks.WifiManagerActivity"));
       i.setClassName("com.hilton.networks", "com.hilton.networks.WifiManagerActivity");
       startActivity(i);

首先,带有Context为参数的是不能够用的,因为通常你无法拿到其他应用程序的Context,你只能拿到你所在应用程序的Context,所以用你所在的应用程序的Context去启动外部的Activity肯定会报错的。其次,不参再像上面那样通过Class.getName()去指定类名,你为你无法导入外部的类,会有编译错误的。另外,千万要注意不要拼错,否则会有RuntimeException抛出的。
对于Service组件,也是一样,Intent的写法与Activity组件一致,但是对于BroadcastReceiver组件通常都用显式Intent。
隐式Intent的消息过滤器--IntentFilter
IntentFilter是用来解析隐式Intent(Implicit Intent)的,也就是说告诉系统你的组件(Activity, Service, BroadcastReceiver)能够处理哪些隐式的Intent。在使用的时候我们通常是这样子的:


代码如下:

<manifest ...>
    <receiver ...>
           <intent-filter>
              <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
              <action android:name="android.appwidget.action.APPWIDGET_ENABLED" />
              <action android:name="android.appwidget.action.APPWIDGET_DISABLED" />
              <action android:name="android.appwidget.action.APPWIDGET_DELETED" />
           </intent-filter>
           <intent-filter>
              <action android:name="android.intent.action.MEDIA_MOUNTED"/>
              <action android:name="android.intent.action.MEDIA_UNMOUNTED"/>
              <action android:name="android.intent.action.MEDIA_SHARED"/>
              <action android:name="android.intent.action.MEDIA_REMOVED"/>
              <action android:name="android.intent.action.MEDIA_EJECT"/>
              <data android:scheme="file" />
           </intent-filter>
           <intent-filter>
              <action android:name="android.intent.action.PACKAGE_ADDED"/>
              <action android:name="android.intent.action.PACKAGE_REMOVED"/>
              <action android:name="android.intent.action.PACKAGE_DATA_CLEARED"/>
              <data android:scheme="package" />
           </intent-filter>
   </receiver>
</manifest>

在Manifest中使用IntentFilter时要注意以下三点:
1. 千万注意拼写错误
这里有一个需要十分小心和注意的地方那就是对于IntentFilter里面的Action和Data字串常量不要写错,因为这个在编译时是不会被检查,在运行时又不会抛出异常,如果你拼写错了,比如大小写拼错了,在编译时和运行时都不会有错误,但是你的程序却不能正常工作,你的程序无法收到相应的Intent。曾有一个同事在IntentFilter中写了一些Action,但把其中一个的大小写拼错了,结果花了他一个下午的时间来调试,最后还是另外一个同事到他那聊天才发现了是大小写的拼写错误。
这里也可以发现Android在Manifest文件中的IntentFilter这块的封装性很差。如果,仅仅是如果,这些Action常量也可以通过引用的方式来写,就可以在编译时做些检查和匹配,可以大大的减少出错的机率,同时也加强了封装和信息隐藏。比如,对于上面的可以写成这样:


代码如下:

<manifest ...>
    <receiver ...>
           <intent-filter>
              <action android:name="@android:action/AppWidgetManager.APPWIDGET_UPDATE" />
              <action android:name="@android:action/AppWidgetManager.APPWIDGET_ENABLED" />
              <action android:name="@android:action/AppWidgetManager.APPWIDGET_DISABLED" />
              <action android:name="@android:action/AppWidgetManager.APPWIDGET_DELETED" />
           </intent-filter>
   </receiver>
</manifest>

虽然这种拼写错误很低级,但是因为它低级所以当程序不能正常工作时没有人会想到是因为拼写错误,所以这种拼写错误通常会耗费不少的调试时间。另外一种避免此种错误的方法就是在代码中通过Context.registerReceiver(BroadcastReceiver,IntentFilter)来注册BroadcastReceiver,就可以直接写入常量,而非具体字串。但这只能是接收Broadcast的时候,对于那些想作为公开接口的组件,还是需要在Manifest里面声明,比如Email,它要能处理Intent.ACTION_SEND_TO,就需要在Manifest中声明。
2. 要注意Data字段除了上面讨论的之外,对于IntentFilter还有另外的一点需要注意,就是对于某些Action是需要加上Data字段信息,否则有可能接收不到。比如:


代码如下:

<manifest ...>
    <receiver ...>
           <intent-filter>
              <action android:name="android.intent.action.MEDIA_MOUNTED"/>
              <action android:name="android.intent.action.MEDIA_UNMOUNTED"/>
              <action android:name="android.intent.action.MEDIA_SHARED"/>
              <action android:name="android.intent.action.MEDIA_REMOVED"/>
              <action android:name="android.intent.action.MEDIA_EJECT"/>
              <data android:scheme="file" />
           </intent-filter>
           <intent-filter>
              <action android:name="android.intent.action.PACKAGE_ADDED"/>
              <action android:name="android.intent.action.PACKAGE_REMOVED"/>
              <action android:name="android.intent.action.PACKAGE_DATA_CLEARED"/>
              <data android:scheme="package" />
           </intent-filter>
   </receiver>
</manifest>

对于手机外部存储卡的状态变化的Broadcast,在注册监听器的时候就需要加上DataScheme,否则就会接收不到。这个也花费了我几个小时的调试时间,改在代码中用Context.registerReceiver(BroadcastReceiver,IntentFilter)注册也不行,最后参考了Music中的做法,加上了DataScheme才能在onReceive()中接收到Intent。同样对于后面的Package相关的Broadcast,也是要加上DataScheme否则也是接收不到Broadcast。可悲的是对于像这样的系统公共的Broadcast
Intent,在Intent的文档中并没有说明如何使用,如果没有参考事例,相信需要一定的时间才能够找出为什么接收不到Intent。
除了DataScheme还有一个是MimeType,这个对于系统公共接口是必须加上的,比如Email要处理Intent.ACTION_SENTTO,就需要这样声明:


代码如下:

<manifest ...>
    <activity android:name="EmailComposer">
           <intent-filter>
              <action android:name="android.intent.action.SEND"/>
              <data android:mimeType="image/*" />
           </intent-filter>
   </activity>
</manifest>

3. 同时也要注意Category字段
如果没有对IntentFilter写正确的Category字段,也是收不到Intent。比如:


代码如下:

<manifest ...>
    <receiver ...>
            <intent-filter>
                <action android:name="com.hilton.controlpanel.action.BUTTON_ACTION" />
                <category android:name="com.hilton.controlpanel.category.SELF_MAINTAIN" />
            </intent-filter>
   </receiver>
</manifest>

如果把Category去掉,死活也接收不到Intent,当然这要取决于Intent是如何发出的,如果Intent发出时没有加Category,那就没有必须在IntentFilter加上Category。
总之,对于Intent,要保证发出和接收完全一致,否则系统就无法找到相应的匹配,程序也就无法接收Intent。
有关于 DEFAULT category,也要注意,如果是针对Activity的Implicit Intent隐式Intent,如果在没有其他Category的情况下,一定要加上DEFAULT Category。因为系统会在Context.startActivity(Intent)和Context.startActivityForResult(
Intent)时给Intent加上DEFAULT category。而对于Context.sendBroadcast(Intent),Context.sendOrderedBroadcast(Intent),Contxt.sendStickyBroadcast(Intent)和Context.bindService(Intent)Context.startService(Intent)就不会加DEFAULT Category。
另外要注意,尽量把Action进行合并写进一个IntentFilter中。因为对于每个IntentFilter标签都会创建一个IntentFilter对象,所以如果写几个就会有几个对象在那,不但耗费资源而且在匹配的时候也会耗费更多的时间,因为在查询匹配的时候是要一个IntentFilter对象接着一个IntentFilter对象进行检查的。直到找到最佳匹配或是到所有的IntentFilter都检查完为止。
IntentFilter的匹配规则
1. 通过Action字段来匹配这个是Intent中比较基本的一个字段,也比较简单,就是一个字串,如果相等就匹配成功,否则证明还没找到目标。但要注意,如果IntentFilter没有指定Action,那么它不会匹配到任何的隐式Intent,它只能被显式的Intent匹配上。反过来,如果Intent自己没有指定Action,那么它能匹配上含有任何Action的IntentFilter,但不能匹配上没有指定Action的IntentFilter。对于Action,平时要注意拼写错误,因为在AndroidManifest文件中声明Action都是字串,并且在编译时不会做检查,运行时,如果Action拼错了导致匹配不上,要么是程序不能正常工作,要么会有异常抛出。
2. 通过Category字段来匹配对于Activity来讲,如果想处理隐式Intent,并且除了Intent.ACTION_MAIN以外,必须指定Category为DEFAULT,否则不会被匹配到。因为Context.startActivity()和Context.startActivityForResult()会自动加上DEFAULT Category。其他情况,Service和BroadcastReceiver则不会,对于Service和BroadcastReceiver,如果Intent中没有指定Category,那么在其IntentFilter中也不必指定。
3. 通过Data字段来匹配这个相对来讲比较复杂,通常Data包含uri, scheme(content, file, http)和type(mimeType)对于Intent来讲有二个方法:


代码如下:

Intent.setData(Uri); //一个Uri,Scheme包含在其中
Intent.setType(String); //指定MimeType,比如'image/jpeg', 'audio/mpeg'等
Intent.setDataAndType(Uri, String); //上面二个方法的简便调用方式,一起搞进去

对于IntentFilter来讲,需要设置的是Scheme和Type,Scheme是对Uri的限制,目标需要限制Scheme是因为Scheme能告诉目录能从哪里拿到Uri所指向的文件,Type是MimeType对类型的限制。


代码如下:

<intent-filter>
           <action android:name="android.intent.action.SEND" />
           <category android:name="android.intent.category.DEFAULT" />
           <data android:scheme="content" android:mimeType="image/*" />
      </intent-filter>

Data匹配时的规则一共有四条:
a.如果Intent没有指定Data相关的字段,只能匹配上没有指定Data的IntentFilter。也就是说如果一个Intent没有指定任何的Data(Uri和Type),它只能匹配到没有指定任何Data(Scheme和Type)的IntentFilter。
b.如果一个Intent只指定了Uri但是没有Type(并且Type也不能够从Uri中分析出)只能匹配到仅指定了相应Scheme且没有指定Type的IntentFilter。实际的例子有如果一个Intent是想要发邮件,或是打电话,它们的Intent是类似这样的:"mailto:someone@sb.com"和"tel:1234567"。换句话说,这些Uri本身就是数据,而不再是一个指向数据的地址。比如:Phone中的Dialer就有如下的IntentFilter:


代码如下:

<intent-filter>
    <action android:name="android.intent.action.CALL" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:scheme="tel" />
</intent-filter>

再如,要处理SD状态变化的IntentFilter:


代码如下:

<intent-filter>
      <action android:name="android.intent.action.MEDIA_MOUNTED"/>
      <action android:name="android.intent.action.MEDIA_UNMOUNTED"/>
      <action android:name="android.intent.action.MEDIA_SHARED"/>
      <action android:name="android.intent.action.MEDIA_REMOVED"/>
      <action android:name="android.intent.action.MEDIA_EJECT"/>
      <category android:name="android.intent.category.DEFAULT" />      
      <data android:scheme="file" />
</intent-filter>

再如,要处理Package状态变化的IntentFilter:


代码如下:

<intent-filter>
      <action android:name="android.intent.action.PACKAGE_ADDED"/>
      <action android:name="android.intent.action.PACKAGE_REMOVED"/>
      <action android:name="android.intent.action.PACKAGE_DATA_CLEARED"/>
      <category android:name="android.intent.category.DEFAULT" />
      <data android:scheme="package" />
<intent-filter>

但是注意,对于想对数据进行操作的Intent,最好不要只指定Uri,而不指定类型。因为如果这样做通常会匹配到一大堆
c. 如果一个Intent只指定了Type,但是没有指定Uri,它只能匹配到只指定了相应Type且没有指定Scheme的IntentFitler
d. 如果一个Intent即有Uri又有Type,那么它会匹配上:1).Uri和Type都匹配的IntentFilter;2).首先Type要匹配,另外如果Intent的Uri是content:或file:,且IntentFilter没有指定Scheme的IntentFilter。因为对于Android来讲content和file这二种Scheme是系统最常见也是用的最多的,所以就当成缺省值来对待。
另外需要注意,Type,因为是MimeType,所以是允许使用通配符的,比如'image/*',能匹配上所有以'image'为开头的类型,也说是说能匹配上所有的图像。
根据Data匹配的例子
假如系统中有四个Activity,A的IntentFilter是这样子的:


代码如下:

<activity ...>
            <intent-filter>
                <action android:name="android.intent.action.SEND" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:scheme="content" android:mimeType="image/*" />
            </intent-filter>
   </activity>

这表明A可以发送一切图片类型,并且内容必须是由ContentProvider提供的,也就是Uri必须是以"content://"开头的
而另外一个Activity B是这样子声明的:


代码如下:

<activity ...>
            <intent-filter>
                <action android:name="android.intent.action.SEND" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:scheme="file" android:mimeType="image/*" />
            </intent-filter>
   </activity>

这表明B可以发送一切图片,但内容必须是单独的一个文件,也就是Uri必须是由"file://"开头的
还有一个C是这样子声明的:


代码如下:

<activity ...>
            <intent-filter>
                <action android:name="android.intent.action.SEND" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
   </activity>

这表明C只能接收那些没有指定任何Uri和Type的Action是SEND的Intent。
而D是这样子声明的:


代码如下:

<activity ...>
            <intent-filter>
                <action android:name="android.intent.action.SEND" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="image/*" />
            </intent-filter>
   </activity>

这表明D可以发送一切图片,无论是数据库内的(content),还是单独的文件(file)。
如果一个Intent是这样写的:


代码如下:

Intent share = new Intent(Intent.ACTION_SEND);
startActivity(share);

那么它只能匹配C,因为C没有指定数据和类型,Action是SEND,根据规则a,它只能匹配Activity A。但如果给Intent加上额外的条件


代码如下:

share.setDataAndType(uri,"image/jpeg");

那么如果uri是数据库内容,它会匹配到A,如果它是一个文件,会匹配到B。但无论是content还是file都会匹配到D,因为它能处理以任何形式存储的图片。但始终不会匹配到C,因为C没有声明Data字段,所以不会匹配上。
所以,通常想把组件作为系统公用接口时都是这样子来写:


代码如下:

<activity ...>
            <intent-filter>
                <!-- implement public actions such as View, Edit, Pick or Send -->
                <action android:name="android.intent.action.SEND" />
                <!-- never forget default category, otherwise your activity never receives intents -->
                <category android:name="android.intent.category.DEFAULT" />
                <!-- specify mimeType to constrain data type, receive data from both content provider and file -->
                <data android:mimeType="image/*" />
                <!-- specify scheme to constrain data source, if necessary -->
                <data android:shceme="http" />
            </intent-filter>
   </activity>

Intent和IntentFilter对于组件Activity来讲注意事项比较多,但是对于Service和BroadcastReceiver来说就没有那么多的注意事项了,因为对于Service和BroadcastReceiver通常都不用设置Category和Data。但也有例外,比如前面所讲到的SD相关广播和应用程序安装相关广播。
另外要注意,如果使用Context.startActivity()或Context.startActivityForResult(),Context.bindService()和Context.startService(),如果系统没有为Intent匹配到目标Activity和Service那么会有RuntimeException(ActivityNotFoundException)抛出;如果有多个目标同时匹配,会以列表的方式来让用户选择使用哪个。
使用IntentFilter匹配来进行查询可用的组件
Intent和IntentFilter不但可以用来进行组件复用,还可以用于查询系统内都有哪里组件能做哪些事情。比如Launcher上面会列出很多的应用,其实这种说法不准确,应该是上面列出了所有的能启动一个应用的组件(比如,Dialer和Contacts同属于一个应用程序Contacts中,但是在Launcher里面却有二个,一个是Dialer一个是Contacts。那么Launcher是如何做到的呢?它不可能是去检查系统文件,看看哪些应用程序文件存在,然后再列出来。它是通过查询Intent的方式,把所有含有"android.intent.action.MAIN"和"android.intent.category. LAUNCHER"的Activity的相关信息都取出来,然后列出它们的名称和Icon。同样,我们也可这样来获得具体相应特征的组件

(0)

相关推荐

  • Android 中IntentFilter的匹配规则实例详解

    IntentFilter的匹配规则 IntentFilter的使用 假如我们要隐式启动一个Activity我们需要成功匹配activity中的任意一个intent-filter.如果要成功匹配该intent-filter我们需要完全匹配该intent-filter中的 action.category.data. 示例: <activity android:name=".MainActivity"> <intent-filter> <action andro

  • Android组件间通信--深入理解Intent与IntentFilter

    Understanding Intent and IntentFilter--理解Intent和IntentFilterIntent(意图)在Android中是一个十分重要的组件,它是连接不同应用的桥梁和纽带,也是让组件级复用(Activity和 Service)成为可能的一个重要原因.Intent的使用分为二个方面一个是发出Intent,另一个则是接收Intent用官方的说法就是Intent Resolving.本主将对Intent和IntentFilter进行一些介绍.Intent和Inte

  • 深入理解Android组件间通信机制对面向对象特性的影响详解

    组件的特点对于Android的四大组件Activity, Service, ContentProvider和Service,不能有Setter和Getter,也不能给组件添加接口.原因是组件都是给系统框架调用的,开发者只能实现其规定的回调接口,组件的创建与销毁都是由系统框架控制的,开发者不能强行干预,更没有办法获取组件的对象.比如Activity,Service,BroadcastReceiver,你没有办法去创建一个Activity,Service或BroadcastReceiver,然后像使

  • 详解Angualr 组件间通信

    Angualr 组件间通信 约定: 遵循Angular官方的说法,下文中的AngularJS代指1.x版本,Angular代指Angular2及以后的升级版本. 采用Angular(或者任意MV*)的前端框架开发单页应用(SPA)时,我们都可能会遇见如下的场景: A组件和B组件之前需要相互通信,或是A路由状态需要知道B路由状态的信息等等业务需求. 这个时候就需要设计到采用一套合理的通信方案来解决数据同步,数据通信的问题. AngularJS 组件间的数据通信 在AngularJS中,也就是Ang

  • vue之父子组件间通信实例讲解(props、$ref、$emit)

    组件是 vue.js 最强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用.那么组件间如何通信,也就成为了vue中重点知识了.这篇文章将会通过props.$ref和 $emit 这几个知识点,来讲解如何实现父子组件间通信. 在说如何实现通信之前,我们先来建两个组件father.vue和child.vue作为示例的基础. //父组件 <template> <div> <h1>我是父组件!</h1> <child>

  • Vue如何实现组件间通信

    1. 父子间通信 最常见的就是父子之间的通信,通信是双向的数据传递. 1.1 父组件 --> 儿子组件 父组件向儿子组件传递数据的方式就是 通过 Prop 向子组件传递数据. //child.vue <template> <div> 我是儿子,我收到来自父亲的数据为 {{value}} </div> </template> <script> export default { props:{ value: String } } //App.v

  • Android线程间通信 Handler使用详解

    目录 前言 01.定义 02.使用 第一步.创建 第二步.发送消息 第一种是 post(Runnable) 第二种是 sendMessage(Message) 第三步.处理消息 03.结语 前言 Handler,可谓是面试题中的一个霸主了.在我<面试回忆录>中,几乎没有哪家公司,在面试的时候是不问这个问题的.简单一点,问问使用流程,内存泄漏等问题.复杂一点,纠其源码细节和底层 epoll 机制来盘你.所以其重要性,不言而喻了吧. 那么今天让我们来揭开 Handler 的神秘面纱.为了读者轻松易

  • vue组件间通信子与父详解(二)

    接着vue组件父与子通信详解继续学习. 二.组件间通信(子组件传值给父组件) 通过事件的方式来完成数据的传输. ①在父组件中 定义一个方法,用来接收子组件所通过事件传来的值 methods:{ recvMsg:function(msg){ //参数msg就是子组件通过事件出来的数据 } } ②绑定事件处理函数 事件一般情况 都是自定义事件 <child-component @myEvent="recvMsg"></child-component> ③在子组件触发

  • vue组件间通信解析

    组件间通信(父子,兄弟) 相关链接\组件通信:点击查看 学习链接:Vue.js--60分钟快速入门点击查看 分分钟玩转Vue.js组件点击查看 父组件传子组件 父传子方法(一) 属性传递 props //子组件 <template> <ul> <li v-for="item in dataList">{{item}}</li> </ul> </template> <script> export defa

  • 详解Vue2中组件间通信的解决全方案

    前言 在Vue中组件是实现模块化开发的主要内容,而组件的通信更是vue数据驱动的灵魂,下面这篇文章将给大家介绍关于Vue2组件间通信的相关内容,下面话不多说,来一起看看详细的介绍. 组件通讯包括:父子组件间的通信和兄弟组件间的通信.在组件化系统构建中,组件间通信必不可少的. 父组件--> 子组件 1. 属性设置 父组件关键代码如下: <template> <Child :child-msg="msg"></Child> </templat

  • Vue 父子组件、组件间通信

    本人对Vue组件间通信不懂,搜索了很多关于Vue 父子组件间通信介绍,下面我来记录一下,有需要了解Vue 父子组件.组件间通信的朋友可参考.希望此文章对各位有所帮助. <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>组件</title> <meta name="viewport"

随机推荐