$attrs、$listeners is readonly
发布于 3 年前 作者 huaer 2452 次浏览 来自 问答
粉丝福利 : 关注VUE中文社区公众号,回复视频领取粉丝福利

我使用npm link在项目中调试一个confirm组件

  1. 在组件中npm link
    
  2. 在项目中npm link [\@xxx](/u/xxx)/confirm  
    

    当点击弹出confirm时,$attrs is readonly.报错,搜索网上大都是说因为组件中跟项目中vue版本不同,我查看了版本发现是相同的。找到一个英文例子跟我的情况感觉一样,但是我不知道最后如何解除这个警告https://forum.vuejs.org/t/vue-warn-attrs-is-readonly/18053/8

    <script> // component.vue import Vue from 'vue'; import Modal from '../modal'; const timestamp = new Date().getMilliseconds(); let count = 0; const Confirm = { name: 'confirm', components: { Modal }, props: { value: { type: Boolean, default: false }, modalProps: { type: Object, default() { return {}; } }, title: { type: String, default: '提示' }, icon: String, color: String, content: [String, Function] }, data() { return { visible: this.value }; }, watch: { value(v) { this.visible = v; }, visible(v) { this.$emit('input', v); } }, methods: { onInput(v) { this.visible = v; }, onConfirm() { this.$emit('confirm'); }, onCancel() { this.$emit('cancel'); } }, render(h) { const { visible, modalProps, title, icon, color, content, $slots } = this; const node = typeof content === 'string' ? content : content(h); return ( <modal title={title} width={450} {...{ props: modalProps }} value={visible} on-input={this.onInput} on-confirm={this.onConfirm} on-cancel={this.onCancel} >
    { $slots.default || node }
    </modal> ); } }; const Popup = { name: 'PopUp', components: { Confirm }, props: { popupClass: String, Component: {} }, data() { return { popups: [], colorMap: { info: 'info', success: 'success', error: 'error', warning: 'warning ' }, iconMap: { info: 'info-circle-o', success: 'check-circle-', error: 'close-circle-o', warning: 'exclamation-circle-o ' } }; }, methods: { add(props) { count++; props.name = props.name || `${timestamp}-${count}`; this.popups.push(props); return () => { this.close(props.name); }; }, close(name) { let index = -1; this.popups.forEach((item, i) => { if (item.name === name) { index = i; } }); if (index !== -1) { this.popups.splice(index, 1); } }, closeAll() { this.popups = []; } }, render() { const { popupClass, popups, colorMap, iconMap } = this; const fn = () => {}; const nodes = popups.map((item, i) => { item.color = colorMap[item.type]; item.icon = item.icon || iconMap[item.type]; return ( <confirm {...{ props: item }} value={item.value} key={i} on-confirm={item.onOk || fn} on-cancel={item.onCancel || fn} > { item.content } </confirm> ); }); return (
    {nodes}
    ); } }; Confirm.createWrapper = (props = {}) => { const Instance = new Vue({ render(h) { return h(Popup, { props: props }); } }); const popup = Instance.$mount(); document.body.appendChild(popup.$el); return Instance.$children[0]; }; export default Confirm; </script>

    index.js Confirm.install = function (Vue) { const types = [‘info’, ‘success’, ‘error’, ‘warning’];

    types.forEach(type => { Confirm[type] = xxx;

    Confirm.confirm = xxxx; Confirm.closeAll =xxxx;

    Vue.prototype.$Confirm = Confirm; Vue.component(Confirm.name, Confirm); };

    export default Confirm;

回到顶部