前端知识点记录:Vue组件传值的各个方式

85 阅读1分钟

第二题:Vue组件传值的各个方式

父组件向子组件传值

props
单向传值,子组件无法直接修改父组件值(引用类型除外)

子组件向父组件传值

子组件this.$emit('myEvent') 抛出事件 / 父组件监听事件

兄弟组件传值

新建 eventBus Vue实例

  • eventBus.$emit('pushMsg', params) 抛出事件
  • eventBus.$on('pushMsg', params => {}) 接收事件

路由传值

  • 问号传值:
    页面A this.$router.push('/B?name=danseek') 传值
    页面B this.$route.query.name 取值

  • 冒号传值:

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

通过 this.$route.params.name 取值

  • 组件传值:
// router-view本身也是一个组件 可以使用 组件传值 props
<router-view :type="type"></router-view>
// 子页面
......
props: ['type']
......
watch: {
    type(){
        // console.log("在这个方法可以时刻获取最新的数据:type=",this.type)
    },
},

$ref传值

this.$refs[组件定义的ref值].属性名

<template>
    <div class="parent">
        <!-- 给子组件设置一个ID ref="children" -->
        <Children ref="children"></Children>
        <div @click="pushMsg">push message</div>
    </div>
</template>

<script>
    import Children from '../components/Children'

    export default {
        name: 'parent',
        components: {
            Children,
        },
        methods:{
            pushMsg(){
                // 通过这个ID可以访问子组件的方法
                this.$refs.children.updateMsg('Have you received the clothes?')
                // 也可以访问子组件的属性
                console.log('children props:',this.$refs.children.desc)
            }
        },
    }
</script>

依赖注入

可以传递到子组件、孙组件、重孙组件... (避免多层透传)

父组件

<template>
    <div class="parent">
        <Children></Children>
    </div>
</template>

<script>
    import Children from '../components/Children'

    export default {
        name: 'Parent',
        components: {
            Children,
        },
        data() {
            return {
                name:'dan_seek'
            }
        },
        provide: function () {
            return {
                getName: this.name
            }
        },
    }
</script>

子组件

<template>
    <section>
        父组件传入的值:{{getName}}
    </section>
</template>

<script>
    export default {
        name: "Children",
        components: {},
        data() {
            return {
            }
        },
        inject: ['getName'],
    }
</script>

爷孙传值 $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>

$parent 获取父组件数据

// 获父组件的数据
this.$parent.foo

// 写入父组件的数据
this.$parent.foo = 2

// 访问父组件的计算属性
this.$parent.bar

// 调用父组件的方法
this.$parent.baz()

sessionStorage传值

// 保存数据到 sessionStorage
sessionStorage.setItem('key', 'value');

// 从 sessionStorage 获取数据
let data = sessionStorage.getItem('key');

// 从 sessionStorage 删除保存的数据
sessionStorage.removeItem('key');

// 从 sessionStorage 删除所有保存的数据
sessionStorage.clear();

Vuex、Pinia

Pinia 相当于 Vuex 的升级版本,同 TypeScript 一起使用