vue入门

简介: MVVM:M 是模型(model),V是视图(view),VM(ViewModel)是V和M的双向协调者

一、MVVM模式

MVVM

M 是模型(model),V是视图(view),VM(ViewModel)是V和M的双向协调者。

view

View是视图层,也就是用户界面。前端主要由HTML和css来构建,为了更方便地展现viewModel或者Model层的数据,已经产生了各种各样的前后端模板语言,比如FreeMarker、Thymeleaf等等,各大MVVM框架如Vue.js, AngularJs, EJS等也都有自己用来构建用户界面的内置模板语言。

model

Model是指数据模型,泛指后端进行的各种业务逻辑处理和数据操控,主要围绕数据库系统展开。这里的难点主要在于需要和前端约定统一的接口规则

ViewModel

ViewModel是由前端开发人员组织生成和维护的视图数据层。在这一层,前端开发者对从后端获取的Model数据进行转换处理,做二次封装,以生成符合View层使用预期的视图数据模型

需要注意的是ViewModel所封装出来的数据模型包括视图的状态行为两部分,而Model层的数据模型是只包含状态

  • 比如页面的这一块展示什么,那一块展示什么这些都属于视图状态(展示)
  • 页面加载进来时发生什么,点击这一块发生什么,这一块滚动时发生什么这些都属于视图行为(交互)

视图状态和行为都封装在了ViewModel里。这样的封装使得 ViewModel 可以完整地去描述View 层。由于实现了双向绑定,ViewModel的内容会实时展现在View层,这是激动人心的,因为前端开发者再也不必低效又麻烦地通过操纵 DOM 去更新视图。

MVVM 框架已经把最脏最累的一块做好了,我们开发者只需要处理和维护ViewModel,更新数据视图就会自动得到相应更新,真正实现事件驱动编程。 View 层展现的不是Model层的数据,而是ViewModel的数据,由ViewModel 负责与Model 层交互,这就完全解耦View 层和Model层,这个解耦是至关重要的,它是前后端分离方案实施的重要一环。

MVC

M 是模型,V是视图,C是控制器(业务)


vue使用了MVVM架构来设计框架。架构是说逻辑分层,框架是指具体的实现。

很明显VM的实现是这个框架的核心,也是最复杂的地方。从更大范围上看,vue专注界面的实现,也就是MVC中的V层。因此,vue只是一个局部框架,传统MVC中的模型和业务不是vue的范畴,需要自行设计。

  • Model:模型层,这里表示JavaScript对象
  • View:视图层,这里表示DOM(HTML操作的元素)
  • ViewModel:连接视图和数据的中间件

二、vue基础

1. 安装

<script>引入

直接下载并用 <script> 标签引入,Vue 会被注册为一个全局变量。

对于制作原型或学习,你可以这样使用最新版本:

<script src="https://cdn.jsdelivr.net/npm/vue"></script>

对于生产环境,我们推荐链接到一个明确的版本号和构建文件,以避免新版本造成的不可预期的破坏:

<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>

2. 常用操作

变量取值

标签内取值

使用双引号

<!--view层:模板-->

<divid="app"v-text="message">

</div>

<script>

   varvm=newVue({

       el:"#app",

       //model:数据对象

       data:{

           message:"hello world!"

       }

   })

</script>

标签外取值

使用双大括号{{}}

<!--view层:模板-->

<divid="app">

   {{ message }}

</div>

<script>

   varvm=newVue({

       el:"#app",

       //model:数据

       data:{

           message:"hello world!"

       }

   })

</script>

绑定HTML属性

v-bind

<divid="app">

   <pv-bind:title="title">html属性不能使用双大括号形式绑定,只能使用v-bind指令</p>

</div>

......

var vm = new Vue({

   el: '#app',

   data: {

       title: 'title content'

   }

});

这里的 html 最后会渲染成:

<divid="app">

   <ptitle="title content">html属性不能使用双大括号形式绑定,只能使用v-bind指令</p>

</div>

v-bind缩写

<!-- 完整语法 -->

<av-bind:href="url">...</a>

<!-- 缩写 -->

<a:href="url">...</a>

<!-- 动态参数的缩写 (2.6.0+) -->

<a:[key]="url"> ... </a>

条件

if-else

<divid="app">

   <pv-if="seen">seen为真</p>

   <pv-else>seen为假</p>

