Skip to content

Vue组件间传值

Vue 父组件获取子组件值

首先准备 querySearch 数据

js
const list = [{ value: "value1" }, { value: "value2" }, { value: "value3" }];

组件代码, 其中 querySelect 是获取代码的一个 method

html
<el-autocomplete v-model="state" :fetch-suggestions="querySearch" placeholder="Please input" @select="handleSelect" />

1. 方法传递, 这也是我认为最灵活的方式

props 支持 Function 传递

js
props: {
  getUser: Function,
},

const  handleSelect = (data) => {
  this.$props.getUser(data);
};

2. 自定义事件方式

这种方式可以传递任意数据给 $parent, 并且能够得到触发时机

js
const handleSelect = (data) => {
  this.$emit("change", data);
};

父组件获取内容就很方便了, 在 change 中获取值即可, 假设封装后的组件是MyAutocomplete

html
<my-autocomplete @change="update" />
js
const update = (data) => {
  // 这里的 data 就是我们需要的数据
};

3. 通过 $ref 引用获取 data 数据

这种引用方式可以获取到 myAutocomplete 的所有 data 值, 对于值获取值来说非常实用, 但是违背了封装原则, 不容易维护

js
const state = this.$ref.myAutocomplete.$data.state;

父组件传递值给子组件

最容易想到的就是 props, 这也是官方推荐方式

js
props: {
  value: String,
},

调用时只需要传递 value 即可

html
<input :value="value" />

DANGER

当组件被封装时, 不能使用 v-model 显示内容, 一方面 props 不支持修改, 另外 props 修改后无法传递给 v-model

element-ui

element-ui封装 select

html
// my-select.vue

<template>
  <el-select v-model="userId" placeholder="用户名" :remote-method="getList" @change="change">
    <el-option v-for="item in list" :key="item._id" :label="item.name" :value="item._id"> </el-option>
  </el-select>
</template>

<script>
  export default {
    props: {
      initData: String,
      getUser: Function,
    },
    data() {
      return {
        userId: null,
        list: [],
      };
    },
    watch: {
      initData() {
        this.$data.userId = this.$props.initData;
      },
    },
    mounted() {
      this.$data.userId = this.$props.initData;
    },
    methods: {
      change(userId) {
        const user = this.list.find((data) => data._id === userId);
        if (this.$props.getUser) {
          this.$props.getUser(user);
        }
      },
      async getList(name) {
        if (!name) {
          return;
        }
        let url = urls.userList;
        let data = {
          name
        };
        const list = await request({data,, url});
        this.list = list || [];
      },
    },
  };
</script>

父标签引入 my-select

html
<template>
  <my-select :init-data="data" :get-user="getUser" />
</template>
<script>
  // ...

  const getUser = (user) => {
    // 这一步必须做, 否则 选择的数据不能回显
    data.value = user;
  };
</script>