Vue学习笔记

Vue学习笔记

1.1、nodeJs

在安装vue之前,我们首先要在电脑上安装nodeJs,在百度上搜索nodeJs就可以下载了,其次还需要安装Visual Studio Code,这个是前端开发的工具,安装成功后即可安装vue了。

1.2、Vue的安装

vue的官网:vuejs.org

另外推荐使用v3.cn.vuejs.org

ctrl+R调出运行窗,输入cmd打开控制器终端,输入vue下载安装指令。

cnpm install -g @vue/cli

等待安装完成,在控制终端输入

vue --version

检测vue是否安装成功。

1.2.1、创建项目

打开VSCode,在盘符中创建一个文件夹用于存放项目代码,选择打开文件夹,选中创建的文件夹,打开项目后右键该项目,选择“在集成终端中打开”,在终端中输入如下指令创建vue项目:

vue create vue-demo

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LjFTN8fJ-1662712197001)(D:\xmImg\image-20220908143558400.png)]

1.2.2、创建时可能遇到的问题

在创建项目时,可能会遇到创建失败并报错的情况,大致内容为“禁止运行脚本”问题,这种情况为没有权限,使用

get -ExecutionPolicy

指令查看该权限,若结果为无权限,则使用如下代码修改权限:

set -ExecutionPolicy RemoteSigned

VSC指令选择为上下键,勾选和取消为空格键,回车键确认。

在创建项目时,建议将Manually select features勾选,将Linter/Formatter取消勾选。

1.2.3、运行项目
cd vue-demo
npm run serve
1.2.4、安装vue高亮插件

在运行vue项目后,查看代码时全黑状态,可点击VSC编辑器左边栏如下的操作按钮,在输入框中输入volar,选择骷髅头样式的,下载安装即可。关闭终端为ctrl+J。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bBZhiQqJ-1662712197003)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220908144342711.png)]

1.3、vue模板语言

vue的模板语言为双花括号:{{}},项目访问路径默认为localhost:8080

assets文件用于存放静态文件,app.vue是根组件,components是组件

1.3.1、vue中变量的创建与使用

vue中通过data函数创建变量,并通过{{变量}}的方式取值,如:

<template>
  <h3>message={{message}}</h3>
</template>

<script>
export default {
  name: 'HelloWorld',
  data(){
    return{
      message:"测试"
    }
  }
}
</script>
1.3.2、v-html指令

v-html指令能直接传输html标签,如下:

<template>
 <div v-html="rawhtml"></div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data(){
    return{
      rawhtml:"<a href='https://www.baidu.com'>百度</a>"
    }
  }
}
</script>
1.3.3、v-bind指令

v-bind用于绑定一个或多个属性值,或者向另一个组件传递props值

<div id="app">
		<!-- 不能使用mustache语法 把imgURL直接当成字符串 在内容里面才能使用-->
		<!-- <img src="{{imgURL}}" alt=""> -->
		<img v-bind:src="imgURL" alt="">
		<a v-bind:href="aHref">百度一下</a>
		<a :href="aHref">百度一下</a>
	</div>

	<script src="../js/vue.js"></script>

	<script>
		const app = new Vue({
			el: '#app',
			data: {
				message: 'nihao',
				imgURL:'https://m.360buyimg.com/babel/jfs/t1/49107/14/3176/6019/5d0eea59E238562fd/2576bcda7fc37edd.jpg',
				aHref:'http://www.baiu.com'
			}
		})
	</script>

很多时候,我们希望动态的来切换class,比如:
当数据为某个状态时,字体显示红色。
当数据另一个状态时,字体显示黑色。

绑定class有两种方式:
对象语法
数组语法

对象语法动态绑定class

对象语法的含义是:class后面跟的是一个对象。

.active{
	color:red;
}

<div id="app">
	<h2 :class="active">{{message}}</h2>
</div>