</div>

<script>

   varvm=newVue({

       el:"#app",

       data:{

           // seen:true

           seen:false

       }

   })

</script>

if-else-if

<divid="app">

<!--    ==只要求值相等,===要求类型和值都要相同-->

   <pv-if="type==='A'">A</p>

   <pv-else-if="type==='B'">B</p>

   <pv-else-if="type==='C'">C</p>

   <pv-else-if="type==='D'">D</p>

   <pv-else>0</p>

</div>

<script>

   varvm=newVue({

       el:"#app",

       data:{

           type:'1'

       }

   })

</script>

循环

v-for

<div id="app" >

   <ol>

       <li v-for="(todo,index) in todos">

           <!--index是当前遍历元素的索引-->

           {{ todo.text }}--{{index}}

       </li>

   </ol>

</div>


<script>

   var vm=new Vue({

       el:"#app",

       //js中对象用{},数组用[]

       data: {

           todos: [//数组中存放对象

               { text: '学习 JavaScript' },

               { text: '学习 Vue' },

               { text: '整个牛项目' }

           ]

       }

   })

</script>

事件处理

v-on

给按钮绑定单机事件,事件方法定义在methods对象中

<div id="app" >

   <button v-on:click="sayHello">点击我</button>

</div>


<script>

   var vm=new Vue({

       el:"#app",

       //js中对象用{},数组用[]

       data: {

           message:"hello"

       },

       methods:{//方法必须定义在methods对象中

           sayHello: function () {

               alert(this.message)

           }

       }

   })

</script>

v-on可以缩写

<!-- 完整语法 -->

<a v-on:click="doSomething">...</a>


<!-- 缩写 -->

<a @click="doSomething">...</a>

表单输入绑定

v-model

将表单与model变量进行双向绑定

  • 修改变量,表单内容也会改变
  • 修改表单内容,变量也会改变
文本

示例1:将输入框与变量message绑定

<div id="app" >

   输入的文本:<input type="text" v-model="message"> {{message}}

</div>


<script>

   var vm=new Vue({

       el:"#app",

       //js中对象用{},数组用[]

       data: {

           message:"hello"

       },

       methods:{//方法必须定义在methods对象中


       }

   })

</script>

单选框

实例2:将单选框与model变量message绑定,并且在下面展示出选择的内容

将单选框的value与message进行双向绑定

<div id="app">

   <input type="radio" value="男" v-model="message">男

   <input type="radio" value="女" v-model="message">女

   您的选择:{{message}}

</div>


<script>

   var vm=new Vue({

       el:"#app",

       //js中对象用{},数组用[]

       data: {

           message:""

       },

       methods:{//方法必须定义在methods对象中


       }

   })

</script>

下拉框

<div id="app">

   <select v-model="message">

       <option disabled value="">请选择</option>

       <option>A</option>

       <option>B</option>

       <option>C</option>

   </select>

   您的选择:{{message}}

</div>


<script>

   var vm=new Vue({

       el:"#app",

       //js中对象用{},数组用[]

       data: {

           message:""

       },

       methods:{//方法必须定义在methods对象中


       }

   })

</script>

3. Vue组件

组件是可复用的 Vue 实例,可以抽取公共片段,类似于thymeleaf的th:fragment

这里有一个 Vue 组件的示例:在template中编写可重用组件

<divid="app">

   <button-counter></button-counter>

</div>

<script>

   // 定义一个名为 button-counter 的新组件

   Vue.component('button-counter', {

       data: function () {

           return {

               count: 0

           }

       },

       template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'

   })

   

   varvm=newVue({

       el:"#app",

   })

</script>

组件是可复用的 Vue 实例,且带有一个名字:在这个例子中是 <button-counter>

  1. 一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝

通过 Prop 向子组件传递数据

用于修改公共页面的动态部分,如网页title,用户名等

Prop 是你可以在组件上注册的一些自定义 attribute。当一个值传递给一个 prop attribute 的时候,它就变成了那个组件实例的一个 property。

  1. 自定义组件:zujian
  2. 自定义组件的属性:shuxing
  3. 调用组件时,通过v-bind将组件属性与data变量绑定

<divid="app">

   <zujianv-bind:shuxing="title"></zujian>

</div>

