zoukankan      html  css  js  c++  java
  • vue组件通信

    参照博客:https://www.jianshu.com/p/7df2576a8a2b

    方法一、prop和$emit

    1.prop--父组件向子组件传值

    a.prop大小写: postTitle 等价于 post-title;

    b.prop类型:

      以数组形式:

    1 props: ['title', 'likes', 'isPublished', 'commentIds', 'author']

      以对象形式:(通常你希望每个 prop 都有指定的值类型)

    1 props: {
    2   title: String,
    3   likes: Number,
    4   isPublished: Boolean,
    5   commentIds: Array,
    6   author: Object,
    7   callback: Function,
    8   contactsPromise: Promise // or any other constructor
    9 }

    c.传递静态或者动态prop

    1 <!-- 静态赋值 -->
    2 <blog-post title="My journey with Vue"></blog-post>
    3 <!-- 动态赋予一个变量的值 -->
    4 <blog-post v-bind:title="post.title"></blog-post>
    5 <!-- 动态赋予一个复杂表达式的值 -->
    6 <blog-post v-bind:title="post.title + ' by ' + post.author.name"></blog-post>

    d.传递的数据可以是字符串、数组、数字、对象、布尔值

     1 //父组件
     2 <template>
     3   <div id="app">
     4     <users v-bind:users="users"></users>//前者自定义名称便于子组件调用,后者要传递数据名
     5   </div>
     6 </template>
     7 <script>
     8 import Users from "./components/Users"
     9 export default {
    10   name: 'App',
    11   data(){
    12     return{
    13       users:["Henry","Bucky","Emily"]
    14     }
    15   },
    16   components:{
    17     "users":Users
    18   }
    19 }
     1 //子组件
     2 <template>
     3   <div class="hello">
     4     <ul>
     5       <li v-for="user in users">{{user}}</li>//遍历传递过来的值,然后呈现到页面
     6     </ul>
     7   </div>
     8 </template>
     9 <script>
    10 export default {
    11   name: 'HelloWorld',
    12   props:{
    13     users:{           //这个就是父组件中子标签自定义名字
    14       type:Array,
    15       required:true
    16     }
    17   }
    18 }
    19 </script>

    2.$emit--子组件向父组件传值(通过事件形式)

     1 // 子组件
     2 <template>
     3   <header>
     4     <h1 @click="changeTitle">{{title}}</h1>//绑定一个点击事件
     5   </header>
     6 </template>
     7 <script>
     8 export default {
     9   name: 'app-header',
    10   data() {
    11     return {
    12       title:"Vue.js Demo"
    13     }
    14   },
    15   methods:{
    16     changeTitle() {
    17       this.$emit("titleChanged","子向父组件传值");//自定义事件  传递值“子向父组件传值”
    18     }
    19   }
    20 }
    21 </script>
     1 // 父组件
     2 <template>
     3   <div id="app">
     4     <app-header v-on:titleChanged="updateTitle" ></app-header>//与子组件titleChanged自定义事件保持一致
     5    // updateTitle($event)接受传递过来的文字
     6     <h2>{{title}}</h2>
     7   </div>
     8 </template>
     9 <script>
    10 import Header from "./components/Header"
    11 export default {
    12   name: 'App',
    13   data(){
    14     return{
    15       title:"传递的是一个值"
    16     }
    17   },
    18   methods:{
    19     updateTitle(e){   //声明这个函数
    20       this.title = e;
    21     }
    22   },
    23   components:{
    24    "app-header":Header,
    25   }
    26 }
    27 </script>

    总结:子组件通过 events 给父组件发送消息,实际上就是子组件把自己的数据发送到父组件。

    方法二、$parent和 $children与 ref

    ref:如果在普通的DOM元素上使用,引用指向的就是DOM元素;如果用在子组件上,引用就指向组件实例。

    $parent / $children:访问父 / 子实例。

    需要注意的是:这两种都是直接得到组件实例,使用后可以直接调用组件的方法或访问数据。

    我们先来看个用 ref来访问组件的例子:

     1 // 子组件
     2 export default {
     3   data () {
     4     return {
     5       title: '这是子组件的数据'
     6     }
     7   },
     8   methods: {
     9     sayHello () {
    10       console.log('hello');
    11 } 12 } 13 }
     1 // 父组件
     2 <template>
     3   <children ref="comA"></children> //首先你的给子组件做标记
     4 </template>
     5 <script>
     6   export default {
     7     mounted () {
     8       const comA = this.$refs.comA;
     9       console.log(comA.title);  // 这是子组件的数据
    10       comA.sayHello();  // hello
    11     }
    12   }
    13 </script>

     用$parent / $children直接访问组件实例

    1 在父组件中
    2 this.$children
    3 在子组件中
    4 this.$parent

    方法三、vuex

    参照博客:https://segmentfault.com/a/1190000015782272

    1.安装vuex

    1 pm install vuex --save

    2.在src文件目录下新建一个名为store的文件夹,为方便引入并在store文件夹里新建一个index.js,里面的内容如下:

    1 import Vue from 'vue';
    2 import Vuex from 'vuex';
    3 Vue.use(Vuex);
    4 const store = new Vuex.Store();
    5 export default store;

    3.接下来,在 main.js里面引入store,然后再全局注入一下,这样一来就可以在任何一个组件里面使用this.$store了:

    1 import store from './store'//引入store
    2 new Vue({
    3   el: '#app',
    4   router,
    5   store,//使用store
    6   template: '<App/>',
    7   components: { App }
    8 })

    4.配置state、getter、mutation、action

     1 import Vue from 'vue';
     2 import Vuex from 'vuex';
     3 Vue.use(Vuex);
     4  const state={   //要设置的全局访问的state对象
     5      showFooter: true,
     6      changableNum:0
     7      //要设置的初始属性值
     8    };
     9 const getters = {   //实时监听state值的变化(最新状态)
    10     isShow(state) {  //承载变化的showFooter的值
    11        return state.showFooter
    12     },
    13     getChangedNum(){  //承载变化的changebleNum的值
    14        return state.changableNum
    15     }
    16 };
    17 const mutations = {
    18     show(state) {   //自定义改变state初始值的方法,这里面的参数除了state之外还可以再传额外的参数(变量或对象);
    19         state.showFooter = true;
    20     },
    21     hide(state) {  //同上
    22         state.showFooter = false;
    23     },
    24     newNum(state,sum){ //同上,这里面的参数除了state之外还传了需要增加的值sum
    25        state.changableNum+=sum;
    26     }
    27 };
    28  const actions = {
    29     hideFooter(context) {  //自定义触发mutations里函数的方法,context与store 实例具有相同方法和属性
    30         context.commit('hide');
    31     },
    32     showFooter(context) {  //同上注释
    33         context.commit('show');
    34     },
    35     getNewNum(context,num){   //同上注释,num为要变化的形参
    36         context.commit('newNum',num)
    37      }
    38 };
    39   const store = new Vuex.Store({
    40        state,
    41        getters,
    42        mutations,
    43        actions
    44 });
    45 export default store;

    而在外部组件里进行全局执行actions里面方法的时候,你只需要用执行:

    this.$store.dispatch('hideFooter')

    或this.$store.dispatch('showFooter')

    以及this.$store.dispatch('getNewNum',6) //6要变化的实参

    想要获取state值:

    this.$store.state

    5.modules 模块化 以及 组件中引入 mapGetters、mapActions 和 mapStates的使用

    因为在大多数的项目中,我们对于全局状态的管理并不仅仅一种情况的需求,有时有多方面的需求,比如写一个商城项目,你所用到的全局state可能是关于购物车这一块儿的也有可能是关于商品价格这一块儿的;像这样的情况我们就要考虑使用vuex中的 modules 模块化了,具体怎么使用modules呢?咱们继续一步一步的走:

    首先,在store文件夹下面新建一个modules文件夹,然后在modules文件里面建立需要管理状态的js文件(collection.js 、footerStatus.js),既然要把不同部分的状态分开管理,那就要把它们给分成独立的状态文件了。

    而对应的store文件夹下面的index.js 里面的内容就直接改写成:

     1 import Vue from 'vue';
     2 import Vuex from 'vuex';
     3 import footerStatus from './modules/footerStatus'
     4 import collection from './modules/collection'
     5 Vue.use(Vuex);
     6 export default new Vuex.Store({
     7     modules:{
     8          footerStatus,
     9          collection
    10     }
    11 });
     1 //collection.js
     2 const state={
     3     collects:[],  //初始化一个colects数组
     4 };
     5 const getters={
     6   renderCollects(state){ //承载变化的collects
     7     return state.collects;
     8   }
     9 };
    10 const mutations={
    11      pushCollects(state,items){ //如何变化collects,插入items
    12         state.collects.push(items)
    13      }
    14  };
    15 const actions={
    16     invokePushItems(context,item){ //触发mutations里面的pushCollects ,传入数据形参item 对应到items
    17         context.commit('pushCollects',item);
    18     }
    19 };
    20 export default {
    21      namespaced:true,//用于在全局引用此文件里的方法时标识这一个的文件名
    22      state,
    23      getters,
    24      mutations,
    25      actions
    26 }
     1 //footerStatus.js
     2  const state={   //要设置的全局访问的state对象
     3      showFooter: true,
     4      changableNum:0
     5      //要设置的初始属性值
     6    };
     7 const getters = {   //实时监听state值的变化(最新状态)
     8     isShow(state) {  //承载变化的showFooter的值
     9        return state.showFooter
    10     },
    11     getChangedNum(){  //承载变化的changebleNum的值
    12        return state.changableNum
    13     }
    14 };
    15 const mutations = {
    16     show(state) {   //自定义改变state初始值的方法,这里面的参数除了state之外还可以再传额外的参数(变量或对象);
    17         state.showFooter = true;
    18     },
    19     hide(state) {  //同上
    20         state.showFooter = false;
    21     },
    22     newNum(state,sum){ //同上,这里面的参数除了state之外还传了需要增加的值sum
    23        state.changableNum+=sum;
    24     }
    25 };
    26  const actions = {
    27     hideFooter(context) {  //自定义触发mutations里函数的方法,context与store 实例具有相同方法和属性
    28         context.commit('hide');
    29     },
    30     showFooter(context) {  //同上注释
    31         context.commit('show');
    32     },
    33     getNewNum(context,num){   //同上注释,num为要变化的形参
    34         context.commit('newNum',num)
    35      }
    36 };
    37 export default {
    38     namespaced: true, //用于在全局引用此文里的方法时标识这一个的文件名
    39     state,
    40     getters,
    41     mutations,
    42     actions
    43 }

    mapState,mapGetters,mapActions的使用:首先 在需要用的 组件里面先导入 import {mapState,mapGetters,mapActions} from 'vuex';

     1 <template>
     2   <div class="children1">
     3     <button class="joinStatus" @click="invokePushItems(item)">加入收藏列 然后跳转到children2页面查看</button>
     4     <li v-for="(val,index) in arrList" :key="index">
     5       <h5>{{val.productName}}</h5>
     6       <p>{{val.price}}</p>
     7     </li>
     8   </div>
     9 </template>
    10 
    11 <script>
    12 import {mapState,mapGetters ,mapActions} from "vuex";
    13 export default {
    14   name: "children1",
    15   data() {
    16     return {
    17       item: {
    18         id: "01",
    19         productName: "苹果",
    20         price: "1.6元/斤"
    21       }
    22     };
    23   },
    24   methods: {
    25     ...mapActions("collection", [
    26       //collection是指modules文件夹下的collection.js
    27       "invokePushItems" //collection.js文件中的actions里的方法,在上面的@click中执行并传入实参
    28     ])
    29   },
    30   computed: {
    31     // ...mapState({  //用mapState来获取collection.js里面的state的属性值
    32     //    arrList:state=>state.collection.collects
    33     // }),
    34     ...mapGetters("collection", {
    35       //用mapGetters来获取collection.js里面的getters
    36       arrList: "renderCollects"
    37     })
    38   }
    39 };
    40 </script>

     方法四、eventBus 兄弟组件通信

    1.使用 eventBus 首先我们创建一个 bus.js 文件,里面的内容如下

    import Vue from 'vue';  
    export default new Vue(); 

    2.在需要使用 eventBus 的组件中引入上面创建的 bus.js 文件。

    import Bus from 'common/js/bus.js';

    3.发布Bus消息的组件

    Bus.$emit('getTarget', event.target);

    4.接收Bus消息的组件

    Bus.$on('getTarget', target => {  
        console.log(target);  
    });

     5.解决多次触发在发布组件添加解绑事件

    beforeDestroy () {
        bus.$off('getTarget')
    },
  • 相关阅读:
    ArcGIS API for javascript开发笔记(四)——GP服务调用之GP模型的规范化制作详解
    ArcGIS API for javascript开发笔记(三)——解决打印输出的中文为乱码问题
    ArcGIS API for javascript开发笔记(二)——解决ArcGIS Service中的服务在内网环境下无法进行javascript预览问题
    解决GP服务产生的结果无法自动发布为地图服务的问题
    解决oracle12c安装报“[INS-30131]执行安装程序验证所需的初始设置失败(原因:无法访问临时位置)”方法
    Pdf File Writer 中文应用(PDF文件编写器C#类库)
    七牛云存储客户端(本人开发,开源)
    如鹏网 net高级技术 第二章 委托和事件(复习)
    如鹏网 net高级技术 第一章 各种知识点(复习)
    写个QuartzHelper类
  • 原文地址:https://www.cnblogs.com/qxp140605/p/11696789.html
Copyright © 2011-2022 走看看