<script>
const app = new Vue({
	el: '#app',
	data: {
		message: 'nihao',
		active:'active'
	},
}
<h2 v-bind:class="{key:value}">{{message}}</h2>
<h2 v-bind:class="{类名:boolean}">{{message}}</h2>
<h2 v-bind:class="{active:true,line:false}">{{message}}</h2>

boolean值为true的时候,类就被添加。
一般把boolean值放到data中

<h2 v-bind:class="{active:isActive,line:isLine}">{{message}}</h2> 

data: {
	message: 'nihao',
	isActive:true,
	isLine:true
},

如果过于复杂,可以放在一个methods或者computed中

<h2 v-bind:class="getClasses()">{{message}}</h2>
<button v-on:click="btnClick">按钮</button>

methods:{
	getClasses: function () {
		return { active: this.isActive, line: this.isLine };
	},
	btnClick:function(){
		this.isActive=!this.isActive;
	},
}

数组语法的含义是:class后面跟的是一个数组。

<h2 class="title" :class="['active','line']">{{message}}</h2>
<!-- 没有单引号,是变量 -->
<h2 class="title" :class="[active,line]">{{message}}</h2>
v-bind绑定style

我们可以利用v-bind:style来绑定一些CSS内联样式。

我们可以使用驼峰式 (camelCase) fontSize
或短横线分隔 (kebab-case,记得用单引号括起来) ‘font-size’

<h2 :style="{key:value}">{{message}}</h2>
<h2 :style="{属性名:属性值}">{{message}}</h2>
<!-- 如果不加单引号,则是变量 -->
<h2 :style="{fontSize:'50px'}">{{message}}</h2>
<h2 :style="{fontSize:finalSize,color:finalColor}">{{message}}</h2>
<h2 :style="getStyles()">{{message}}</h2>

data: {
	message: 'nihao',
	finalSize:'100px',
	finalColor:'red'
},
methods:{
	getStyles:function(){
		return { fontSize: this.finalSize, color: this.finalColor }
	}
}

v-bind :id可改写为:id=“XXXX”

1.3.4、js表达式

vue支持使用表达式的方式,如

{{num+1}}
{{flag?"正确":"错误"}}
{{message.split("").revuerse().join("")}}

注意,表达式中只能绑定单个表达式!

1.4、渲染

1.4.1、条件渲染

所谓条件渲染,就是vue可用于做条件处理的方法,如v-if,v-show等,v-if在渲染页面时,若不为true,整个组件会被删除,而v-show则不是,它时基于css的消失,即style=“display:none”。

<template>
 <p v-if="flag">正确时才显示</p>
 <p v-else>否则的情况下显示</p>
 <p v-show="flag">flag为true时显示哦</p>
</template>

<script>
export default {
  name: 'HelloWorld',
  data(){
    return{
      flag:true
    }
  }
}
</script>

1.4.2、列表渲染
<template>
<ul>
  <li v-for="item in items">name={{item.name}}</li>
</ul>
</template>

<script>
export default {
  name: 'HelloWorld',
  data(){
    return{
      items:[{
          id:1,
          name:"张三"
      },{
        id:2,
        name:"李四"
      }
    ]
    }
  }
}
</script>

维护状态:数组中加入一条数据,列表渲染这一条时,不会重新把所有的都渲染一遍,实现方法:

<template>
<ul>
  <li v-for="item in items" :key="item.id">name={{item.name}}</li><!--加入:key-->
</ul>
</template>

<script>
export default {
  name: 'HelloWorld',
  data(){
    return{
      items:[{
          id:1,
          name:"张三"
      },{
        id:2,
        name:"李四"
      }
    ]
    }
  }
}
</script>
1.4.3、事件处理

v-on添加一个事件,可简写为@

事件的处理方法为methods,与data同级,用“,”隔开,在事件中,读取data中的属性,需要用this属性,方法中的event参数是原生Domevent。

<template>
  <p>{{message}}</p>
<button v-on:click="oneClick">点击1</button>
</template>

<script>
export default {
  name: 'HelloWorld',
  data(){
    return{
      message:""
    }
  },
methods:{
  oneClick(event){
    this.message="点击1",
    event.target.innerHTML="点击之后"
  }
}
}
</script>
内联处理器中的方法

通俗点说就是传参

<template>
  <p>{{message}}</p>
<button @click="say('hi')">hi</button>
<button @click="say('hello')">hello</button>
</template>

<script>
export default {
  name: 'HelloWorld',
  data(){
    return{
      message:""
    }
  },
methods:{
 say(data){
    this.message=data
    
  }
}
}
</script>
1.4.4、表单输入绑定

在日常开发过程中,获取表单填入的数据是非常重要的。

<template>
 用户名: <input type="text" v-model="username"/>
 <p>{{username}}</p>
 密码: <input type="text" v-model="password"/>
 <p>{{password}}</p>
</template>

<script>
export default {
  name: 'HelloWorld',
  data(){
    return{
      username:"",
      password:""
    }
  }
}
</script>
修饰符lazy

v-model在input输入同时,可以加入一个lazy属性,只有在改变结束时同步获取数据,能减少不适感和内存占用。

trim可去除多余的空格

<template>
 用户名: <input type="text" v-model.lazy="username"/>
 <p>{{username}}</p>
 密码: <input type="text" v-model.trim="password"/>
 <p>{{password}}</p>
</template>

<script>
export default {
  name: 'HelloWorld',
  data(){
    return{
      username:"",
      password:""
    }
  }
}
</script>

2.1、组件

2.1.1、单文件组件

*.vue是特殊的文件格式,内容分为三个部分,html标签位置、

在App.vue的script中,引入某个自定义的vue组件(自己写的页面)

import HelloWorld from './components/HelloWorld.vue'

挂载该组件

export default {
  name: 'App',
  components: {
    HelloWorld
  }
}

显示组件

<HelloWorld/>

若是在style组件中加入scoped属性,则是表示该样式只在当前组件中使用。

2.1.2、多文件组件

props组件交互

可以在组件上注册一些自定义的attribute

在属性前加“:”可以将属性编程动态的。

定义多组件交互,共分为以下几个步骤:

1、定义一个自己的组件,即*.vue文件,在script标签中标注自己的名字,如:

export default {
  name: 'MyApp'
 
}

2、在App.vue中挂载自己的组件,挂载方式见上面。

3、在app.vue中定义一个变量,变量赋值到标签上,如

4、在自己定义的组件中接收该值并显示

实现代码如下:

MyComponent.vue

<template>
<h3>{{title}}</h3>
</template>
<script>
export default{
    name:"myComponent",
    props:{
        title:{
            type:String,
            default:""
        }
    }
}
</script>
<style scoped>

</style>

app.vue

<template>
  <img alt="Vue logo" src="./assets/logo.png">
  <MyComponent :title="title"/>
</template>

<script>
import MyComponent from './components/MyComponent.vue'

export default {
  name: 'App',
  data(){
    return{
      title:"我是标题"
    }
  },
  components: {
    MyComponent
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

若是type为Array,数组和对象都必须要通过使用函数进行返回,如:

defaut:function(){
return []
}
2.1.3、自定义事件的组件交互

上一个是从父传到子,这一个则是从子到父

MyComponent.vue

<template>
<button @click="sendClickHandle">点击传递</button>
</template>
<script>
export default{
    name:"myComponent",
    data(){
        return{
            Message:"我是子数据"
        }
    },
    methods:{
       sendClickHandle(){
        //参数1:字符串,理论上自定义,但是需要有意义
        //参数2:传递的数据
        this.$emit("onEvent",this.Message)
       } 
    }
}
</script>
<style scoped>

</style>

app.vue

<template>
  <img alt="Vue logo" src="./assets/logo.png">
  <MyComponent @onEvent="getDataHandle"/>
  <p>{{message}}</p>
</template>

<script>
import MyComponent from './components/MyComponent.vue'

export default {
  name: 'App',
  
  data(){
    return{
      message:""
    }
  },
  components: {
    MyComponent
  },
  methods:{
    getDataHandle(data){
      this.message=data;
    }
  }
  }
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

2.2.1、组件生命周期

创建时:beforeCreate、create

渲染时:beforeMount、mounted

更新时:beforeUpdate、update

卸载时:beforeUnmount、unmounted

3.1、第三方 swiper

swiper是第三方的滑动触摸插件,先需要下载安装

官网:swiperjs.com.cn

​ swiper.com.cn

cnpm install --save swiper@8.1.6

使用swiper制作轮播图

<template>
  <swiper>
  <swiper-slide>
    <img src="../assets/linai.jpg" alt=""/>
  </swiper-slide>
  <swiper-slide>
    <img src="../assets/linai.jpg" alt=""/>
  </swiper-slide>
  <swiper-slide>
    <img src="../assets/linai.jpg" alt=""/>
  </swiper-slide>
</swiper>
</template>

<script>
  import {Swiper,SwiperSlide} from 'swiper/vue'
import 'swiper/css'
export default {
  name: 'HelloWorld',
  components:{
    Swiper,
    SwiperSlide
  }
}
</script>


<style scoped>
  img{
    width:auto;
  }
</style>

加入指示器

<template>
  <swiper :modules="modules" :pagination="{clickable:true}">
  <swiper-slide>
    <img src="../assets/linai.jpg" alt=""/>
  </swiper-slide>
  <swiper-slide>
    <img src="../assets/linai.jpg" alt=""/>
  </swiper-slide>
  <swiper-slide>
    <img src="../assets/linai.jpg" alt=""/>
  </swiper-slide>
</swiper>
</template>

<script>
  import { Pagination } from 'swiper'
  import {Swiper,SwiperSlide} from 'swiper/vue'
import 'swiper/css'
import 'swiper/css/pagination'
export default {
  name: 'HelloWorld',
  components:{
    Swiper,
    SwiperSlide
  },
  data(){
    return{
      modules:[Pagination]
    }
  }
}
</script>


<style scoped>
  img{
    width:auto;
  }
</style>

4.1、网络请求

4.1.1、Axior

Axior是基于promise的网络请求库

安装:

cnpm install --save axios

格式转换:

请求数据需要做格式转换,安装一个queryString

cnpm install --save querystrig

使用(局部引入):

get请求:

<template>
 
</template>

<script>
  
import axios from 'axios'
  import querystring from 'querystring';
export default {
  name: 'HelloWorld',
  mounted(){
    axios({
        method:"get",
        url:"XXXX"
    }).then(res=>{
      //成功后对数据处理的代码
    })
  }
}
</script>

post请求

<template>
 
</template>

<script>
  
import axios from 'axios'
  import querystring from 'querystring';
export default {
  name: 'HelloWorld',
  mounted(){
    axios({
        method:"post",
        url:"XXXX",
        data:querystring.stringify({
          id:1
        })
    }).then(res=>{
      //成功后对数据处理的代码
    })
  }
}
</script>


<style scoped>
</style>

简写版

get请求:

axios.get(url).then(res=>{})

post请求

axios.post(url,querystring.stringify().then(res=>{}))
4.1.2、全局引入

上面的方法是局部引入axios,每到一个页面就需要引入一次,增加了代码量,于是便有了全局引入的解决方案。

在main.js中引入:

import { createApp } from 'vue'
import App from './App.vue'
//引入axios
import axios from 'axios'
//挂载到全局
const app = createApp(App)
app.config.globalProperties.$axios=axios
app.mount('#app')
//createApp(App).mount('#app')改写成上方形式

使用:上面定义成了 符号,这边使用就用 符号,这边使用就用 符号,这边使用就用符号

HelloComponent.vue

this.$axios.post(url,querystring.stringify().then(res=>{}))
this.$axios.get(url).then(res=>{})
4.1.3、Axios网络请求封装

在日常的开发中,一个项目的网络请求往往很多,此时一般采取将网络请求封装起来的方法。

在src目录下新建一个utils文件夹,创建一个request.js文件

import axios from 'axios'
import { config } from 'process'
import querystring from 'querystring'
const instance=axios.create({
    timeout:5000
})

const errorHandle=(status,info)=>{
    switch(status){
        case 400:
            console.log("400:语意有误!");
            break;
            case 401:
                console.log("401:服务器认证失败!");
                break;
                case 403:
                    console.log("403:服务器拒绝访问!");
                    break;
                    case 404:
                        console.log("404:路径错误!");
                        break;
                        case 500:
                            console.log("500:服务器错误!");
                            break;
                            case 502:
                                console.log("502:服务器无响应!");
                                break;
                               default:
                                console.log(info);
                                break;
    }
}
//发送数据之前
instance.interceptors.request.use(
    config=>{
        if(config.method==="post"){
            config.data=querystring.stringify(config.data)
        }
        return config;
    },
    error=>{
        return Promise.reject(error)
    }
)
//获取数据之前
instance.interceptors.response.use(
    response=>{
        return response.status===200?Promise.resolve(response):Promise.reject(response)
    },
    error=>{
        const{response}=error;
        //错误处理最关键
        errorHandle(response.status,response.info)
    }
)

export default instance;

网络请求集中放在src目录下的api文件夹中的名为path.js的文件中

const base ={
    //公工路径,如www.baidu.com,至于后面的/XXX不写
    baseUrl:"http://www.XXX.com",
    shengyubufen:"/XXXX"
}

再建一个名为index.js的文件

import axios from "../utils/request";
import path from "./path"
const api={
    getXXX(){
        return axios.get(path.baseUrl+path.shengyubufen)
    }
}
export default api;

测试HelloWorld.vue

<template>
 
</template>

<script>
  
  import api from "../api/index"
  import querystring from 'querystring';
export default {
  name: 'HelloWorld',
  mounted(){
    api.getXXX().then(res=>{
      console.log(res.data)
    })
  }
}
</script>


<style scoped>
</style>
4.1.4、网络请求跨域问题

js采取的是同源策略

同源策略是浏览器的一项安全策略,浏览器只允许js代码请求喝当前所在服务器域名、端口、协议相同的数据接口上的数据,这就是同源策略。

也就是说,当协议、域名、端口任意一个不相同时,就会产生跨域问题

Access to XMLHttpRequest at ‘XXXXXXXX’

目前主流的跨域解决方案有两种:

①、后台解决:cors

②、前台解决:proxy

在vue.config.js文件中写如下代码:

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  devServer:{
    proxy:{
      '/api':{
		//只需要把域名放入就行了
        target:'<url>',
        changeOrigin:true
      }
    }
  }
})

温馨提示:解决完跨域问题后,记得重启服务器!

5.1、vue-router管理路由

在vue中,我们可以通过vue-router路由管理页面之间的关系

vue-router是vue.js的官方路由,它与vue.js核心深度集成,让用vue.js构建单页应用变得轻而易举

5.1.1、安装
npm install -save vue-router
5.1.2、配置独立的路由文件

index.js

import { createRouter,createWebHashHistory} from "vue-router"
import HomeView from'../view/HomeView.vue'

//配置信息中需要页面的相关配置

const routes = [
    {
        path:"/",
        name:"home",
        //名为HomeView的vue页面
        component:HomeView
    },{
        path:"/about",
        name:"about",
        //异步加载  名为AboutView.vue的vue页面
        component:()=>import("../view/AboutView.vue")
    }
]
const router = createRouter({
    history:createWebHashHistory(),
    routes
})
export default router;

测试时需建立两个以上vue页面,此处分别为名为HomeView.vue的文件和AboutView.vue的文件

主入口引入router(main.js)中

import { createApp } from 'vue'
import App from './App.vue'
import router from "./router"

createApp(App).use(router).mount('#app')

在Hello World中配置路由的显示入口

<template>
  
    <router-view></router-view>
</template>

<script>
export default {
  name: 'HelloWorld'
}
</script>

此时访问页面,该页面会加载在HelloWorld中,且路径变成了http://localhost:8081/#/,在后面加上about即可访问关于页面。

<template>
  
    <router-view></router-view>
    <router-link to="/">首页</router-link>
    <router-link to="/about">关于</router-link>
</template>

<script>
export default {
  name: 'HelloWorld'
}
</script>

上方为加上跳转按钮的实现代码。

5.1.3、createWebHashHistiry与createWebHistiry的区别

createWebHashHistiry:路径上会有”/#“

createWebHistiry:此种方式需要后台配合做重定向,否则会404

原理:

createWebHashHistiry:a标签锚点连接

createWebHistiry:H5 push state()

5.1.4、路由传参

页面跳转过程中,往往会有传参的情况,因此便有了如下解决方案

搭建项目时,可勾选router,这样就不用自己再创建了

创建完成后,可建立一个vue页面,这里以news为例

先创建vue文件,再去index.js中配置该文件的路径

NewsView.vue

<template>
    <h3>新闻</h3>
    <ul>
        <li><router-link to="details/百度">百度</router-link></li>
        <li><router-link to="details/网易">网易</router-link></li>
        <li><router-link to="details/头条">头条</router-link></li>
    </ul>
</template>

NewsDetails.vue

<template>
    <h3>新闻详情</h3>
    <p>{{ $route.params.name }}</p>
</template>

HelloWorld.vue

<template>
  
    <router-view></router-view>
    <router-link to="/">首页</router-link>
    <router-link to="/about">关于</router-link>
    <router-link to="/news">新闻</router-link>
</template>

<script>
export default {
  name: 'HelloWorld'
}
</script>

index.js

 {
        path:"/news",
        name:"news",
        component:()=>import("../view/NewsView.vue")
    },
    {
        path:"/details/:name",
        name:"details",
        component:()=>import("../view/NewsDetails.vue")
    }

其中 path:“/details/:name”,中”/:name“为参数

路由传递参数共分为三步:

第一步:咋路由配置中指定参数的key,即上面写到的”/:name”

第二步:在跳转过程中携带参数,即to=“details/百度”

第三步:在详情页面读取路由携带的参数,即{{ $route.params.name }}

5.1.5、嵌套路由配置

例如:左边导航时的父子导航

现在view文件夹下创建一个名为AboutSub的文件夹,在此文件夹下创建两个vue文件,分别为AboutInfo.vue、AboutUs.vue

AboutInfo.vue

<template>
    <h3>信息</h3>
</template>
<script>

</script>
<style scoped></style>

AboutUs.vue

<template>
    <h3>我们</h3>
</template>
<script>

</script>
<style scoped></style>

然后在index.js中配置该页面的路径

{
        path:"/about",
        name:"about",
        //异步加载  名为AboutView.vue的vue页面
        component:()=>import("../view/AboutView.vue"),
        children:[{
            //二级导航的路径不要加
            path:"us",
            component:()=>import("../view/AboutSub/AboutUs.vue")
        },
        {
            //二级导航的路径不要加
            path:"info",
            component:()=>import("../view/AboutSub/AboutInfo.vue")
        }]
    }

再去到aboutView.vue中配置路径

<template>
    //此处要写全路径
    <router-link to="/about/us">关于我们</router-link>
    <router-link to="/about/info">关于信息</router-link>
    <router-view></router-view>
</template>
<script></script>
<style scoped></style>

重定向:redirect:“/about/us”

5.2、vuex状态管理

Vuex是一个专为Vue.js 应用程序开发的状态管理模式+库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
简单来说,状态管理可以理解成为了更方便的管理组件之间的数据交互,提供了一-个集中式的管理方案,任何组件都可以按照指定的方式进行读取和改变数据。

5.2.1、安装
npm install --save vuex
5.2.2、配置

在src目录下创建一个store文件夹,文件夹中创建一个名为index.js的文件

import { createStore } from "vuex"
//vuex的核心作用就是帮我们管理组件之间的状态的
export default createStore({
    //所有的状态都放在这里(数据)
state:{
    counter:0
}
})

将这个文件引入到main.js中

import store from './store'
createApp(App).use(store).mount('#app')

在组件中读取状态(测试)

//HelloWorld中
<p>{{ $store.state.counter }}</p>
//App.vue中
<p>{{ $store.state.counter }}</p>

如果在一个组件中读取很多次,则用下面的方法

<template>
 
    <p>{{ counter }}</p>

</template>

<script>
  import {mapState} from "vuex"
export default {
  name: 'HelloWorld',
  computed:{
    ...mapState(["counter"])
  }
}
</script>

<style scoped>

</style>

5.3、vuex状态管理核心

最常用的核心概念包含:State、Getter、Mutation、Action

5.3.1、Getter

对vuex中的数据进行过滤(store文件夹下index.js)

import { createStore } from "vuex"
//vuex的核心作用就是帮我们管理组件之间的状态的
export default createStore({
    //所有的状态都放在这里(数据)
state:{
    counter:0
},
getters:{
    getCounter(state){
        return state.counter>0?state.counter:"异常"
    }
}
})

测试(HelloWorld)

<template>
 
    <p>{{ $store.getters.getCounter }}</p>

</template>

<script>
export default {
  name: 'HelloWorld'
}
</script>

<style scoped>

</style>

另一种方案

<template>
 
    <p>{{ $store.getters.getCounter }}</p>
<p>{{ getCounter }}</p>
</template>

<script>
import { mapGetters } from 'vuex';

export default {
  name: 'HelloWorld',
  components:{

  },
  computed:{
    ...mapGetters(["getCounter"])
  }
}
</script>

<style scoped>

</style>

5.3.2、Mutation

更改Vuex的store中的状态的唯一方法是提交mutationVuex中的mutation非常类似于事件:每个mutation都有一个字符串的事件类型(type)和一个回调函数(handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受state作为第一个参数。

index.js

import { createStore } from "vuex"
//vuex的核心作用就是帮我们管理组件之间的状态的
export default createStore({
    //所有的状态都放在这里(数据)
state:{
    counter:10
},
getters:{
    getCounter(state){
        return state.counter>0?state.counter:"异常"
    }
},
mutations:{
    addCounter(state,num){
        state.counter+=num
    }
}
})

helloworld.vue

<template>
 
<button @clock="addClick">增加</button>
</template>

<script>
import { mapGetters } from 'vuex';

export default {
  name: 'HelloWorld',
  components:{

  },
  computed:{
    ...mapGetters(["getCounter"])
  },
  methods:{
    addClick(){
      this.$store.commit("addCounter",16)
    }
  }
}
</script>

<style scoped>

</style>

第二种方式

<template>
 
<button @clock="addClick">增加</button>
</template>

<script>
import { mapGetters, mapMutations } from 'vuex';

export default {
  name: 'HelloWorld',
  components:{

  },
  computed:{
    ...mapGetters(["getCounter"])
  },
  methods:{
    ...mapMutations(["addCounter"]),
    addClick(){
      //this.$store.commit("addCounter",16)
      this.addCounter(20)
    }
  }
}
</script>

<style scoped>

</style>

5.3.3、Action

Action类似于mutation,不同在于:
●Action 提交的是mutation,而不是直接变更状态
●Action 可以包含任意异步操作

idex.js

import axios from "axios"
//为异步操作准备的
actions:{
    ansyncAddCounter({commit}){
        axios.get("XXXXXXX").then(res=>{
            commit("addCounter",res.data[0])
        })
    }
}

helloworld.vue

<template>
<div class= "home">
< img
alt="Vue logo"
src=". ./as sets/ logo . png">
<h3> home< /h3>
<p> count={{ $store . getters. getCounter }}</p>
<p>{{ getCounter }}</p>
<button @click=" addClickHandle" >增加< /button>
<button @click=" addAsyncClickHandle">异步增加< /button> 
</div>
</ template>
<script>
import { mapGetters , mapMutations,mapActions } from "vuex" 
export default {
name: ' HomeView' 
components: {
},
computed:{
. mapGetters([" getCounter" ])
},
methods:{
.. . mapMutations ([" addCounter"]),
... mapActions( ["asyncAddCounter"]), 
addClickHandle(){
//固定调用方式
/ this . $store. commit(”addCounter" ,15)
this . addCounter(20)
};
addAsyncCl ickHandle( ){
// this . $store . dispatch("asyncAddCounter");| I
this . asyncAddCounter();
}
</script>

Click">增加


#### 5.3.3、Action

Action类似于mutation,不同在于:
●Action 提交的是mutation,而不是直接变更状态
●Action 可以包含任意异步操作

idex.js

```vue
import axios from "axios"
//为异步操作准备的
actions:{
    ansyncAddCounter({commit}){
        axios.get("XXXXXXX").then(res=>{
            commit("addCounter",res.data[0])
        })
    }
}

helloworld.vue

<template>
<div class= "home">
< img
alt="Vue logo"
src=". ./as sets/ logo . png">
<h3> home< /h3>
<p> count={{ $store . getters. getCounter }}</p>
<p>{{ getCounter }}</p>
<button @click=" addClickHandle" >增加< /button>
<button @click=" addAsyncClickHandle">异步增加< /button> 
</div>
</ template>
<script>
import { mapGetters , mapMutations,mapActions } from "vuex" 
export default {
name: ' HomeView' 
components: {
},
computed:{
. mapGetters([" getCounter" ])
},
methods:{
.. . mapMutations ([" addCounter"]),
... mapActions( ["asyncAddCounter"]), 
addClickHandle(){
//固定调用方式
/ this . $store. commit(”addCounter" ,15)
this . addCounter(20)
};
addAsyncCl ickHandle( ){
// this . $store . dispatch("asyncAddCounter");| I
this . asyncAddCounter();
}
</script>
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

甜甜圈的小饼干

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值