<script>

   Vue.component('zujian',{

       props:['shuxing'],

       template:'<h3>{{ shuxing }}</h3>'

   })

   varvm=newVue({

       el:"#app",

       data:{

           title:"这是标题"

       }

   })

</script>

new Vue() 和 export default{}的区别

new Vue()

Vue 就是一个构造函数,生成的实例是一个巨大的对象,可以包含数据、模板、挂载元素、方法、生命周期钩子等选项。

所以渲染的时候,可以使用构造 Vue 实例的方式来渲染相应的 html 页面:

new Vue({

   el: '#app'

   ...

})

export default {}

这是在复用组件的时候用到的。假设我们写了一个单页面组件 A 文件,而在另一个文件 B 里面需要用到它,那么就要用 ES6 的 import/export 语法 ,在文件 A 中定义输出接口 export **,在文件 B 中引入 import **,然后再生成一个 Vue 实例 new Vue (**),把引入的组件用起来,这样就可以复用组件 A 去配合文件 B 生成 html 页面了。

所以在复用组件的时候,export 和 new Vue 缺一不可。

export 用来导出模块,Vue 的单文件组件通常需要导出一个对象,这个对象是 Vue 实例的选项对象,以便于在其它地方可以使用 import 引入。而 new Vue() 相当于一个构造函数,在入口文件 main.js 构造根组件的同时,如果根组件还包含其它子组件,那么 Vue 会通过引入的选项对象构造其对应的 Vue 实例,最终形成一棵组件树。

export 和export default 的区别在于:export 可以导出多个命名模块,例如:

//demo1.js

export const str = 'hello world'


export function f(a){

   return a+1

}

  对应的引入方式:

//demo2.js

import { str, f } from 'demo1'

  export default 只能导出一个默认模块,这个模块可以匿名,例如:

//demo1.js

export default {

   a: 'hello',

   b: 'world'      

}

  对应的引入方式:

//demo2.js

import obj from 'demo1'

引入的时候可以给这个模块取任意名字,例如 "obj",且不需要用大括号括起来。

三、Axios异步通信

cdn

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

get请求

{

 "name":"狂神说java",

 "url": "http://baidu.com",

 "page": 1,

 "isNonProfit":true,

 "address": {

   "street": "含光门",

   "city":"陕西西安",

   "country": "中国"

 },

 "links": [

   {

     "name": "B站",

     "url": "https://www.bilibili.com/"

   },

   {

     "name": 4399,

     "url": "https://www.4399.com/"

   },

   {

     "name": "百度",

     "url": "https://www.baidu.com/"

   }

 ]

}

<div id="app">

{{name}}

</div>


<script>

   var vm=new Vue({

       el:"#app",

       data:{

           name:'',

       },

       mounted(){//钩子函数,用来加载异步请求

           axios.get("data.json").then(response=>(this.name=response.data.address.city))

       }

   })

</script>

四、vue-cli

nodejs淘宝镜像加速

npm config set registry https://registry.npm.taobao.org

安装vue-cli

npm install vue-cli -g

创建

在projects文件夹下初始化vue项目

myvue是名字,一路no即可

vue init webpack myvue

进入myvue文件的cmd窗口,下载所有的依赖

cd myvue

npm install

运行

npm run dev

Ctrl+C停止

配置

vue.config.js

设置proxy与端口

proxy是ES6中就存在的,用于修改某些操作的默认行为,可以理解成在目标对象前设一个拦截层,因此也叫“代理器”。

如果你的前端应用和后端 API 服务器没有运行在同一个主机上,你需要在开发环境下将 API 请求代理到 API 服务器。这个问题可以通过 vue.config.js 中的 devServer.proxy 选项来配置。

module.exports={

 devServer: {

   disableHostCheck: false,

   port: 8181,  //指定项目运行的端口号端口号

   //配置代理

   proxy: {

     "/api": {

       target: "http://localhost:8080",//代理地址,这里设置的地址会代替axios中设置的baseURL

       changeOrigin: true,// 是否跨域,虚拟的站点需要更管origin

       pathRewrite: {

         "^/api": ""

         //pathRewrite: {'^/api': '/'} 重写之后url为 http://localhost:8080/xxxx

         //pathRewrite: {'^/api': '/api'} 重写之后url为 http://localhost:8080/api/xxxx

       }

     }

   },

 },

 chainWebpack: config=> {

   config.resolve.alias.set("@", resolve("src"));

 }

}

