我们可以像 vue 3 中的方法那样对 return 其他反应变量和计算属性使用 expose 方法吗?

Can we use expose method to return other reactive variables and computed properties like methods in vue 3?

我正在将我的应用程序从 vue 2 更改为 vue 3。通过使用组合 api,我已经在该设置挂钩中更改了我之前的渲染函数。在检查了一些文档之后,我知道我可以使用 context.expose({}).

公开方法

现在我的问题是:

  1. 如何替换 vue 3 组合中创建的方法 api? (我们知道,setup hook 发生在 Create hook 之前,但无法理解如何在 setup hook 中执行这些操作?)
  2. 我们可以 return 使用 context.expose 反应变量和计算属性吗?

这是我的设置脚本:

    <script>
import {h,ref,computed,provide} from 'vue';
export default {
 name: 'something',
 props: some props,
setup(props,context) {
      const currIdx = ref(0);
      const tabCnt = ref(0);
      const idxMap = ref(new Map());
      const idxs = ref([]);

      // other variables

      // computed properties
        const $_size = computed(() =>{
         // 1. check this.size
            if(props.size) {//'medium','small'
                if(props.size === 'medium') return 'medium'
                if(props.size === 'small' ) return 'small'
            }
            // 2. check flags
            if(props.medium) return 'medium'
            if(props.small ) return 'small'
            // 3. default value : 'medium'
            return 'medium';
        });
       // [COMPUTED] Props normalize : SHAPE
        const $_shape = computed(() =>{
            // 1. check this.shape
            if(props.shape) { // 'border','underline','none'
                if(props.shape === 'border'   ) return 'border'
                if(props.shape === 'underline') return 'underline'
                if(props.shape === 'none'     ) return 'none'
            }
            // 2. check flags
            if(props.border   ) return 'border'
            if(props.underline) return 'underline'
            // x. default value : 'border'
            return 'border';
        });


      // [COMPUTED] - [END REGION]
      const getLabelNode = (props) => {
            var label = props.label, idx = props.idx, disabled = !!(props.disabled || props.disable)
            return h('vu-tab-label',{props:{idx, disabled}},[label]);
        };

      
          
          // 2. make window area -> label + navi(?)
        var labelWindow = [];
        labelWindow.push(h("div",{"class":"vu-tab__label-wrapper","ref":"scroll"}, labels));
        if(props.navigation || props.addBtn) {
            labelWindow.push(h(tabNavi))
        }

        // 3. do something
        idxs.value = Array.from(idxMap.value.keys());

        // 4. make class
        let tabClass = [];
        tabClass.push("vu_tab-box");
        tabClass.push(`vu-tab-box--${this.$_shape}`);

        // methods
        const onAddClick =(e) => {
            context.emit('add-tab',e);
        };

        context.expose({
            onAddClick,
        });
  
        // x. return all nodes
        return h("div",{"class":tabClass},[
            h("div",{"class":"vu-tab__label-window","ref":"window"},labelWindow),
            h("div",{"class":"vu-tab__content-wrapper"},contents)
        ]);
    
    },
  }
</script>

对于问题 1,这是我创建的钩子,我想在设置中执行这些操作。

created() {
    // 1. Check default index
    if( (this.defaultIdx === 0) || this.defaultIdx ) {
        this.currIdx = this.defaultIdx;
        return;
    }
    // 2. check slots
    var slots = this.$slots['default']
    if(!!slots) {
        slots.find(vNode => {
            if (!vNode.componentOptions) { return false }
            var idx = vNode.componentOptions.propsData.idx;
            if (idx === undefined) { return false }
            this.currIdx = idx;
            return true;
        });
    }
},

created 勾入作文api

这个很简单,组合api中没有createdbeforeCreate钩子。它完全被 setup 取代。您可以直接 运行 将您的代码直接放在 setup 函数中,或者将其放在您从 setup.

中调用的函数中

属性是否使用 expose 反应式公开

是的。虽然使用模板引用访问子组件的值并不是真正的“Vue”方式,但它是可能的,并且传递的值保持它们的反应性。我找不到任何关于此的文档,所以我很快实现了一个小型代码沙箱来试用它。自己看看。

https://codesandbox.io/s/falling-breeze-twetx3?file=/src/App.vue

(如果遇到类似“Cannot use import outside a module”的错误,只需重新加载浏览器within代码沙箱,代码沙箱似乎有问题模板)