精华内容
下载资源
问答
  • Vue2.0 传值方法
    2021-10-29 16:07:16

    Vue2.0 传值方法

    在Vue的框架开发的项目过程中,经常会用到组件来管理不同的功能,有一些公共的组件会被提取出来。这时必然会产生一些疑问和需求?比如一个组件调用另一个组件作为自己的子组件,那么我们如何进行给子组件进行传值呢?如果是电商网站系统的开发,还会涉及到购物车的选项,这时候就会涉及到非父子组件传值的情况。当然你也可以用Vuex状态管理工具来实现,这部分我们后续会单独介绍。

    引用官网的一句话:父子组件的关系可以总结为 prop 向下传递,事件向上传递。父组件通过 prop 给子组件下发数据,子组件通过事件给父组件发送消息,如下图所示:

    接下来,我们通过实例来看可能会更明白一些:

    1. 父组件向子组件进行传值props


    父组件:

    <template>
      <div>
        父组件:
        <input type="text" v-model="name">
        <br>
        <br>
        <!-- 引入子组件 -->
        <child :inputName="name"></child>
      </div>
    </template>
    <script>
      import child from './child'
      export default {
        components: {
          child
        },
        data () {
          return {
            name: ''
          }
        }
      }
    </script>
    子组件:
    <template>
      <div>
        子组件:
        <span>{{inputName}}</span>
      </div>
    </template>
    <script>
      export default {
        // 接受父组件的值
        props: {
          inputName: String,
          required: true
        }
      }
    </script>


    2. 子组件向父组件传值$emit,父组件通过子组件的ref属性获取值


    子组件:

    <template>
      <div>
        子组件:
        <span>{{childValue}}</span>
        <!-- 定义一个子组件传值的方法 -->
        <input type="button" value="点击触发" @click="childClick">
      </div>
    </template>
    <script>
      export default {
        data () {
          return {
            childValue: '我是子组件的数据'
          }
        },
        methods: {
          childClick () {
            // childByValue是在父组件on监听的方法
            // 第二个参数this.childValue是需要传的值
            this.$emit('childByValue', this.childValue)
          }
        }
      }
    </script>


    父组件:

    <template>
      <div>
        父组件:
        <span>{{name}}</span>
        <br>
        <br>
        <!-- 引入子组件 定义一个on的方法监听子组件的状态-->
        <child v-on:childByValue="childByValue"></child>
      </div>
    </template>
    <script>
      import child from './child'
      export default {
        components: {
          child
        },
        data () {
          return {
            name: ''
          }
        },
        methods: {
          childByValue: function (childValue) {
            // childValue就是子组件传过来的值
            this.name = childValue
          }
        }
      }
    </script>


     

    尽管有 prop 和事件,但是有时仍然需要在 JavaScript 中直接访问子组件。
    为此可以使用 ref 为子组件指定一个引用 ID。例如:

    <div id="parent">
      <user-profile ref="profile"></user-profile>
    </div>
    var parent = new Vue({ el: '#parent' })
    // 访问子组件实例
    var child = parent.$refs.profile


    当 ref 和 v-for 一起使用时,获取到的引用会是一个数组,包含和循环数据源对
    应的子组件。
    $refs 只在组件渲染完成后才填充,并且它是非响应式的。它仅仅是一个直接
    操作子组件的
    应急方案——应当避免在模板或计算属性中使用 $refs。

    具体使用方法:

    父组件

    <template>
      <div id="app">
        {{ a }}
        <button @click="getchild">通过ref得到子组件的值</button>
        <!-- 使用组件 -->
        <three ref="mesage"/>
      </div>
    </template>
    <script>
     
     
    import three from './components/three'
     
    export default {
      components:{
        three,
      },
      data(){
        return {
          a:'我是父组件',
        }
      },
      methods:{
        getchild(){
           // 通过this.$refs调用
          console.log(this.$refs.mesage.mes)
        }
      }
    }
    </script>


     
     
    子组件: 

    <template>
        <div class="three">
            {{mes}}
        </div>
    </template>
     
    <script>
        export default {
          data() {
            return {
                mes:'666'
            };
          }
        };
    </script>


     
     

    3. 事件总线 $emit / $on
     

    非父子组件之间传值,需要定义个公共的公共实例文件bus.js,作为中间仓库来传值,不然路由组件之间达不到传值的效果。这种方法通过一个空的Vue实例作为中央事件总线(事件中心),用它来触发事件和监听事件,巧妙而轻量地实现了任何组件间的通信,包括父子、兄弟、跨级。当我们的项目比较大时,可以选择更好的状态管理解决方案vuex。

    公共bus.js

    //bus.js
    import Vue from 'vue'
    export default new Vue()
    组件A:
    <template>
      <div>
        A组件:
        <span>{{elementValue}}</span>
        <input type="button" value="点击触发" @click="elementByValue">
      </div>
    </template>
    <script>
      // 引入公共的bug,来做为中间传达的工具
      import Bus from './bus.js'
      export default {
        data () {
          return {
            elementValue: 4
          }
        },
        methods: {
          elementByValue: function () {
            Bus.$emit('val', this.elementValue)
          }
        }
      }
    </script>
    组件B:
    <template>
      <div>
        B组件:
        <input type="button" value="点击触发" @click="getData">
        <span>{{name}}</span>
      </div>
    </template>
    <script>
      import Bus from './bus.js'
      export default {
        data () {
          return {
            name: 0
          }
        },
        mounted: function () {
          var vm = this
          // 用$on事件来接收参数
          Bus.$on('val', (data) => {
            console.log(data)
            vm.name = data
          })
        },
        methods: {
          getData: function () {
            this.name++
          }
        }
      }
    </script>


    4. 利用vuex


    (1)简要介绍Vuex原理

    Vuex实现了一个单向数据流,在全局拥有一个State存放数据,当组件要更改State中的数据时,必须通过Mutation进行,Mutation同时提供了订阅者模式供外部插件调用获取State数据的更新。而当所有异步操作(常见于调用后端接口异步获取更新数据)或批量的同步操作需要走Action,但Action也是无法直接修改State的,还是需要通过Mutation来修改State的数据。最后,根据State的变化,渲染到视图上。

    (2)简要介绍各模块在流程中的功能:

    Vue Components:Vue组件。HTML页面上,负责接收用户操作等交互行为,执行dispatch方法触发对应action进行回应。

    dispatch:操作行为触发方法,是唯一能执行action的方法。

    actions:操作行为处理模块,由组件中的 $store.dispatch('action 名称',data1)来触发。然后由commit()来触发mutation的调用 , 间接更新 state。负责处理Vue Components接收到的所有交互行为。包含同步/异步操作,支持多个同名方法,按照注册的顺序依次触发。向后台API请求的操作就在这个模块中进行,包括触发其他action以及提交mutation的操作。该模块提供了Promise的封装,以支持action的链式触发。

    commit:状态改变提交操作方法。对mutation进行提交,是唯一能执行mutation的方法。

    mutations:状态改变操作方法,由actions中的 commit('mutation 名称')来触发。是Vuex修改state的唯一推荐方法。该方法只能进行同步操作,且方法名只能全局唯一。操作之中会有一些hook暴露出来,以进行state的监控等。

    Vuex 的 mutation 中为什么 不能做异步操作?

    Vuex中所有的状态更新的唯一途径都是mutation,异步操作通过 Action 来提交 mutation实现,这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。每个mutation执行完成后都会对应到一个新的状态变更,这样devtools就可以打个快照存下来,然后就可以实现 time-travel 了。如果mutation支持异步操作,就没有办法知道状态是何时更新的,无法很好的进行状态的追踪,给调试带来困难。

    state:页面状态管理容器对象。集中存储Vue components中data对象的零散数据,全局唯一,以进行统一的状态管理。页面显示所需的数据从该对象中进行读取,利用Vue的细粒度数据响应机制来进行高效的状态更新。

    getters:state对象读取方法。图中没有单独列出该模块,应该被包含在了render中,Vue Components通过该方法读取全局state对象。

    5.Vuex与localStorage


    vuex 是 vue 的状态管理器,存储的数据是响应式的。但是并不会保存起来,刷新之后就回到了初始状态,具体做法应该在vuex里数据改变的时候把数据拷贝一份保存到localStorage里面,刷新之后,如果localStorage里有保存的数据,取出来再替换store里的state。

    let defaultCity = "北京"
    try {   
    // 用户关闭了本地存储功能,此时在外层加个try...catch
    if(!defaultCity){
        defaultCity = JSON.parse(window.localStorage.getItem('defaultCity'))
      }
    }catch(e){}
    export default
     new Vuex.Store({
      state: {
        city: defaultCity
      },
      mutations: {
        changeCity(state, city) {
          state.city = city
        try{
            window.localStorage.setItem('defaultCity', JSON.stringify(state.city));   
            // 数据改变的时候把数据拷贝一份保存到localStorage里面
         } catch(e) {}
      }
    }
    })


    这里需要注意的是:由于vuex里,我们保存的状态,都是数组,而localStorage只支持字符串,所以需要用JSON转换:

    JSON.stringify(state.subscribeList);   
    // array -> string
     
    JSON.parse(window.localStorage.getItem("subscribeList"));    
    // string -> array

     
    6.  $attrs / $listeners


    1.简介

    多级组件嵌套需要传递数据时,通常使用的方法是通过vuex。但如果仅仅是传递数据,而不做中间处理,使用 vuex 处理,未免有点大材小用。为此Vue2.4 版本提供了另一种方法---- $attrs/ $listeners

    $attrs:包含了父作用域中不被 prop 所识别 (且获取) 的特性绑定 (class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件。通常配合 interitAttrs 选项一起使用。

    $listeners:包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件接下来我们看个跨级通信的例子:

    //index.vue
    <template>
        <div>
            <h2>浪里行舟</h2>
            <child-com1 :foo="foo" :boo="boo" :coo="coo" :doo="doo" title="前端工匠"></child-com1>
        </div>
    </template>
    <script>
    import childCom1 from "./childCom1.vue"
    export default {
        components: {childCom1},
        data (){
            return {
                foo:"javascript",
                boo: "Html",
                coo: "Css",
                doo: "Vue"
            }
        }
    }
    </script>
    //childCom1.vue
    <template>
        <div>
            <p>foo:{{foo}}</p>
            <p>childCom1的$attrs:{{$attrs}}</p>
            <child-com2 v-bind="$attrs"></child-com2>
        </div>
    </template>
    <script>
    import childCom2 from "./childCom2.vue";
    export default {
        components:{ childCom2 },
        inheritAttrs:false,//可以关闭自动挂载到组件跟元素上的没有在props声明的属性
        props: { foo: String },// foo作为props属性绑定
        created() { console.log(this.$attrs); // { "boo": "Html", "coo": "CSS", "doo": "Vue", "title": "前端工匠" }
      }
    }
    </script>
    
    
    //childCom2.vue
    <template>
        <div>
            <p>boo:{{boo}}</p>
            <p>childCom2的$attrs:{{$attrs}}</p>
            <child-com3 v-bind="$attrs"></child-com3>
        </div>
    </template>
    <script>
    import childCom3 from "./childCom3.vue";
    export default {
        components:{ childCom3 },
        inheritAttrs:false,//可以关闭自动挂载到组件跟元素上的没有在props声明的属性
        props: { foo: String },// foo作为props属性绑定
        created() { console.log(this.$attrs); // { "boo": "Html", "coo": "CSS", "doo": "Vue", "title": "前端工匠" }
      }
    }
    </script>
    
    
    // childCom3.vue
    <template>
      <div> 
        <p>childCom3: {{ $attrs }}</p>
      </div>
    </template>
    <script>
    export default{
      props: {
        coo: String,
        title: String
      }
    };
    </script>


     

    如上图所示 $attrs表示没有继承数据的对象,格式为{属性名:属性值}。Vue2.4提供了 $attrs ,$listeners 来传递数据与事件,跨级组件之间的通讯变得更简单。

    简单来说: $attrs与 $listeners 是两个对象, $attrs 里存放的是父组件中绑定的非 Props 属性, $listeners里存放的是父组件中绑定的非原生事件。

    7.provide/inject


    1.简介

    Vue2.2.0新增API,这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。一言而蔽之:祖先组件中通过provider来提供变量,然后在子孙组件中通过inject来注入变量。provide / inject API 主要解决了跨级组件间的通信问题,不过它的使用场景,主要是子组件获取上级组件的状态,跨级组件间建立了一种主动提供与依赖注入的关系。

    2.举个例子

    假设有两个组件: A.vue 和 B.vue,B 是 A 的子组件

    // A.vue
    export default{
      provide: {    name: '浪里行舟'  }
    }
     
    // B.vue
    export default {
      inject: ['name'],
      mounted () {
        console.log(this.name); // 浪里行舟
      }
    }


    可以看到,在 A.vue 里,我们设置了一个 provide: name,值为 浪里行舟,它的作用就是将 name 这个变量提供给它的所有子组件。而在 B.vue 中,通过 inject 注入了从 A 组件中提供的 name 变量,那么在组件 B 中,就可以直接通过 this.name 访问这个变量了,它的值也是 浪里行舟。这就是 provide / inject API 最核心的用法。

    需要注意的是:provide 和 inject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的----vue官方文档 所以,上面 A.vue 的 name 如果改变了,B.vue 的 this.name 是不会改变的,仍然是 浪里行舟。

    3.provide与inject 怎么实现数据响应式

    一般来说,有两种办法:

    provide祖先组件的实例,然后在子孙组件中注入依赖,这样就可以在子孙组件中直接修改祖先组件的实例的属性,不过这种方法有个缺点就是这个实例上挂载很多没有必要的东西比如props,methods

    使用2.6最新API Vue.observable 优化响应式 provide(推荐)

    我们来看个例子:孙组件D、E和F获取A组件传递过来的color值,并能实现数据响应式变化,即A组件的color变化后,组件D、E、F不会跟着变(核心代码如下:)

    // A 组件 
    <div>
          <h1>A 组件</h1>
          <button @click="() => changeColor()">改变color</button>
          <ChildrenB/><ChildrenC/>
    </div>
     
    ......
     
      data() {   
        return
         {
            color: "blue"
         };
      },
      
    // provide() {
    //   return {
    //     theme: {
    //       color: this.color //这种方式绑定的数据并不是可响应的
    //     } // 即A组件的color变化后,组件D、E、F不会跟着变 
    //   };
    // },
      provide() { 
        return{
          theme: this//方法一:提供祖先组件的实例
        };
      },
      methods: {
        changeColor(color) {  
        if(color) {     
            this.color = color;
        } else{      
            this.color = this.color === "blue"? "red": "blue";
         }
       }
      }
    // 方法二:使用vue2.6最新API Vue.observable 优化响应式 provide
    // provide() {
    //   this.theme = Vue.observable({
    //     color: "blue"
    //   });
    //   return {
    //     theme: this.theme
    //   };
    // },
    // methods: {
    //   changeColor(color) {
    //     if (color) {
    //       this.theme.color = color;
    //     } else {
    //       this.theme.color = this.theme.color === "blue" ? "red" : "blue";
    //     }
    //   }  
    // }
    // F 组件 
     
    <template functional>
      <div class="border2">
        <h3 :style="{ color: injections.theme.color }">F 组件</h3>
      </div>
    </template>
     
    <script>
    export default
     {
      inject: {
      theme: {   
     //函数式组件取值不一样     
        default: () => ({})
       }
      }
    };
    </script>


    虽说provide 和 inject 主要为高阶插件/组件库提供用例,但如果你能在业务中熟练运用,可以达到事半功倍的效果!

    8. $parent / $children & ref


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

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

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

    // component-a 子组件
    export default
     {
      data () {   
        return
         {
             title: 'Vue.js'
         }
      },
      methods: {
        sayHello () {
          window.alert('Hello');
        }
      }
    }
    // 父组件
    <template>
      <component-a ref="comA"></component-a>
    </template>
     
    <script>  
    export default
     {
        mounted () {    
            const comA = this.$refs.comA;
            console.log(comA.title);  // Vue.js
            comA.sayHello();  // 弹窗
        }
      }
    </script>


     

    不过,这两种方法的弊端是,无法在跨级或兄弟间通信。

    // parent.vue
    <component-a></component-a>
    <component-b></component-b>
    <component-b></component-b>
    我们想在 component-a 中,访问到引用它的页面中(这里就是 parent.vue)的两个 component-b 组件,那这种情况下,就得配置额外的插件或工具了,比如 Vuex 和 Bus 的解决方案。

    总结
    常见使用场景可以分为三类:

    父子通信: 父向子传递数据是通过 props,子向父是通过 events( $emit);通过父链 / 子链也可以通信( $parent / $children);ref 也可以访问组件实例;provide / inject API; $attrs/$listeners

    兄弟通信: Bus;Vuex

    跨级通信: Bus;Vuex;provide / inject API、 $attrs/$listeners

    更多相关内容
  • vue 传值 vue 三种传值方法

    千次阅读 2021-12-10 11:30:15
    vue 三种传值方法 第一种:父传子 父: <template>  <div> 父组件: <input type="text" v-model="val">(v-model双向绑定) <!-- 这里是引入子组件 -->  <child :inputName="name">...

    jQuery

    https://blog.csdn.net/Wave_explosion/article/details/121855584
    

    深拷贝:

    https://blog.csdn.net/Wave_explosion/article/details/121858994
    

    vue 三种传值方法

    第一种:父传子

    父:

    <template>
    
      <div> 父组件: <input type="text" v-model="val">(v-model双向绑定)
    
       <!-- 这里是引入子组件 -->
    
      <child :inputName="name"></child> </div>
    
    </template>
    
    <script>
    
      import child from './child'
    
      export default {
    
        components: { child },
    
        data () {
    
          return {
    
            val: ''
    
          }
    
         }
    
      }
    
    </script>
    

    子组件

    <template>
    
      <div> 子组件: <span>{{inputName}}</span> </div>
    
    </template>
    
    <script>
    
    export default {
    
      // 接受父组件的值
    
      props: {
    
         inputName: String,
    
         required: true
    
      }
    
    }
    
    </script>
    

    子传父

    子:

    <template>
    
      <div> 子组件: <span>{{childValue}}</span> <!-- 定义一个子组件传值的方法 --> <input type="button" value="点击触发" @click="childClick"> </div>
    
    </template>
    
    <script>
    
    export default {
    
      data () {
    
        return {
    
          childValue: '我是子组件的数据'
    
         }
    
       },
    
       methods: {
    
         childClick () {
    
           // childByValue是在父组件on监听的方法 // 第二个参数this.childValue是需要传的值
    
           this.$emit('childByValue', this.childValue)
    
        }
    
      }
    
    }
    
    </script>
    

    父:

    <template>
    
      <div> 父组件: <span>{{name}}</span> <br> <br> <!-- 引入子组件 定义一个on的方法监听子组件的状态--> <child v-on:childByValue="childByValue"></child> </div>
    
    </template>
    
    <script>
    
    import child from './child'
    
    export default {
    
      components: { child },
    
      data () {
    
        return { name: '' }
    
      },
    
      methods: {
    
        childByValue: function (childValue) {
    
          // childValue就是子组件传过来的值
    
          this.name = childValue
    
        }
    
      }
    
    }
    
    </script>
    

    非父子间传值

    (tip:需通过新定义个vue实例去传值通过bus.js文件,该文件是你自己新建的文件,随你放在那里,但之后需

    要引用,这个文件也可以用于兄弟间传值,简单的解释就是该文件相当于是一个中转站,它就是中间做处理

    的,用来传递和接收的)

    首先介绍下bus创建

    let Hub = new Vue(); //一个新的vue实例,事件中心
    

    下面为具体操作方法

    触发传递参数

    <div @click="xuanFn(5)"></div>
     
    xuanFn: function(a){
        var that = this;
            Hub.$emit('name',a);//Hub触发事件
    },
     
    

    接收参数事件

    <div></div>
    created() {
        Hub.$on('name', (msg) => { //Hub接收事件
            this.xuanname= msg;
        });
    }
    
    **https://blog.csdn.net/Wave_explosion/article/details/118613794?spm=1001.2014.3001.5501**
    
    ****cookei:https://blog.csdn.net/Wave_explosion/article/details/118613794****
    
    https://blog.csdn.net/Wave_explosion/article/details/118162649?spm=1001.2014.3001.5502
    

    深拷贝:

    https://blog.csdn.net/Wave_explosion/article/details/121858994
    
    展开全文
  • vue传值的12种方式

    2022-04-02 13:49:20
    组件传值 1、父传子 (1)在父组件的子组件标签上绑定一个属性,挂载要传输的变量 (2)在子组件中通过props来接受数据,props可以是数组也可以是对象,接受的数据可以直接使用 props: [“属性名”] 或 props:{属性...

    组件传值

    1、父传子

    (1)在父组件的子组件标签上绑定一个属性,挂载要传输的变量
    (2)在子组件中通过props来接受数据,props可以是数组也可以是对象,接受的数据可以直接使用 props: [“属性名”] 或 props:{属性名:数据类型}

    //父组件
    <template>
      <div>
        <i>父组件</i>
        <!--页面使用-->
        <son :faToSonName='name'></son> 
      </div>
    </template>
    
    <script>
    import son from "./son.vue";//导入父组件
    export default {
      components: { son },//注册组件
      name: "父组件",
      data() {
        return {
          name: "Frazier", //父组件定义变量
        };
      },
    };
    </script>
    
    //子组件
    <template>
      <div>{{data}}</div>
    </template>
    
    <script>
    export default {
    	components: { },
    	name: '子组件',
    	props:["faToSonName"],
    	//或
    	props:{
    		faToSonName:{
    			type: String,
    			default: ''
    		}
    	}
    };
    </script>
    

    2、子传父

    (1)在父组件的子组件标签上自定义一个事件,然后调用需要的方法 ​
    (2)在子组件的方法中通过 this.$emit(“事件”)来触发在父组件中定义的事件,数据是以参数的形式进行传递的

    //父组件
    <template>
      <div>
        <i>父组件</i>
        <!--页面使用-->
        <son @click="lcclick"></son>//自定义一个事件
      </div>
    </template>
    
    <script>
    import son from "./son.vue"; //导入父组件
    export default {
      components: { son }, //注册组件
      name: "父组件",
      data() {
        return {};
      },
      methods: {
        lcclick(){
          alert('子传父')
        }
      },
    };
    </script>
    
    //子组件
    <template>
      <div>
        <button @click="lcalter">点我</button>
      </div>
    </template>
    
    <script>
    export default {
    components: { },
      name: '子组件',
      methods: {
        lcalter(){
          this.$emit('lcclick')//通过emit来触发事件
        }
      },
    };
    </script>
    

    3、父子组件通信

    (1)ref 如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例,
    (2)可以通过实例直接调用组件的方法或访问数据。也算是子组件向父组件传值的一种

    //父组件
    <template>
      <div>
        <button @click="sayHello">sayHello</button>
        <child ref="childForRef"></child>
      </div>
    </template>
    <script>
    import child from './child.vue'
      export default {
        components: { child },
        data () {
          return {
            childForRef: null,
          }
        },
        mounted() {
          this.childForRef = this.$refs.childForRef;
          console.log(this.childForRef.name);
        },
        methods: {
          sayHello() {
            this.childForRef.sayHello()
          }
        }
      }
    </script>
    
    //子组件
    <template>
      <div>child 的内容</div>
    </template>
    <script>
    export default {
      data () {
        return {
          name: '我是 child',
        }
      },
      methods: {
        sayHello () {
          console.log('hello');
          alert('hello');
        }
      }
    }
    </script>
    

    4、$parent

    通过parent可以获父组件实例 ,然 后通过这个实例就可以访问父组件的属 性和方法 。
    它还有一个兄弟root,可以获取根组件实例。

    // 获父组件的数据
    this.$parent.foo
    
    // 写入父组件的数据
    this.$parent.foo = 2
    
    // 访问父组件的计算属性
    this.$parent.bar
    
    // 调用父组件的方法
    this.$parent.baz()
    
    //在子组件传给父组件例子中,可以使用this.$parent.getNum(100)传值给父组件。
    

    5、祖传孙

    正常情况下需要借助父亲的props作为中间过渡,但是这样在父亲组件就会多了一些跟父组件业务无关的属性,耦合度高,借助$attrs可以简化些,而且祖跟孙都无需做修改

    <template>
        <section>
        		<!---->
            <parent name="grandParent" sex="男" age="88" hobby="code" @sayKnow="sayKnow"></parent>
        </section>
    </template>
    
    <script>
        import Parent from './Parent'
        export default {
            name: "GrandParent",
            components: {
              Parent
            },
            data() {
                return {}
            },
            methods: {
              sayKnow(val){
                console.log(val)
              }
            },
            mounted() {
            }
        }
    </script>
    
    <template>
    	<!---->
      <section>
        <p>父组件收到</p>
        <p>祖父的名字:{{name}}</p>
        <children v-bind="$attrs" v-on="$listeners"></children>
      </section>
    </template>
    
    <script>
      import Children from './Children'
    
      export default {
        name: "Parent",
        components: {
          Children
        },
        // 父组件接收了name,所以name值是不会传到子组件的
        props:['name'],
        data() {
          return {}
        },
        methods: {},
        mounted() {
        }
      }
    </script>
    
    <template>
    		<!---->
      <section>
        <p>子组件收到</p>
        <p>祖父的名字:{{name}}</p>
        <p>祖父的性别:{{sex}}</p>
        <p>祖父的年龄:{{age}}</p>
        <p>祖父的爱好:{{hobby}}</p>
    
        <button @click="sayKnow">我知道啦</button>
      </section>
    </template>
    
    <script>
      export default {
        name: "Children",
        components: {},
        // 由于父组件已经接收了name属性,所以name不会传到子组件了
        props:['sex','age','hobby','name'],
        data() {
          return {}
        },
        methods: {
          sayKnow(){
            this.$emit('sayKnow','我知道啦')
          }
        },
        mounted() {
        }
      }
    </script>
    

    6、孙传祖

    利用$listeners传值

    <template>
    	<!---->
      <div id="app">
        <children-one @eventOne="eventOne"></children-one>
        {{ msg }}
      </div>
    </template>
    <script>
    import ChildrenOne from '../src/components/children.vue'
    export default {
      name: 'App',
      components: {
        ChildrenOne,
      },
      data() {
        return {
          msg: ''
        }
      },
      methods: {
        eventOne(value) {
          this.msg = value
        }
      }
    }
    </script>
    
    <template>
    <!---->
      <div>
        <children-two v-on="$listeners"></children-two>
      </div>
    </template>
    
    <script>
    import ChildrenTwo from './childrenTwo.vue'
    
    export default {
      name: 'childrenOne',
      components: {
        ChildrenTwo
      }
    }
    </script>
    
    <template>
    	<!---->
      <div>
        <button @click="setMsg">点击传给祖父</button>
      </div>
    </template>
    
    <script>
    export default {
      name: 'children',
      methods: {
        setMsg() {
          this.$emit('eventOne', '123')
        }
      }
    }
    </script>
    

    7、兄弟组件通信(bus总线)

    (1)在src中新建一个Bus.js的文件,然后导出一个空的vue实例 ​
    (2)在传输数据的一方引入Bus.js ,然后通过Bus. $emit ( “ 事 件 名 ” , "

    参 数 " ) 来 派发事件 , 数据是以$emit()的参数形式来传递 ​

    (3)在接受的数据的一方 引入 Bus.js 然后通过 Bus.$on(“事件名”,(data)=>{data是接受的数据})

    Bus.js

    import Vue from 'vue'
    const Bus = new Vue()
    export default Bus
    

    组件一

    import Bus from './Bus'
    
    export default {
        data() {
            return {
                .........
                }
          },
      methods: {
            ....
            Bus.$emit('log', 120)
        },
      } 
    

    组件二

    import Bus from './Bus'
    
    export default {
        data() {
            return {
                .........
                }
          },
        mounted () {
           Bus.$on('log', content => { 
              console.log(content)
            });    
        }    
    } 
    

    8、Vuex通信

    一般用于解决复杂组件之间的通信传值
    vuex官方文档

    其他传值

    9、全局变量

    定义一个全局变量,在有值的组件直接赋值,在需要的组件内直接使用就可以了。
    具体查看下面链接
    博文链接

    10、promise传参

    //类似与这样使用,但实际上后面两个参数无法获取
    promise = new Promise((resolve,reject)=>{
        let a = 1
        let b = 2
        let c = 3
        resolve(a,b,c) 
    })
    promise.then((a,b,c)=>{
        console.log(a,b,c)
    })
    

    resolve() 只能接受并处理一个参数,多余的参数会被忽略掉。
    如果想多个用数组,或者对象方式。
    数组

    promise = new Promise((resolve,reject)=>{
        resolve([1,2,3]) 
    })
    promise.then((arr)=>{
        console.log(arr[0],arr[1],arr[2])
    })
    

    对象

    promise = new Promise((resolve,reject)=>{
        resolve({a:1,b:2,c:3}) 
    })
    promise.then(obj=>{
        console.log(obj.a,obj.b,obj.c)
    })
    

    11、sessionStorage传值

    sessionStorage 是浏览器的全局对象,存在它里面的数据会在页面关闭时清除 。运用这个特性,我们可以在所有页面共享一份数据。

    // 保存数据到 sessionStorage
    sessionStorage.setItem('key', 'value');
    
    // 从 sessionStorage 获取数据
    let data = sessionStorage.getItem('key');
    
    // 从 sessionStorage 删除保存的数据
    sessionStorage.removeItem('key');
    
    // 从 sessionStorage 删除所有保存的数据
    sessionStorage.clear();
    

    注意:里面存的是键值对,只能是字符串类型,如果要存对象的话,需要使用 let objStr = JSON.stringify(obj) 转成字符串然后再存储(使用的时候 let obj = JSON.parse(objStr) 解析为对象)。
    推荐一个库 good-storage ,它封装了sessionStorage ,可以直接用它的API存对象

    //localStorage
     storage.set(key,val) 
     storage.get(key, def)
    //sessionStorage
     storage.session.set(key, val)
     storage.session.get(key, val)
    

    12、路由传值

    A页面跳转B页面时使用this.router.push(/B?name=danseek), B页 面可以使用this.route.query.name 来获取A页面传过来的值
    上面要注意router和route的区别.

    使用冒号传值
    配置如下路由:(动态路由配置)

    {
        path: '/b/:name',
        name: 'b',
        component: () => import( '../views/B.vue')
    },
    

    在B页面可以通过 this.$route.params.name 来获取路由传入的name的值

    使用父子组件传值
    由于router-view本身也是一个组件,所以我们也可以使用父子组件传值方式传值,然后在对应的子页面里加上props,因为type更新后没有刷新路由,所以不能直接在子页面的mounted钩子里直接获取最新type的值,而要使用watch

    <router-view :type="type"></router-view>
    
    // 子页面
    props: ['type']
    watch: {
           type(){
               // console.log("在这个方法可以时刻获取最新的数据:type=",this.type)
           },
    },
    
    展开全文
  • 今天小编就为大家分享一篇vue props传值失败 输出undefined的解决方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
  • 七种Vue3传值方式

    千次阅读 2022-03-11 10:28:07
    Vue3七种传值方式
    七种Vue3传值方式
    props
    emit
    v-model
    refs
    provide/inject
    eventBus
    vuex/pinia(状态管理工具)
    

    Props方式

    Props方式是Vue中最常见的一种父传子的一种方式
    父组件代码如下:

    <template>
      <child-components :list="list"></child-components>
      <div>
        <input v-model="value" type="text" placeholder="请输入"/>
        <button @click="handleAdd" type="button">添加</button>
      </div>
    </template>
    <script setup>
    import { ref } from 'vue'
    import ChildComponents from './child.vue'
    const list = ref(['JavaScript', 'HTML', 'CSS'])
    const a= ref('1')
    // add 触发后的事件处理函数
    const handleAdd = () => {
      list.value.push(a.value)
    }
    </script>
    

    子组件只需要对父组件传递的值进行渲染即可,代码如下:

    <template>
      <ul >
        <li v-for="i in props.list" :key="i">{{ i }}</li>
      </ul>
    </template>
    <script setup>
    import { defineProps } from 'vue'
    const props = defineProps({
      list: {
        type: Array,
        default: () => [],
      },
    })
    </script>
    

    emit方式

    emit方式也是Vue中最常见的组件通信方式,该方式用于子传父;

    子组件代码如下:
    <template>
      <div >
        <input v-model="value" type="text" placeholder="请输入"/>
        <button @click="handleSubmit" type="button">添加</button>
      </div>
    </template>
    <script setup>
    import { ref, defineEmits } from 'vue'
    const a= ref('1')
    const emits = defineEmits(['add'])
    const handleSubmit = () => {
      emits('add', a.value)
      a.value = ''
    }
    </script>
    在子组件中点击【添加】按钮后,emit一个自定义事件,并将添加的值作为参数传递。
    

    父组件代码如下:

    <template>
      <ul>
        <li v-for="i in list" :key="i">{{ i }}</li>
      </ul>
      <child-components @add="handleAdd"></child-components>
    </template>
    <script setup>
    import { ref } from 'vue'
    import ChildComponents from './child.vue'
    const list = ref(['JavaScript', 'HTML', 'CSS'])
    // add 触发后的事件处理函数
    const handleAdd = value => {
      list.value.push(value)
    }
    </script>
    

    在父组件中只需要监听子组件自定义的事件,然后执行对应的添加操作。

    v-model

    v-model是Vue中一个比较出色的语法糖,就比如下面这段代码

    <ChildComponent v-model:title="pageTitle" />
    // 就是下面这段代码的简写形势
    <ChildComponent :title="pageTitle" @update:title="pageTitle = $event" />
    

    子组件

    <template>
      <div>
        <input v-model="value" placeholder="请输入"/>
        <button @click="handleAdd" type="button">添加</button>
      </div>
    </template>
    <script setup>
    import { ref, defineEmits, defineProps } from 'vue'
    const value = ref('')
    const props = defineProps({
      list: {
        type: Array,
        default: () => [],
      },
    })
    const emits = defineEmits(['update:list'])
    // 添加操作
    const handleAdd = () => {
      const arr = props.list
      arr.push(value.value)
      emits('update:list', arr)
      value.value = ''
    }
    </script>
    

    在子组件中我们首先定义props和emits,然后添加完成之后emit指定事件。
    注:update:*是Vue中的固定写法,*表示props中的某个属性名。

    父组件中使用就比较简单,代码如下:
    <template>
      <!-- 父组件 -->
      <ul >
        <li  v-for="i in list" :key="i">{{ i }}</li>
      </ul>
      <!-- 子组件 -->
      <child-components v-model:list="list"></child-components>
    </template>
    <script setup>
    import { ref } from 'vue'
    import ChildComponents from './child.vue'
    const list = ref(['JavaScript', 'HTML', 'CSS'])
    </script>
    

    refs

    在使用选项式API时,我们可以通过this.$refs.name的方式获取指定元素或者组件,但是组合式API中就无法使用哪种方式获取。如果我们想要通过ref的方式获取组件或者元素,需要定义一个同名的Ref对象,在组件挂载后就可以访问了。

    <template>
      <ul>
        <li v-for="i in childRefs?.list" :key="i">
          {{ i }}
        </li>
      </ul>
      <!-- 子组件 ref的值与<script>中的保持一致 -->
      <child-components ref="childRefs"></child-components>
      <!-- 父组件 -->
    </template>
    <script setup>
    import { ref } from 'vue'
    import ChildComponents from './child.vue'
    const childRefs = ref(null)
    </script>
    

    子组件

    <template>
      <div>
       <input v-model="value" placeholder="请输入"/>
       <button @click="handleAdd" type="button">添加</button>
      </div>
    </template>
    <script setup>
    import { ref, defineExpose } from 'vue'
    const list = ref(['JavaScript', 'HTML', 'CSS'])
    const a= ref('1')
    // add 触发后的事件处理函数
    const handleAdd = () => {
      list.value.push(a.value)
      a.value = ''
    }
    defineExpose({ list })
    </script>
    

    setup组件默认是关闭的,也即通过模板ref获取到的组件的公开实例,不会暴露任何在**

    provide/inject

    provide和inject是Vue中提供的一对API,该API可以实现父组件向子组件传递数据,无论层级有多深,都可以通过这对API实现。示例代码如下所示:

    父组件

    <template>
      <!-- 子组件 -->
      <child-components></child-components>
      <!-- 父组件 -->
      <div>
       <input v-model="value" placeholder="请输入"/>
       <button @click="handleAdd" type="button">添加</button>
      </div>
    </template>
    <script setup>
    import { ref, provide } from 'vue'
    import ChildComponents from './child.vue'
    const list = ref(['JavaScript', 'HTML', 'CSS'])
    const a= ref('')
    // 向子组件提供数据
    provide('list', list.value)
    // add 触发后的事件处理函数
    const handleAdd = () => {
      list.value.push(a.value)
      a.value = ''
    }
    </script>
    

    子组件

    <template>
      <ul >
        <li v-for="i in list" :key="i">{{ i }}</li>
      </ul>
    </template>
    <script setup>
    import { inject } from 'vue'
    // 接受父组件提供的数据
    const list = inject('list')
    </script>
    

    使用provide进行数据传递时,尽量readonly进行数据包装,避免子组件修改父级传递过去的数据。

    事件总线

    Vue3中移除了事件总线,但是可以借助于第三方工具来完成,Vue官方推荐mitt[2]或tiny-emitter[3]

    状态管理工具

    Vuex[4]和Pinia[5]可以轻松实现组件通信,由于这两个工具功能比较强大,具体可以查阅文档

    展开全文
  • Vue组件传值的三种方法

    千次阅读 2021-06-29 14:03:22
    Vue组件传值的三种方式 1、父传子 父传子使用props: 1、父组件:即在使用的子组件标签上,自定义一个绑定数据,这里我使用的是“mymsg”,将父组件的msg绑定在其上。 2、子组件:在props属性中:声明一个“mymsg”...
  • vue函数回调传值

    千次阅读 2020-04-20 20:31:30
    在业务开发中,有时候会碰到一种情况... 通常我们可以通过this.$emit() 将事件传递到父组件中,让父组件请求数据,然后再传值给子组件,子组件拿到数据后进行下一步处理。适用大部分场景。 在父组件中写一个数据请...
  • vue props 传值

    千次阅读 2020-05-18 10:04:17
    选项声明它期待获得的数据props:[data]然后在组件内使用data二、父组件需要做的这个时候需要区分静态传值和静态传值静态在父组件使用子组件标签时   <tem data="haha"></tem>这个时候静态传值...
  • Vue组件传值.sync

    千次阅读 2021-12-15 10:18:55
    传统的父子组件之间传值,父组件-->子组件 ----父组件(父组件会接收到子组件传回来的方法,并且对数据进行更改) <template> <div class="content"> <btn :btnName='num' @changeFn= changeFn&...
  • HTML页面向Vue页面传值

    千次阅读 2021-02-26 13:55:40
    但是难免会有.html页面向vue项目传值的场景。本节将介绍html项目利用JavaScript向vue项目传值。 1:HTML页面传递事件 可以随便写一个用于跳转的事件。如下: <!DOCTYPE html> <html lang="en"> <...
  • vue组件传值方式

    2022-02-15 22:09:16
    我们都知道 Vue 作为一个轻量级的前端框架,其核心就是组件化开发。Vue 就是由一个一个的组件构成的,组件化是它的精髓,也是最强大的功能之一。而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法...
  • vue 组件传值

    千次阅读 多人点赞 2020-04-21 19:14:40
    前言:在我们vue项目中组件传值大致可以分为三大类,1、子组件传值给父组件,2、父组件传值给子组件,3、兄弟组件之间传值; 1、父组件传值给子组件: 1.1、定义父组件 //父组件 //引入的add-widget组件 //使用 v-...
  • Vue组件传值EventBus

    2022-01-07 16:05:42
    vue组件传值
  • 01 父传子 props:props可以是数组或对象,用于接收来自父组件通过v-bind传递的数据。...app.vue <template> <div id="app"> Hello <!-- 想改变传递过去的数据,直接在自己的组件里面修改..
  • 前言上一篇关于vue面试的文章 (面试时面试官想要听到什么答案) 中提到了多种组件传值方式,本文对几种传值方式如何使用具体说明一下。props、$emit、eventbus、vuex、$parent / $children / ref、sessionStorage、...
  • props传值验证 props: { // 检测类型 height: Number, // 检测类型 + 其他验证 age: { type: Number, //验证类型 default: 0, //默认值 对象或数组的默认值必须从一个工厂函数返回 // 对象或数组默认值...
  • 本篇文章给大家带来的内容是关于vue传值方式有哪些?vue中常用的传值方式介绍(3种),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。一. 父组件向子组件传值1. 使用props建立数据通道的渠道// 这...
  • vue中prop传值

    2022-03-10 20:33:27
    props配置项 功能:让组件接收外部传过来的数据 传递数据: 接收数据: 第一种方式(只接收):... vue中prop传值时加不加v-bind(冒号:): 只有传递字符串常量时,不采用v-bind形式,其余情况均采用v-bind形式传递。
  • Vue 父子传值

    万次阅读 多人点赞 2019-04-30 16:28:31
    父组件向子组件传值: parent: <parent> <child :message="msg"></child> </parent> data(){ return { msg: "this is parent message" } } child: <div> <...
  • vue是数据驱动视图更新的框架, 所以对于vue来说组件间的数据通信非常重要,那么组件之间如何进行数据通信的呢? 首先我们需要知道在vue中组件之间存在什么样的关系, 才更容易理解他们的通信方式, 就好像过年回家,坐...
  • Vue 路由传值的几种方法

    万次阅读 2018-03-21 22:29:38
    vue中使用router-link标签跳转有几种方法:一、直接在path后面添加简单动态参数,如标识id等: 路由配置: 标签内容:属性id可以在$router.params中获取 二、 路由配置: 标签内容: 或者注意上面方法的区别...
  • vue 组件传值之子传父

    2021-07-29 15:57:49
    首先,子传父是通过vue的事件机制来实现的,需要主动调用$emit进行触发,$emit("自定义的事件函数”,”要传递的参数”) //2.在子组件的标签上,通过v-on绑定通过$emit发射的自定义事件,处理函数写在父组件的methods...
  • vue组件传值--详细版

    2021-01-12 15:07:32
    vue组件传值在日常开发中比较常见,在官方文档里面也有介绍,但是对于新手理解起来会有一点生涩。所以今天就把这个拉出来写一次。一般有三种传值方式:1.父传子、2.子传父、3.兄弟组件之间通信1.父组件向子组件传值...
  • 子组件(goods.vue):直接使用props接收的值显示在页面上 <text>{{`另需配送费${busiIntroData.physical}元`}}</text> props:{ busiIntroData:Object } 显示: 解决: 对于props声明为驼峰写法,...
  • VUE data传值

    2019-01-22 09:41:19
    data 必须是一个函数 上面例子中,可以看到 button-counter 组件中的 data 不是一个对象,而是一个函数: data: function () { return { count: 0 } } 这样的好处就是每个实例可以维护一份被返回对象的独立的...
  • this.filterOptions[this.cuoduleCode] = res.data this.$set(this.filterOptions, this.curreeCode, res.data) Vue.set()和this.$ set()的区别在于:Vue.set()是将set函数绑定在Vue构造函数上,this.$set()是将set...
  • Vue传值(3种常用传值方法) 父组件传值给子组件,首先父组件发送的形式是用bind(用缩写:)绑定值到子组件身上。然后子组件用属性props接收。 子组件传值父组件,首先是子组件发送的形式是this.$emit(事件名,需要...
  • 最全Vue传值方式

    2021-04-23 18:48:32
    vue组件之间相互传值的方式 我们都知道 Vue 作为一个轻量级的前端框架,其核心就是组件化开发。Vue 就是由一个一个的组件构成的,组件化是它的精髓,也是最强大的功能之一。而组件实例的作用域是相互独立的,这就...
  • 我是一个人,一个低低矮矮的平平凡凡的好看的人,如果你来了解我,你会发现我。真的是一个低低矮矮的平平凡凡的好看的人。 vue 组件的传值
  • Vue 组件之间传值

    2020-12-24 02:40:49
    Vue 中,可以使用props向子组件传递数据。子组件部分:这是 header.vue 的 HTML 部分,logo 是在 data 中定义的变量。如果需要从父组件获取 logo 的值,就需要使用props: ['logo']在 props 中添加了元素之后,就...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 17,835
精华内容 7,134
关键字:

vue函数传值

友情链接: JnnGiiv01.1.rar