constpath=require("path");

functionresolve(dir) {

 returnpath.join(__dirname, dir);

}

axios请求

getNewsList() {

 axios.get('/api/getData')

   .then((res) => {

     console.log(res)

   })

}

  • axiosbaseURL 如果被配置过,如:baseURL="http://192.168.100.1/9000",此时proxy代理不生效

五、webpack

打包工具

安装

npm install webpack -g

npm install webpack-cli -g

查看版本

webpack -v

使用

一、定义一个模块hello.js

//暴露方法

exports.sayHello=function () {

   document.write("<h1>hello,webpack</h1>")

}

二、在main.js中引入hello模块,并调用其方法

//引入hello模块

var hello=require("./hello");

//调用hello模块中的sayHello方法

hello.sayHello()

三、创建 webpack.config.js 配置文件

  • entry:入口文件,指定WebPack 用哪个文件作为项目的入口
  • output:输出,指定WebPack把处理完成的文件放置到指定路径
  • module:模块,用于处理各种类型的文件
  • plugins:插件,如:热更新、代码重用等
  • resolve:设置路径指向
  • watch:监听,用于设置文件改动后直接打包

// entry:入口文件,指定WebPack 用哪个文件作为项目的入口

// output:输出,指定WebPack把处理完成的文件放置到指定路径

// module:模块,用于处理各种类型的文件

// plugins:插件,如:热更新、代码重用等

// resolve:设置路径指向

// watch:监听,用于设置文件改动后直接打包

module.exports={

   entry:"./modules/main.js",

   output:{

       filename:"./js/bundle.js"

   }

}

四、在命令行中使用webpack命令打包

webpack --watch可以实现热部署,实时监听变化

得到打包后的js文件:dist/js/bundle.js

五、在index.heml中导入打包后的js文件

<script src="dist/js/bundle.js"></script>

六、vue-router路由

npm install vue-router --save-dev

路由配置文件 src/router/index.js

类似controller的功能,将请求路径与资源进行绑定

那么每次路径的改变,其实是改变页面的组件,并不是加载一个新的页面

importVuefrom"vue";

importVueRouterfrom"vue-router";

importcontentfrom"../components/content";

importMainfrom"../components/Main";

//使用路由

Vue.use(VueRouter);

//配置导出路由

exportdefaultnewVueRouter({

 routes:[

   {

     //路由路径

     path:"/content",

     //路由名字

     name:"content",

     //跳转的组件

     component:content

   },

   {

   path: "/login",

   name: "登录",

   hidden: true,

   component: () =>import("../views/login/Login.vue")//vue3的新语法,将login.vue组件与路径"/login"进行绑定

  }

 ]

});

src/main.js

importVuefrom'vue'

importAppfrom'./App'

importrouterfrom"./router"//自动加载index.js配置

Vue.config.productionTip=false

newVue({

 //配置路由

 router,

 el: '#app',

 components: { App },

 template: '<App/>'

})

router-link和router.push

区别

使用router-link方式跳转,会在页面渲染的时候就加载对应的路由比起直接写的方式的优点:不管是h5的history还是hash模式,切换的时候很方便;会默认阻止浏览器的默认事件;写路径的时候不用写基路径了。

$router.push("/myroute")跳转到对应的路径,可在页面中写对应的点击事件,然后执行对应的方法中写跳转,可在跳转前再写一些别的逻辑。

<router-link :to="...">to里的值可以是一个字符串路径,或者一个描述地址的对象。例如:

// 字符串

<router-linkto="apple">toapple</router-link>

// 对象

<router-link :to="{path:'apple'}">toapple</router-link>

// 命名路由

<router-link :to="{name: 'applename'}">toapple</router-link>

//直接路由带查询参数query,地址栏变成 /apple?color=red

<router-link :to="{path: 'apple', query: {color: 'red' }}">toapple</router-link>

// 命名路由带查询参数query,地址栏变成/apple?color=red

<router-link :to="{name: 'applename', query: {color: 'red' }}">toapple</router-link>

//直接路由带路由参数params,params 不生效,如果提供了 path,params 会被忽略

<router-link :to="{path: 'apple', params: { color: 'red' }}">toapple</router-link>

// 命名路由带路由参数params,地址栏是/apple/red

<router-link :to="{name: 'applename', params: { color: 'red' }}">toapple</router-link>

