Vue3: как смешивать api композиции и api опций для составного/смешанного пространства имен

#vuejs3 #composable

Вопрос:

Добрый день!

Допустим, я хочу использовать Vue с api опций, но также не хочу использовать миксины, так как они вызывают много проблем. Я хочу использовать составные элементы в качестве миксинов, чтобы предоставить пространство имен для миксинов/составных элементов.

Итак, мое «решение» состояло в том, чтобы объединить api опций и api композиции.

Допустим, у меня есть такая смесь:

 export default {
  data() {
    return {
      person: {
        first_name: 'first name',
        last_name: 'last name',
      },
      gender: 'gender'
    }
}
 

Поэтому я решил преобразовать его в композиционный следующим образом:

 export default () => {
  const person = reactive({first_name: 'fn', last_name: 'ln'});
  const gender = ref('gender');
  
  return {
    person,
    gender,
  }
}
 

Итак, в моем файле .vue я могу импортировать составные:

 <script lang="ts">
import useDataComposable from './dataMixin';
...

export default defineComponent({
  ...
  setup() {
    const dataComposable = useDataComposable();
    dataComposable.gender.value = 'gender2';
    dataComposable.person.first_name = 'first name2';

    return {dataComposable};
  },
  created() {
    // I want to use data and methods inside the composable as namespace.attribute
    // eg:
    console.log(this.dataComposable.person.first_name) // => returns 'first name2'
 
    // However,
    console.log(this.dataComposable.gender // does not return 'gender2';
      // but returns Ref object.
...
 

Я знаю, что могу разрушить композицию в функции настройки и вернуть ее:

 <script lang="ts">
import useDataComposable from './dataMixin';
...

export default defineComponent({
  ...
  setup() {
    const {person, gender}= useDataComposable();

    return {
      person, gender,
    };
  },
  created() {
    console.log(this.person.first_name) // => returns 'first name2'
 
    // However,
    console.log(this.gender // returns 'gender2';
...
 

Однако в этом нет смысла, так как в любом случае он будет смешан с состоянием компонента.

Кроме того, я мог бы просто использовать миксины только с одним объектом, но я в этом не уверен.

 export default {
  data() {
    return {
      state: {
        person: {
          first_name: 'first name',
          last_name: 'last name',
        },
        gender: 'gender',
        
        myMethod: function() {...},
        computed: function() {...}
      },
      
      created() {...},
      onMounted() {...},
      watch: {
        gender(value) {...}.
      },
    }
}
 

Мне любопытно, можно ли делать то, что я хочу.

Есть ли какой-либо способ использовать объект с реактивными элементами и элементами ref из составного в коде vue api опций?

Заранее спасибо!

Ответ №1:

Вы можете либо: деструктировать и добавить return { пространство имен: { человек, пол}}, Изменить составное, чтобы вернуть имя, содержащее как личность, так и пол.