欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

vueX 中的 provide 和 inject 实现状态管理

程序员文章站 2022-03-27 17:09:14
...


1、html 部分

<!-- 页面 -->
<div id="app">
	<div class="component_box">
		<h1>问卷调查</h1>
		<vote-plugin class="commponents" v-for="item in votes" :key="item.id" :title="item.title"></vote-plugin>
	</div>
</div>

<!-- 父组件 -->
<template id="MyVoteTemplate">
	<div>
		<h3>
			<span v-text="title"></span>
			&nbsp;&nbsp;
            参与人数:<span v-text="nums.supNum+nums.oppNum"></span>
		</h3>
		<vote-content></vote-content>
		<vote-button></vote-button>
	</div>
</template>

2、JavaScript 部分

// 内容组件
const VoteContent = {
	template: `<div><p>支持人数 <span v-text="nums.supNum"></span></p><p>反对人数 <span>{{nums.oppNum}}</span></p><p>支持率 <span v-text="ratio"></span></p></div>`,
	inject: ['nums'],

	computed: {
		ratio() {
			let total = this.nums.supNum + this.nums.oppNum;
            if (total === 0) {
            	return '0.00%'
            }
            return (this.nums.supNum / total * 100).toFixed(2) + '%';
		}
	}
};

// 按钮组件
const VoteButton = {
	template: `<div class="btn_box"><button @click="handle('yes')">是</button><button @click="handle('no')">否</button></div>`,

	// 和 props 一样都会把注册的信息挂载到实例上
    inject: ['change'],

	methods: {
		handle(i) {
			this.change(i);
		}
	}
};

// provide / inject
Vue.component('VotePlugin', {
	template: '#VotePluginTemplate',
	props: ['title'],
	// 这些数据存储在 this._provided 中
	// provide: {
	//     supNum: 0,
	//     oppNum: 0,
	//     change: this.change
	// },

	// 可以写成对象,也可以写成闭包的方式
	// 必报的方式会在实例上的信息都挂载完成后再处理
	// 可以使用 created 声明周期函数验证
	provide() {
		return {
			// supNum: 0,
			// oppNum: 0,
			nums: this.nums,
			change: this.change
		}
	},
	components: {
		VoteContent,
		VoteButton
	},
	data() {
		return {
			nums: {
				supNum: 0,
				oppNum: 0
			}
		};
	},

	methods: {
		change(i) {
			i == 'yes' ? this.nums.supNum++ : this.nums.oppNum++;
			// i == 'yes' ? this._provided.supNum++ : this._provided.oppNum++;
			// // 强制刷新
			// this.$forceUpdate();
		}
	}
});

// 父组件
const MyVote = {
	template: '#MyVoteTemplate',

	props: {
		title: {
			type: [String, Number],
			// 设置默认值
			default: '这是标题'
		}
	},
	
	components: {
		VoteContent,
		VoteButton
	}
};

// 页面
new Vue({
	el: "#app",
	components: {
		MyVote
	},
	
	data: {
		voteList: [
			{
				id: 1,
				title: "**是否很漂亮!"
			}, 
			{
				id: 2,
				title: "***是否很帅!"
			}
		],
	}
});

3、css 部分

.component_box {
	position: fixed;
	left: 50%;
	top: 50%;
	transform: translate(-50%, -50%);
}
        
.commponents {
	border-bottom: 1px solid #666666;
	padding: 20px 0;
	box-sizing: border-box;
}
        
.btn_box>button:first-child {
	color: blue;
}
        
.btn_box>button:last-child {
	margin-left: 16px;
}
相关标签: Vue 功能 vue