同样的规则也适用于router.push(...)方法

// 字符串

router.push('apple')

// 对象

router.push({path:'apple'})

// 命名路由

router.push({name: 'applename'})

//直接路由带查询参数query,地址栏变成 /apple?color=red

router.push({path: 'apple', query: {color: 'red' }})

// 命名路由带查询参数query,地址栏变成/apple?color=red

router.push({name: 'applename', query: {color: 'red' }})

//直接路由带路由参数params,params 不生效,如果提供了 path,params 会被忽略

router.push({path:'applename', params:{ color: 'red' }})

// 命名路由带路由参数params,地址栏是/apple/red

router.push({name:'applename', params:{ color: 'red' }})

注意:

1、关于带参数的路由总结如下:

无论是直接路由“path" 还是命名路由“name”,带查询参数query,地址栏会变成“/url?查询参数名:查询参数值“;直接路由“path" 带路由参数params params 不生效;命名路由“name" 带路由参数params 地址栏保持是“/url/路由参数值”;

2、设置路由map里的path值:

带路由参数params时,路由map里的path应该写成: path:'/apple/:color' ;带查询参数query时,路由map里的path应该写成: path:'/apple' ;

3、获取参数方法:

在组件中: {{route.params.color}} 在js里: this.route.params.color

七、elementUI

//初始化项目

vueinitwebpackeleUI

//进入工程目录

cdeleUI

//安装vue-router

npminstallvue-router--save-dev

//安装elementUI

npmielement-ui-S

//安装依赖

npminstall

//安装SASS加载器

npminstallsass-loadernode-sass--save-dev

//启动测试

npmrundev

八、npm脚本

概念

npm 允许在package.json文件里面,使用scripts字段定义脚本命令。

{

 // ...

 "scripts": {

   "build": "node build.js"

 }

}

上面代码是package.json文件的一个片段,里面的scripts字段是一个对象。它的每一个属性,对应一段脚本。比如,build命令对应的脚本是node build.js

命令行下使用npm run命令,就可以执行这段脚本。

$ npm run build

# 等同于执行

$ node build.js

这些定义在package.json里面的脚本,就称为 npm 脚本。它的优点很多:

  • 项目的相关脚本,可以集中在一个地方。
  • 不同项目的脚本命令,只要功能相同,就可以有同样的对外接口。用户不需要知道怎么测试你的项目,只要运行npm run test即可。
  • 可以利用 npm 提供的很多辅助功能。

查看当前项目的所有 npm 脚本命令,可以使用不带任何参数的npm run命令。

$ npm run

参数

npm install packagename --save 或 -S

--save、-S参数意思是把模块的版本信息保存到dependencies(生产环境依赖)中,即你的package.json文件的dependencies字段中;

npm install packagename --save-dev 或 -D

--save-dev 、 -D参数意思是吧模块版本信息保存到devDependencies(开发环境依赖)中,即你的package.json文件的devDependencies字段中;

九、vuex

组件之间共享数据

Vuex中的主要核心概念如下:

  • State
  • Mutation
  • Action
  • Getter

State

在Vuex中,State提供唯一的公共数据源,所有共享的数据都要统一放到Store的State中进行存储,这里的Store相当于一个用于存储数据的公共容器。

conststore=newVue.Store({

   state: {

       count: 0

   }

   ...

})

在js中访问State中的数据

this.$store.state.全局数据名称

在HTML中

<span>{{$store.state.全局数据名称}}</span>

Mutation

mutation:变化

Vuex中的Mutation是用于变更Store中的数据。

在Vuex中,只能通过mutation变更Store数据,不可以直接操作Store中的数据。虽然通过mutation的方式来操作数据,虽然繁琐了一点,但是却可以集中监控所有数据的变化。

例如需要让全局数据自增加1,则可以通过如下的方式在Mutation中定义

conststore=newVuex.Store({

   state: {

       count: 0

   },

   mutations: {

       add(state) {

           //变更状态

           state.count++;

       }

   }

})

触发mutation函数

在方法中,通过$store.commit()函数来触发mutation

commit参数为mutation函数的名字

methods: {

   handle1 () {

       // 触发mutations的第一种方式

       this.$store.commit('add')

   }

}

接着就可以通过@click方法来调用handle1,从而来触发mutation函数。

