引入
1、cdn引入
开发环境cdn:
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
生产环境cdn:
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
2、下载与引入
通过官网下载源码,并且通过<script>引入
3、npm安装
vue的MVVM
Vue的原理
通过建立虚拟dom树
document.createDocumentFragment()
,方法创建虚拟dom树。一旦被监测的数据改变,会通过Object.defineProperty定义的数据拦截,截取到数据的变化。
截取到的数据变化,从而通过订阅者——发布者模式,触发Watcher(观察者),从而改变虚拟dom的中的具体数据。
最后,通过更新虚拟dom的元素值,从而改变最后渲染dom树的值,完成双向绑定。
Vue的模式是m-v-vm模式,即(model-view-modelView),通过modelView作为中间层(即vm的实例),进行双向数据的绑定与变化。
而实现这种双向绑定的关键就在于:
Object.defineProperty和订阅——发布者模式这两点。
下面我们通过实例来实现Vue的基本双向绑定。
Vue的options选项
el:vue实例管理哪一个DOM
data:组件化中必须传对象
methods:vue实例中的方法
components:组件
computed:计算属性
watch:监视,是一个对象。
键是需要观察的表达式,
值是:
- 回调函数
- 方法名
- 包含选项的对象
created :function(){}
mounted:
Vue的生命周期
生命周期
诞生到消亡的整个过程。
Vue指令
插值指令
v-once 后面没有表达式。让显示的东西不响应式,即后期修改了对象属性值页面上的显示的不同步变化。
v-html 后面写属性名。把属性值以html的形式插入到此标签里面。
v-text 后面写属性名。把属性值以文本的形式插入到此标签里面。标签原有的内容会被覆盖。
v-pre 后面没有表达式。去除{{}}表达式效果,使里面的文本原封不动显示出来。
v-cloak 后面没有表达式。给元素添加一个属性,这个属性可以添加css样式,使其隐藏。vue解析以后就去除这个属性。用于解决界面闪烁。
v-for
循环数据。
<body>
<div id="app">
<!-- v-for -->
<ul>
菜式
<li v-for="(item,index) in food">{{index+1}}、{{item}}</li>
<!-- item为属性值,index为索引值,v-for会循环每一个元素并且创建相同的元素节点显示数据 -->
<li v-for="(value,key,index) in person">{{index+1}},{{key}},{{value}}</li>
客人
<!--v-for还可以遍历对象,value为对象属性值,key为对象属性名,index为索引-->
<li v-for="(item,index) in food" :key="item">{{index+1}}、{{item}}</li>
<!--可以为对应的元素添加key属性,当我们对数组进行增删改时,可以提高更新虚拟DOM的性能-->
</ul>
</div>
</body>
<script>
const app = new Vue({
el:"#app",
data:{
food:["大鸡腿","土豆丝","土豆丝","嫩鲍鱼"],
person:{
name:"xiaoming",
age:19,
height:178
}
},
})
</script>
以下方法对数组元素进行操作时,dom同步更新。(响应式)
- push() 后面添加
- pop() 后面删除
- shift() 前面删除
- unshift() 前面添加
- splice() 切割、拼接
- sort() 排序
- reverse() 倒序
通过索引值修改数组元素不会同步更新到页面 --> arr[0]="aaaaaa";
通过Vue实现的修改数组元素方法实现响应式Vue.set(arr,index,value) -(目标数组,目标索引,要修改的值)。
v-bind
动态绑定属性值。会把标签里面属性值当作一个变量传到vue中,把变量的值返回到标签得属性。
<body>
<div id="app">
<!-- v-bind -->
<a v-bind:href="src">v-bind的使用</a>
<a :href="src">v-bind的简写</a>
<div :my="src">v-bind可以为任意的属性赋值</div>
<p class="title" :class="{active:true,line:flag}">
对象语法:通过对象的键作为类名,值(boolean)作为判断是否采用,值也可以用data里面的属性代替。会拼接原有的class。</p>
<p :class="arr">数组语法:跟对象语法相似。</p>
<div :style="style">直接绑定设置style</div>
<input :value="age">设置计算属性,计算属性设置在computed里,虽然定义是函数,但是是一个属性,使用时不加()。
</div>
</body>
<script>
const app = new Vue({
el:"#app",
data:{
src:"https://www.baidu.com",
flag:false,
arr:["active","line"],
style:{
width:"100px",
height:"100px",
backgroundColor:"green"
},
value:10
},
computed:{
age:function(){
return this.value + 12;
}
/*
上面的计算属性的真面目
age:{
set:function(value){
//this.value=value; 实际上我们会让set空着,只是用get。
},
get:function(value){
return this.value + 12;
}
}
*/
}
})
</script>
computed和methods
也可以把计算属性直接定义在methods里面,但是为什么要使用computed呢?
因为在methods里的function,每一次使用都会执行。
但是多次调用computed里的计算属性时,他只执行了一次后形成了缓存,如果value值不发生变化,后续都使用这个缓存。性能比methods好。
v-on
事件监听,当用户触发事件时执行特定的方法。
</body>
<div id="app">
<button v-on:click="fn1()">v-on的使用</button>
<button @click="fn2(2)">v-on可以简写为@click,函数体还可以传递参数</button>
<button @click="fn3(name)">以对象属性作为参数</button>
<button @click="fn4($event)">获取事件对象用$event</button>
<div @click="Div()">
<p @click.stop="Button()">使用.stop修饰符取消事件冒泡</p>
</div>
<form action="test.html">
<input type="text" @keyup.enter="keyUp()">当用户使用键盘事件且点击Enter时触发事件<br/>
<input type="submit" value="提交" @click.prevent="mySubmit()">使用.prevent修饰符阻止默认事件
</form>
<button @click.once="Once()">用户第一次点击时触发</button>
</div>
</body>
<script>
const app = new Vue({
el:"#app",
data:{
name:"shabi"
},
methods:{
fn1(){console.log(1);},
fn2(a){console.log(a)},
fn3(name){console.log(name);},
fn4(e){console.log(e);},
Div(){console.log("div")},
Button(){console.log("button")},
mySubmit(){console.log("submit")},
keyUp(){console.log("key up!")},
Once(){console.log(1)}
}
})
</script>
.prevent 阻止默认行为,相当于原生preventDefault
.stop 阻止冒泡传播,相当于stopPropergation
.once 当前函数指回执行一次
.self 只有点击元素本身才会触发这个函数
.capture 在捕获阶段执行,相当于ele.addEventListener('click',fn,==false==)
.passive 先执行默认,后执行此函数
v-if , v-else-if , v-else
条件判断,使元素进行显示或者不显示。
<body>
<div id="app">
<div v-if="flag">
<h4>if的值或条件判断结果为true时显示</h4>
</div>
<div v-else>当v-if不显示时显示</div>
----------------------------------
<div v-if="score>=90">优秀</div>
<div v-else-if="score>=80">良好</div>
<div v-else-if="score>=60">及格</div>
<div v-else>不及格</div>
</div>
</body>
<script>
const app = new Vue({
el:"#app",
data:{
flag:true,
score:85
},
})
</script>
v-show
语法与v-if一样。
但是不显示时,v-if的元素不存在于document上,v-show元素存在只是display=none。
v-if是对dom进行增加和删除,v-show是对dom进行display=block/none;
v-model
Vue的核心特性之一是双向绑定,vue的响应式原理是实现了数据->视图,接下来我们要学习 视图->数据的原理。
v-model是一个指令,限制在<input>、<select>、<textarea>、components中使用。
<body>
<div id="app">
<form action="#">
<input type="text" v-model="name">v-model的使用,在表单元素上添加v-model,他的值为data里面的变量。</br>
<h4>{{name}}</h4>输入框文字变化,name的值动态变化,即双向绑定。</br>
<input type="text" :value="name" @input="name = $event.target.value">双向绑定原理</br>
v-model的单选框radio使用:
男<input type="radio" value="男" name="sex" v-model="sex">
女<input type="radio" value="女" name="sex" v-model="sex"><br>
v-model的多选框checkbox使用:
苹果 <input type="checkbox" value="苹果" name="fruit" v-model="fruit">
香蕉 <input type="checkbox" value="香蕉" name="fruit" v-model="fruit">
西瓜 <input type="checkbox" value="西瓜" name="fruit" v-model="fruit">
(使用数组接收)<br>
v-model的下拉框select的使用:
<select v-model="sport">
<option value="唱">唱</option>
<option value="跳">跳</option>
<option value="rap">rap</option>
<option value="篮球">篮球</option>
</select>
</form>
</div>
</body>
<script>
const app = new Vue({
el:"#app",
data:{
name:"小明",
sex:'',
fruit:[],
sport:'rap'
},
})
</script>
v-model值绑定:使用单选,多选,下拉框的时候,不用再html上写死,可以把可选项写到data数组里面,再用v-for写入到html中,是页面更加灵活。
.lazy(取代 input 监听 change 事件),使得输入框失去焦点时数据才更新。
.number(输入字符串转为有效的数字),输入框的内容都当作字符串处理,这个可以让他转换为数字类型。
.trim(输入首尾空格过滤),过滤内容两边的空格。
Vue组件化
组件化是vue.js中的重要思想
- 它提供一种抽象,让我们可以开发出一个个独立使用的小组件来构造我们的应用。
- 任何的应用都会被抽象成一棵组件树。
注册组件基本步骤
- 创建组件构造器
- 注册组件
- 使用组件
<body>
<div id="app">
<my-cpn></my-cpn><!--3、组件的使用-->
</div>
</body>
<script>
// 1、创建组件构造器对象
const cpnC = Vue.extend({
template:
`<div>
<h1>标题</h1>
<p>内容1</p>
<p>内容2</p>
</div>`
})
// 2、注册组件
Vue.component('my-cpn',cpnC);//参数为标签名,组件构造器
</script>
全局组件和局部组件
全局组件
意味着可以在多个Vue实例中使用。上面那种方式就是全局组件的创建方式,把创建和注册的步骤写在实例的外面。
局部组件
在特定的Vue实例中使用。第二步注册的是否在要使用的Vue实例的Components里面注册局部组件。
const app = new Vue({
el:"#app",
data:{},
components:{
// 2、注册局部组件 标签名:构造器对象
cpn:cpnC
}
})
父组件和子组件
Vue实例也可以看作是最大的父组件,叫做root component,其他的组件都属于他的子组件。
必须在Vue实例中注册了才可以在HTML中使用。
组件注册语法糖
// 省去Vue.extend创建组件对象,注册组件时直接创建对象。
Vue.component('my-cpn',{
template:
`<div>
<h1>标题</h1>
<p>内容1</p>
<p>内容2</p>
</div>`
});
//使用<my-cpn></my-cpn>
//如果是局部组件就在component里面写:
components:{
Cpn:{
template:
`<div>
<h1>标题</h1>
<p>内容</p>
</div>`
}
}
组件模板抽离
使用script标签
把模板写到script标签里面,type="text/x-template",通过id获取。
<script type="text/x-template" id="cpn"></script>
使用template标签
把模板写到template标签里面,通过id获取。
<template id="cpn"></template>
组件的数据存放
组件内部不能直接访问Vue实例里面的data,而在注册组件时,可以有自己的data、methods等。这个data不是一个对象类型而是一个函数,并且需要return一个对象,这个对象才是组件真正能访问的数据。
<template id="cpn">
<div>模板
<h2>{{title}}</h2>
<p>{{content}}</p>
</div>
</template>
<script>
Vue.component("cpn",{
template: '#cpn',
data(){
//这是组件访问数据的地方。
return{
title:"这是一个标题",
content:"这是一段文字"
}
}
})
</script>
为什么组件的data是一个函数?
因为函数返回的时一个对象,每个组件访问data时都会返回唯一的一个对象,当组件需要对数据进行操作的时候,指挥操作自己的对象数据,而不会影响到其他组件的数据。如果data时一个对象,那么每次操作数据时其他组件也会同步变化。
父子组件之间的通信
子组件不能直接访问父组件的数据,所以需要父组件与子组件之间进行通信。
- props 父-->子
- $emit 子-->父
父传子 props
props可以是数组、对象、字符串、Boolean、Function等...
// props:["film"],可以写成数组形式
props:{//也可以写成对象
film:{
type:Array,//类型
required:true,//是否必须传值
default:'当没有传值时默认的值',
default(){
//也可以写成函数形式
return 0;
}
}
}
1、父组件定义一个属性info,应用子组件的标签双向绑定或普通绑定自定义属性:myinfo="info";
2、子组件的option写一个props,里面有一个属性叫myinfo的空对象用于接收数据
3、在子组件模板使用myinfo
props属性校验
在子组件中进行,即使验证失败会有错误提示,但是组件会正常渲染。
props: {
data: {
type: String,//type的类型是任意类型
default: "defalutData",
//如果type类型是Array或Object,dafalut必须是一个函数,他的返回值为默认值
require: true//声明这个参数是否必须传入
}
}
子传父 $emit
$emit用于触发当前实例上的事件,附加参数都会传给监听器回调。
使用:
原理:
1、子组件定义属性categories,并且在组件某个地方触发发送函数btnClick
2、btnClick通过this.$emit('my-event',this.categories)把自定义事件发送个事件池。
3、父组件在事件池中取出@my-event="myfn(a)"自定义事件和方法
4、myfn(a)通过接收的参数a获取到emit过来的参数。
emit 触发。回调函数会接收所有传入事件触发函数的额外参数。
this.$on('my-event',(value)={
console.log(value);
})
监听自定义事件my-event
,每当触发此事件后都会触发$on。
父子组件的访问方式
父组件访问子组件refs
$children
methods:{
btnClick(){
console.log(this.$children.name);
//this.$children保存组件的某些信息,可通过这个来访问组件的属性
}
}
可以在mounted或者函数里面打印this.$children
,是一个数组,包含了所有组件的信息。
通常来说我们不使用children是一个数组,里面存了全部组件对象,而且不是响应式的。当我们添加了组件时,数组下标就发生了变化,此时以前指定的组件就变了。
$refs
更好的方法
<div id="app">
<tag ref="one"></tag>
<tag ref="two"></tag>
<!--在子组件上添加ref属性-->
<tag></tag>
<button @click="btnClick">btn</button>
</div>
<script>
//父组件的方法可以直接获取到refs对象,包含了有ref属性的所有组件
methods:{
btnClick(){
this.$refs.one.showMessage();
this.$refs.two.showMessage();
//通过设置的ref精准获取到特定的组件
}
}
</script>
子组件标签上设置ref属性,触发事件就可以打印refs.name就可以找到对应的组件
子组件访问父组件$parent
$parent指代组件的上一层组件,不建议使用。
因为组件是可以复用的,当复用的情况不一样是会造成$parent指代不明。
<template id="temp">
<div>
<p>子组件</p>
<button @click="btnClick">btn</button>
<!--在组件内部监听事件-->
</div>
</template>
<script>
components:{
tag:{
template:"#temp",
methods:{
btnClick(){
console.log(this.$parent.info)
//触发事件时直接访问$parent,即直接访问上一层的组件。
console.log(this.$root)
//触发事件时访问$root,即直接访问Vue实例。
}
}
}
}
</script>
组件信息通讯EventBus
EventBus--事件总线--完全的发布订阅模式。
原理:无论是父子组件还是兄弟组件或者不相关的组件,只要保证每个组件都可以获取到这个==事件池==即可。
Slot插槽
组件的插槽让组件具有更强的扩展性,让使用者决定组件内部的展示。
基本使用<slot>
插槽定义在子组件,父组件使用子组件<son></son>时,在中间使用标签就会代替掉子组件的插槽。中间不使用插槽则使用子组件的默认标签。
具名插槽的使用
<div id="app">
<tag>
<span slot="title">这是标题</span><!--通过slot名找到指定的spot-->
<p slot="content">这是内容</p><!--通过spot名找到指定的spot-->
</tag>
</div>
<template id="temp">
<div>
<slot name="title"></slot>
<p>子组件</p>
<slot name="content"></slot>
</div>
</template>
子组件定义插槽时给插槽加name,父组件使用插槽时给标签加上slot=name就会用上指定的插槽。
编译作用域
<div id="app">
<tag v-show="show"></tag><!--这个show使用的是Vue实例的show-->
</div>
<template id="temp">
<div>
<p v-show="show">子组件</p><!--这个show使用的是组件里面的show-->
</div>
</template>
父组件模板的所有东西都会在父级作用域内编译;子组件模板的所有东西都会在子级作用域内编译。父子组件之间不能直接访问。
作用域插槽
当我们需要对组件进行数据自定义显示的时候,可用到作用域插槽进行自定义。
父组件替换插槽标签,但是内容由子组件来提供。
<div id="app">
<tag></tag><!--普通显示-->
<tag>
<template slot-scope="slot"><!--利用template标签的slot-scope属性获取子组件的作用域为slot-->
<span>{{slot.data.join(" - ")}}</span><!--slot.data即为子组件的data-->
</template>
</tag>
</div>
<template id="temp">
<div>
<slot :data="language"><!--自定义一个属性并且存需要的数据,以便于使用的时候获取-->
<ul>
<li v-for="i in language">{{i}}</li>
</ul>
</slot>
</div>
</template>
在子组件的插槽使用双向绑定一个自定义属性data="language"
父组件使用时,要在外面包一层template标签,使用slot-scope="slot"属性。
slot就代表着子组件的作用域。
作用域插槽不能使用具名插槽??
ES6-Modules
模块化的两个核心
导出和导入。
export
注意要使用import和export的script标签要加上type="module"
export let name="Hello";//导出一个变量
let width = 100;
let height =120;
export {
width,height
}
//以对象形式导出一组变量
const Student = {
name:"xiaoming",
height:168,
weight:90
}
export {Student}//导出一个对象
export {Student as stu}//还可以给对象起别名
export function run(){
console.log("Run run run....");
}
//导出一个函数
export default function(){
console.log(123)
}
//默认导出,不需要给名字,让接收者命名。且仅允许存在一个默认导出。
import
import {name,Student,run} from './export.js';
/*导入变量。函数,对象等(可一次导多个),都要用大括号把名字包裹住,名字要对应上传过来的变量名。*/
import fun from './export.js';
/*如果是default就不需要大括号,这里的名字可随便取。*/
import * as obj from './export.js';
/*把全部导出的东西存到obj对象里面。*/
webpack
何为webpack
从本质上来讲,webpack是一个js应用静态模块打包工具。
webpack安装
webpack依赖于node环境,node有各种各样的依赖包,为了可以管理大量的依赖包,会一起安装上npm管理工具,类似于Maven。(node packages manager)
下··
webpack起步
webpack配置
Vue CLI
CLI:command-Line Interface,翻译为命令行界面,俗称脚手架。
Vue CLI是一个官方发布的vue.js项目脚手架。
vue-cli可以快速创建Vue开发环境以及对应的webpack配置。
Vue CLI使用前提:node.js
cli2创建方式:
vue init webpack projectname
运行环境runtime-compiler和runtime-only
cli3创建方式:
vue create projectname
//命令行进行配置,选择router和vuex,不用手动配置
vue ui //或者通过图形界面进行配置,狭隘后还要手动引入包和配置信息,烦
Vue-Router
认识路由
vue-router基本使用
路由的初始化
(项目生成时已经完成)
使用路由
1、创建路由组件
2、导入组件,配置路由映射
3、在Vue实例中挂载创建的路由实例
用代码代替router-link
结果:
一些细节
{
routes: [
{
/*用于初始化时进入的路径,这里第一次进入时默认进入\home*/
path:'',
redirect:'/home'
}],
mode:"history", /*改为history模式,去除哈希值‘#’*/
linkActiveClass:'active' /*处于活跃状态下的class*/
}
<router-link>的其他属性:
router-link默认渲染成a标签,使用tag="button"可以渲染成button。
让router-link使用replaceState模式(不可返回),使用replace属性。
标签活动时(被点击等等)会自动生成两个class,其中一个是router-link-active,可通过这个class给标签设置样式,如果觉得此class过长可以为此改名。active-class="active"
动态路由的使用
路由的懒加载
一个项目最后被打包的时候最终是放在一个js文件中,全部页面都放在一个js必然会很大,但我门第一次请求这个页面时可能需要花费一定的时间,甚至用户界面还会出现短暂的空白。如要避免这种情况,使用懒加载把:不同的路由对应的组件分割成不同的代码块,然后当路由被将访问时才加载对应组件,这样就更加高效了。
<img src="C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20200729095516035.png" alt="image-20200729095516035" style="zoom:67%;" />
使用懒加载:当用户使用组件时再import。
vue-router嵌套路由
实现路由嵌套有两个步骤:
1、创建对应子组件,并在路由映射中配置对应的子路由。路径不需要加 /
2、组件内部使用router-view标签
vue-router参数传递
当进行路由跳转时,通常需要传递参数,传递参数有两种方式:
$route.params.value
传递一个参数时使用params
配置路由格式(动态):
/router/:id
传递方式:在path后面跟上对应的值
传递后形成路径:
/router/123
,/router/asd
$route.query.value
传递大量参数时使用query
配置路由格式:/router,普通配置
传递方式:双向绑定路由to,绑定的值是个对象,包含url属性和query属性,query包含需要传递的参数。
传递后形成路径:
/router?id=123
,/router?name=asd
通过
$route.query.value
获取传过来的属性
用button实现query传参
<button @click="toProfile">档案</button>
<script>
toProfile(){
this.$router.push(//使用query时push传递一个对象
{
path:'/profile',
query:{ //query是一个对象
name:"Goku",
height:180,
age:18
}
})
}
</script>
1、父组件主页面设置事件
2、事件函数使用this.$route.push({}),对象有url和query属性,query里面即为传递过去的参数。
3、子组件中的computed中使用this.$route.query.value获取到值
4、页面上使用计算属性显示值
router
this.$router 是个路由导航对象,用它可以方便的使用JS代码实现编程式路由导航,如页面前进、后退、跳转等。
this.$route 是路由参数对象,路由中的所有参数, params、query 都属于它。
this.$router 用来发送。
this.$route用于接收信息。
vue-router导航守卫
1、全局导航钩子
分为前置守卫(beforeEach)+ 后置钩子(afterEach)
beforeEach:在在路由跳转前触发,参数包括to,from,next(参数会单独介绍)三个,这个钩子作用主要是用于登录验证,也就是路由还没跳转提前告知,以免跳转了再通知就为时已晚。
router.beforeEach((to,from,next)=>{
document.title = to.matched[0].name;
next();
})
afterEach和beforeEach相反,他是在路由跳转完成后触发,参数包括to,from没有了next。
单独路由独享钩子
组件内的钩子
keep-alive
?????????
默认情况下,一旦显示了另一个组件,上一个被覆盖的组件就会被销毁,下次再显示时再创建组件。使用keep-alive
标签后组件不会频繁地被创建和销毁。
属性:
exclude + name1,name2... 把此组件排除在外,它们会被创建和消除。
include + name1,name2... 包括这些组件,他们不会被创建和消除。
Vuex
Vuex简单介绍
Vuex是一个专为Vue.js应用开发的状态管理模式,Vuex是一个状态管理工具。
它采用集中式储存管理应用的所有组件的状态,并以相应规则保证状态可预测的方式发生变化。简单来说就是把多个组件共享的数据储存在一个对象里面,然后把这个对象放在Vue实例中让其他组件可以共同使用。Vuex还实现了响应式,多个组件间公用一个状态。
什么时候需要共享一个状态?
- 用户登录状态,用户名称,头像等
- 商品的收藏
- 购物车的商品
单页面状态管理
state改变引起actions改变,用户事件(在view上)可以引起状态改变。
多页面状态管理
使用VueX
vuex-devtools 和 mutations
vuex-devtools时一个浏览器插件,方便调试vue程序。
mutations是vuex中作为修改状态的东西,下面会详细介绍。
Vuex的核心概念
state
用于存放状态信息。
单一状态树:也叫单一数据源。即只用一个state。
Vuex可实现响应式数据,但是要遵循一些条件:
- 提前在store中初始化所需的数据
- 给state对象添加新属性是使用以下方式
- Vue.set(obj,"proper","value")
- 用新对象给旧对象赋值
任何页面都可以使用$store访问store里面的属性。
getters
相当于计算属性 ,当需要使用经过变化的state数据时使用。
区别:里面的函数有两个默认的形参,第一个是state,第二个是getters,不接受其他的参数。
不接受其他函数,如果需要传参数,需要在里面return一个函数。
getters:{
fun(state){
return function (age) {
return state.students.filter(s=>s.age > age)//返回年龄大于参数age的学生 对象
}
}//下图使用
}
使用的时候是$store.getters.fun
mutations
mutations,突变,转变,改变
state唯一的更新方式时通过mutations。
mutations必须是同步方法,因为devtools可帮我们捕捉mutation的快照,如果是异步方法devtools无法捕捉。
mutations可分成两部分:
- type事件类型
- handler回调函数,该回调函数的第一个参数是state
传参:(参数也可以是对象)
1、绑定事件,在事件函数里面使用this.$store.commit('type',value);这种方法只能发一个参数。
2、type是store里面mutations里面的函数名3、mutations对应上的函数第一个参数是state(固定),第二个可以自定义形参用于接收数据
4、在mutations里面操作state数据。
另一种提交风格
mutations的类型常量
action
在vuex中想要进行异步操作,可以用action来取代mutations。action类似于mutation,只是它主要用于进行异步请求(网络请求)。
ps.初学阶段好像在mutation上异步也没啥影响。。。所以action...暂时没啥作用....
module
当项目越来越大的时候,state显得越来越臃肿,但是又提倡使用单一状态树,所以使用module解决。
分模块。
modules:{
a:{
state:{},
mutations:{},
actions:{},
getters:{}
},
b:{
state:{},
mutations:{},
actions:{},
getters:{}
}
}
???