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

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>

猜你喜欢

转载自blog.csdn.net/weixin_43959276/article/details/107095846
今日推荐