另外,可以在触发mutation函数时,传入参数

conststore=newVuex.Store({

   state: {

       count: 0

   },

   mutations: {

       add(state) {

           //变更状态

           state.count++;

       },

       addN(state, n) {

           state.count+=n;

       }

   }

})

然后定义handler2

commit参数为mutation函数的名字和参数

methods: {

   handler2: {

       this.$store.commit('addN', 5);

   }

}

Action

从vuex官网中可以了解到,Action类似于mutation,不同之处在于:

  • Action 提交的是 mutation,而不是直接变更状态。
  • Action 可以包含任意异步操作。

可以得出一个结论就是,如果通过异步操作变更数据,必须通过Action,而不能使用Mutation,但是在Action中还是要通过触发Mutation的方式间接变更数据。

conststore=newVuex.Store({

   state: {

       count: 0

   },

   mutations: {

       add(state) {

           //变更状态

           state.count++;

       },

       addN(state, n) {

           state.count+=n;

       }

   },

   actions: {

       // 通过context去调用mutation

       addAsync(context) {

           setTimeout(() => {

             context.commit('add'  

           }, 1000)

       },

       // 调用Actions是也可以传入参数

       addNAsync(context, n) {

           setTimeout(() => {

               context.commit('addN', n);

           }, 1000);

       }

   }

})

需要再次强调的是,只有通过mutation中定义的函数,才有权利去修改state中的数据,因此actions最终还是要调用mutation。

触发action函数

methods: {

   handleAddAsync() {

       this.$store.dispatch('addAsync');

   },

   handleAddNAsync() {

       this.$store.dispatch('addNAsync', n);

   }

}

Getter

在Vuex官网中,用到了派生这一词来介绍Getter,在这里可以理解为就是用于对Store中的数据进行加工处理,形成新的数据,类似Vue的计算属性。Getter的数据是基于Store中的数据的,所以当Store中数据发生变化时,Getter中的数据也会随之变化。

定义Getter

例如state中存有todos计划项,其对象有一个done状态表示完成与否。

const store = new Vuex.Store({

 state: {

   todos: [

     { id: 1, text: '...', done: true },

     { id: 2, text: '...', done: false }

   ]

 },

 getters: {

   // 这里通过getters定义的doneTodos方法来过滤已完成的todo项

   doneTodos: state => {

     return state.todos.filter(todo => todo.done);

   },

   // 这里还可以通过传入getters对象来获取其他方法

   doneTodosCount: (state, getters) => {

       return getters.doneTools.length;

   },

   // 传入参数

   getTodoById: (state) => (id) => {

       return state.todos.find(todo => todo.id == id);

   }

 }

})

触发getter函数

this.$store.getters.doneTodos // -> [{id: 1, text: '...', done: true}]

this.$store.getters.doneTodosCount // -> 1

Module

当Store中存放了非常多非常大的共享数据对象时,应用会变的非常的复杂,Store对象也会非常臃肿,所以Vuex提供了一个Module模块来分隔Store。通过对Vuex中的Store分隔,分隔成一个一个的Module模块,每个Module模块都拥有自己的state、mutation、actions和getters。

const moduleA = {

 state: () => ({ ... }),

 mutations: { ... },

 actions: { ... },

 getters: { ... }

}


const moduleB = {

 state: () => ({ ... }),

 mutations: { ... },

 actions: { ... }

}


const store = new Vuex.Store({

 modules: {

   a: moduleA,

   b: moduleB

 }

})


store.state.a // -> moduleA 的状态

store.state.b // -> moduleB 的状态

对于模块中的mutations和getters,传入的第一个参数规定为state,而actions则依旧是context参数。如下:

const moduleA = {

 state: {

    count: 0

 },

 mutations: {

   increment (state) {

     // 这里的 `state` 对象是模块的局部状态

     state.count++

   }

 },


 getters: {

   doubleCount (state) {

     return state.count * 2

   }

 },

 actions: {

  // context对象其实包含了 state、commit、rootState。

  incrementIfOddRootsum (context) {

if ((context.state.count + context.rootState.count) % 2 === 1) {

       // 调用mutations

       commit('increment')

     }

  }

 }

}

总结

  1. Vuex主要用于管理Vue组件中共享的数据。
  2. Vuex中有state、mutation、action、getter等核心概念。
  3. 获取state可以通过this.$store.state.xx或者是通过定义mapState来获取。
  4. 修改state中的变量需要通过mutation函数实现,而mutation的触发由两种方式,一种是通过this.$store.commit()函数,另外一种是通过mapMutations来实现。
  5. mutation只能用于修改数据,而Actions可以实现异步操作。
  6. 通过Actions的异步操作+mutation的修改数据,可以实现异步修改数据。调用Actions有两种方式,第一种是通this.$store.dispatch来调用,另外一种方式是通过mapActions来调用。
  7. Getters函数用于对Store中数据进行加工,不会修改原本Store中的数据;Getters中的数据会受Store中数据进行影响。


目录
相关文章
|
7天前
|
缓存 JavaScript 前端开发
vue学习第四章
欢迎来到我的博客!我是瑞雨溪,一名热爱JavaScript与Vue的大一学生。本文介绍了Vue中计算属性的基本与复杂使用、setter/getter、与methods的对比及与侦听器的总结。如果你觉得有用,请关注我,将持续更新更多优质内容!🎉🎉🎉
vue学习第四章
|
7天前
|
JavaScript 前端开发
vue学习第九章(v-model)
欢迎来到我的博客,我是瑞雨溪,一名热爱JavaScript与Vue的大一学生,自学前端2年半,正向全栈进发。此篇介绍v-model在不同表单元素中的应用及修饰符的使用,希望能对你有所帮助。关注我,持续更新中!🎉🎉🎉
vue学习第九章(v-model)
|
7天前
|
JavaScript 前端开发 开发者
vue学习第十章(组件开发)
欢迎来到瑞雨溪的博客,一名热爱JavaScript与Vue的大一学生。本文深入讲解Vue组件的基本使用、全局与局部组件、父子组件通信及数据传递等内容,适合前端开发者学习参考。持续更新中,期待您的关注!🎉🎉🎉
vue学习第十章(组件开发)
|
13天前
|
JavaScript 前端开发
如何在 Vue 项目中配置 Tree Shaking?
通过以上针对 Webpack 或 Rollup 的配置方法,就可以在 Vue 项目中有效地启用 Tree Shaking,从而优化项目的打包体积,提高项目的性能和加载速度。在实际配置过程中,需要根据项目的具体情况和需求,对配置进行适当的调整和优化。
|
13天前
|
存储 缓存 JavaScript
在 Vue 中使用 computed 和 watch 时,性能问题探讨
本文探讨了在 Vue.js 中使用 computed 计算属性和 watch 监听器时可能遇到的性能问题,并提供了优化建议,帮助开发者提高应用性能。
|
13天前
|
存储 缓存 JavaScript
如何在大型 Vue 应用中有效地管理计算属性和侦听器
在大型 Vue 应用中,合理管理计算属性和侦听器是优化性能和维护性的关键。本文介绍了如何通过模块化、状态管理和避免冗余计算等方法,有效提升应用的响应性和可维护性。
|
13天前
|
存储 缓存 JavaScript
Vue 中 computed 和 watch 的差异
Vue 中的 `computed` 和 `watch` 都用于处理数据变化,但使用场景不同。`computed` 用于计算属性,依赖于其他数据自动更新;`watch` 用于监听数据变化,执行异步或复杂操作。
|
12天前
|
JavaScript 前端开发 UED
vue学习第二章
欢迎来到我的博客!我是一名自学了2年半前端的大一学生,熟悉JavaScript与Vue,目前正在向全栈方向发展。如果你从我的博客中有所收获,欢迎关注我,我将持续更新更多优质文章。你的支持是我最大的动力!🎉🎉🎉
|
14天前
|
存储 JavaScript 开发者
Vue 组件间通信的最佳实践
本文总结了 Vue.js 中组件间通信的多种方法,包括 props、事件、Vuex 状态管理等,帮助开发者选择最适合项目需求的通信方式,提高开发效率和代码可维护性。
|
12天前
|
JavaScript 前端开发 开发者
vue学习第一章
欢迎来到我的博客!我是瑞雨溪,一名热爱JavaScript和Vue的大一学生。自学前端2年半,熟悉JavaScript与Vue,正向全栈方向发展。博客内容涵盖Vue基础、列表展示及计数器案例等,希望能对你有所帮助。关注我,持续更新中!🎉🎉🎉
下一篇
无影云桌面