vuex入门实战,看不懂不要赞!

    技术2022-08-31  81

    login.vue文件 <template> <div> <headers title="登录"> <router-link slot="left" to="/">返回</router-link> </headers> <form class="login" v-on:submit.prevent="submit"> <div class="line"> <div v-show="btn && !form.id">id不能为空</div> <input type="number" placeholder="输入你的id" v-model="form.id" ref="input2"> </div> <div class="line"> <div v-show="btn && !form.name">用户名不能为空</div> <input type="text" placeholder="输入你的用户名" v-model="form.name"> </div> <button>登录</button> </form> </div> </template> <script> import headers from '../../components/header' //引入组件 import { mapActions } from 'vuex' export default { data(){ return{ // 初始化数据 btn:false, form:{ id:'', name: '' } } }, mounted () { this.$refs.input2.focus() //获取焦点 this.$refs.input2.value=2 //初始值 }, methods: { ...mapActions([USER_SIGNIN]), //辅助函数写法(异步) submit(){ this.btn = true if(!this.form.id || !this.form.name){ return false }else{ this.USER_SIGNIN(this.form) //传参数 // this.$store.commit('USER_SIGNIN',this.form) 同步写法 this.$router.push({path:'/home'}) } } }, components:{ headers //注入组件 }, } </script> <style lang="scss" scoped> .login { padding: 50px; text-align: center; .line { padding: 5px; input { padding: 0 10px; line-height: 28px; } } button { padding: 0 20px; margin-top: 20px; line-height: 28px; } } </style> home.vue文件 <template> <div> <headers title="首页"> <router-link slot="left" to="/Index">首页</router-link> <router-link slot="right" to="/Singout">退出</router-link> </headers> <div style="padding: 50px;">{{users.name}}欢迎回家</div> </div> </template> <script> import headers from '../../components/header' import {mapState} from 'vuex' export default { data(){ return{ } }, components:{ headers //注入组件 }, computed:mapState(['users']) //获取state里面的值 } </script> index.vue文件 <style lang="scss" scoped> .login-msg { padding: 50px; text-align: center; } .msg { padding: 50px; text-align: center; font-size: 20px; color: red; } </style> <template> <div> <headers title="首页"> <router-link slot="right" to="/home" v-if="users.id">{{users.name}}</router-link> </headers> <div class="login-msg"> <router-link to="/login" v-if="!users.id">你还未登录,请先登录</router-link> </div> <div class="msg" v-if="users.id"> <img width="50" :src="logo" alt=""> <br> 哈哈,恭喜你已经入坑Vue2 </div> <div id="apps"> <product-list-one></product-list-one> <product-list-two></product-list-two> </div> </div> </template> <script> import ProductListOne from '../../view/ProductListOne' import ProductListTwo from '../../view/ProductListTwo' import headers from '../../components/header' import {mapState} from 'vuex' import logo from '../../assets/logo.png' export default { data(){ return{ logo, } }, components:{ headers , 'product-list-one': ProductListOne, //注入组件 'product-list-two': ProductListTwo //注入组件 }, methods: { }, computed:mapState(['users']) //获取state里面的参数 } </script> sigout.vue文件 </style> <template> <div> <headers title="退出"> <router-link slot="left" to="/home">返回</router-link> </headers> <div class="btn"> <button v-on:click="submit">确认退出</button> </div> </div> </template> <script> import headers from '../../components/header' import { mapActions } from 'vuex' export default { components: { headers }, methods: { // ...mapActions(['user_singout']), // ...mapActions([USER_SIGNOUT]), //辅助函数写法 submit(){ // this.$store.commit('user_singout') //vuex普通同步操作 // this.USER_SIGNOUT() //调用上面辅助函数才会执行 this.$store.dispatch('USER_SIGNOUT') //vuex普通异步操作 this.$router.replace({ path: '/' },() => {}) } } } </script> productlistone.vue <template> <div id="product-list-one"> <h2>Product List One</h2> <ul> <li v-for="product in products"> <span class="name">{{ product.name }}</span> <span class="price">${{ product.price }}</span> </li> </ul> </div> </template> <script> export default { data () { return { products : this.$store.getters.saleProducts //返回getters处理的结果 } } } </script> <style scoped> #product-list-one{ background: #FFF8B1; box-shadow: 1px 2px 3px rgba(0,0,0,0.2); margin-bottom: 30px; padding: 10px 20px; } #product-list-one ul{ padding: 0; } #product-list-one li{ display: inline-block; margin-right: 10px; margin-top: 10px; padding: 20px; background: rgba(255,255,255,0.7); } .price{ font-weight: bold; color: #E8800C; } </style> productlisttwo.vue <template> <div id="product-list-two"> <h2>Product List Two</h2> <ul> <li v-for="product in products"> <span class="name">{{ product.name }}</span> <span class="price">${{ product.price }}</span> </li> <button @click="minusPrice">减少价格</button> <button @click="minusPriceAsync">异步减少价格</button> </ul> <div class="box" v-if="this.$store.state.count">loading</div> <button @click="block">显示</button> <button @click="none">消失</button> </div> </template> <script> export default { data () { return { products: this.$store.state.products //直接从state里面拿值 } }, methods: { minusPrice() { this.$store.commit('minusPrice', 2); //同步操作 }, minusPriceAsync() { this.$store.dispatch('minusPriceAsync', 5); //异步操作 }, block(){ this.$store.dispatch('blocking',true) //异步操作 }, none(){ this.$store.dispatch('none',false) //异步操作 } } } </script> <style scoped> .box{ width:500px; height:30px; background: rgb(18, 214, 18); } #product-list-two{ background: #D1E4FF; box-shadow: 1px 2px 3px rgba(0,0,0,0.2); margin-bottom: 30px; padding: 10px 20px; } #product-list-two ul{ padding: 0; list-style-type: none; } #product-list-two li{ margin-right: 10px; margin-top: 10px; padding: 20px; background: rgba(255,255,255,0.7); } .price{ font-weight: bold; color: #860CE8; display: block; } </style> main.js文件 import Vuex from 'vuex' Vue.use(Vuex) const store = new Vuex.Store({ state:{ products: [ {name: '鼠标', price: 20}, {name: '键盘', price: 40}, {name: '耳机', price: 60}, {name: '显示屏', price: 80} ], count:false, users:JSON.parse(sessionStorage.getItem('name')) //解决vuex刷新数据丢失的问题 }, getters:{ //计算属性 saleProducts: (state) => { let saleProducts = state.products.map( product => { return { name: product.name, price: product.price / 2 } }) return saleProducts; } }, mutations:{ //同步操作 minusPrice (state, payload ) { let newPrice = state.products.forEach( product => { product.price -= payload }) }, // 登录 USER_SIGNIN(state, user) { state.users = user; sessionStorage.setItem('name',JSON.stringify(user)) }, // 退出 USER_SIGNOUT(state,user) { sessionStorage.removeItem('name') Object.keys(state).forEach(k => Vue.delete(state, k)) }, //显示 block(state,num){ state.count = num }, //消失 none(state,num){ state.count =num } }, actions:{ //异步 minusPriceAsync( context, payload ) { setTimeout( () => { context.commit( 'minusPrice', payload ); //绑定 mutations下面的方法(异步改变状态) }, 2000) }, // 登录 USER_SIGNIN(context, user) { context.commit('USER_SIGNIN', user) //绑定 mutations下面的方法(异步改变状态) }, // 退出 USER_SIGNOUT(context,user) { context.commit('USER_SIGNOUT',user) //绑定 mutations下面的方法(异步改变状态) }, blocking(context,item){ context.commit('block',item) //绑定 mutations下面的方法(异步改变状态) }, none(context,item){ context.commit('none',item) //绑定 mutations下面的方法(异步改变状态) } } }) new Vue({ el: '#app', router, store, //注入实例 components: { App }, template: '<App/>' }) header.vue文件 <template> <header class="header"> <div class="item left"> <slot name="left"></slot> </div> <div class="title">{{title}}</div> <div class="item right"> <slot name="right"></slot> </div> </header> </template> <script> export default { props:{ title:{ type:String, default:'' } } } </script> <style lang="scss" scoped> .header { position: relative; line-height: 38px; color: #fff; text-align: center; background: #222; .item { position: absolute; top: 0; bottom: 0; z-index: 1; a { color: #fff; } } .left { left: 10px; } .right { right: 10px; } } </style>
    Processed: 0.014, SQL: 9