1、入门案例
1.1 电影列表
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>vue_02</title>
</head>
<body>
<div id="app"></div>
<template id="my-app">
<h2>Hello Vue3</h2>
<h3>666</h3>
<h3>{{msg}}</h3>
<div>{{person.name}}</div>
<div>{{person.age}}</div>
<hr>
<h2>电影列表</h2>
<ul>
<li v-for="movie in movies">{{movie}}</li>
</ul>
</template>
<script src="https://unpkg.com/vue@next"></script>
<script>
const app = Vue.createApp({
template: '#my-app',
data() {
return {
msg: '777',
person: {
name: 'zhangsan',
age: 18
},
movies: ['大话西游', '奥特曼', '大闹天空']
};
},
})
app.mount('#app')
</script>
</body>
</html>
1.2 计数器
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<template id="my-app">
当前计数器:
<button @click="des">-</button>
<span> {{counter}} </span>
<button @click="incr">+</button>
</template>
<script src="./lib/vue.global.js"></script>
<script>
const app = Vue.createApp({
template: '#my-app',
data() {
return {
counter: 100
};
},
methods: {
incr() {
this.counter++
},
des() {
this.counter--
}
}
})
app.mount('#app')
</script>
</body>
</html>
2、MVVM和Vue响应式原理
2.1 MVVM
-
View层:视图层
- 在我们前端开发中,通常就是DOM层,主要的作用是给用户展示各种信息。
-
Model层:数据层
- 数据可能是固定的数据,也可能是从网络上请求下来的数据。
-
VueModel层:视图模型层
- 视图模型层是View和Model沟通的桥梁。一方面它实现了Data Binding(数据绑定),将Model的改变实时的反应到View中(响应式系统),另一方面它实现了DOM Listener(DOM监听),当DOM发生一些事件(点击、滚动、touch等)时,可以监听到,并在需要的情况下改变对应的Data。
2.2 Vue响应式原理
什么是响应式?
- 当数据改变时,引用数据的函数会自动重新执行
响应式是一个过程,这个过程存在两个参予者:一方是触发,另一方是响应,比如:我家有只小狗,当我朝小狗走过去时,小狗竟会对我摇尾巴,这里我就是触发者,小狗就是响应者,同样的,在数据响应式中的两个参与者
- 触发者:数据
- 响应者:引用数据的函数 (副作用函数)
当数据发生改变时,引用数据的函数 响应 数据的改变而重新执行
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script>
const obj = { name: '阿杰' }
function effect() {
document.querySelector('#app').innerHTML = obj.name
}
effect()
// 当数据改变的时候,effect如何自动执行?
// vue中使用proxy对数据进行拦截
// proxy就是obj的代理对象,当对proxy读取时,会自动执行get函数,赋值时,会自动执行set函数
const proxy = new Proxy(obj, {
get(target, key) {
// target: 代理对象 ,key读取的属性
console.log(`读取数据`);
return target[key]
},
set(target, key, value) {
console.log(`赋值`);
target[key] = value
effect()
return true
}
})
</script>
</body>
</html>
2.3 data与methods属性说明
data 属性
-
data属性是传入一个函数,并且该函数需要返回一个对象
-
data中返回的对象会加入到Vue的响应式系统中,之后对该对象的修改或者访问
都会被Vue的响应式系统所处理,更新对应视图 (Vue响应式原理)
methods属性
- methods属性是一个对象,通常我们会在这个对象中定义很多的方法:
- 这些方法可以被绑定到模板中;
- 在这些方法方法中,我们可以使用this关键字来直接访问到data中返回的对象的属性;
- methods中的函数不可以使用箭头函数
注意,不应该使用箭头函数来定义method函数(例如
plus:()->this.a++
)。理由是箭头函
数绑定了父级作用域的上下文,所以this将不会按照期望指向组件实例,this.a将是undefined。
3、模板语法
3.1 插值语法
- 插值表达式(Mustache )的作用是在View中获得Model中的内容,插值表达式不能写在HTML中,不能作为值的部分。
<div id="app"></div>
<template id="my-app">
<h2>{{firstname}} - {{lastname}}</h2>
<h2>function: {{getName()}}</h2>
<h2>{{msg.split(' ').reverse().join(' ')}}</h2>
<h2>{{counter>=60?'及格':'不及格'}}</h2>
<h2>数组取值:{{arr[2]}}</h2>
<h2>对象取值:{{ obj.age }}</h2>
</template>
<script src="./lib/vue.global.js"></script>
<script>
const app = Vue.createApp({
template: '#my-app',
data() {
return {
lastname: "san",
firstname: "zhang",
counter: 80,
msg: 'i am a student',
arr: [1, 2, 3, 4],
obj: { "name": "xiaoyu", "age": 20 }
};
},
methods: {
getName() {
return this.firstname + this.lastname;
}
},
})
app.mount('#app')
</script>
3.2 v-once指令
指明此元素的数据只获取一次,之后数据内容的修改不影响此元素。
<p v-once>{{title}}</p>
3.3 v-text 和 v-html
- v-text: 纯文本输出内容
- v-html :就好比是innerHTML
<p v-text="finishedlink"></p>
<p v-html="finishedlink"></p>
data:{
title:"hello world!",
link:"http://www.baidu.com",
finishedlink:"<a href='http://www.baidu.com'>百度</a>"
},
3.4 v-pre
- V-pre用于跳过元素和它的子元素的编译过程,显示原始的Mustache标签
- 跳过不需要编译的节点,加快编译的速度
<h2 v-pre>{{msg}}</h2>
3.5 v-cloak(了解)
-
这个指令保持在元素上直到关联组件实例结束编译
-
需要和 CSS 规则 [v-cloak] { display: none } 一起使用,这个指令可以隐藏未编译的 Mustache 标签直到组件实例准备完毕
3.6 v-bind 属性绑定⭐
- v-bind用于绑定一个或多个属性值,或者向另一个组件传递props值
- 简写:
:
在开发中,有哪些属性需要动态进行绑定呢?比如图片的链接src、网站的链接href、动态绑定一些样式等等
案例:动态绑定网站的链接href,动态改变图片src
① 绑定基本属性
<body>
<div id="app"></div>
<template id="my-app">
<a v-bind:href="link">{{link}}</a>
<button @click="changeLink">changeLink</button>
<img :src="imgUrl" height="50" height="50">
<button @click="changeImg1">第一张图</button>
<button @click="changeImg2">第二张图</button>
</template>
<script src="./lib/vue.global.js"></script>
<script>
const app = Vue.createApp({
template: '#my-app',
data() {
return {
link: 'www.jd.com',
imgUrl: './img/1.jpg'
};
},
methods: {
changeLink() {
this.link = 'www.baidu.com'
},
changeImg1() {
this.imgUrl = './img/1.jpg'
},
changeImg2() {
this.imgUrl = './img/2.jpg'
}
},
})
app.mount('#app')
</script>
</body>
② 绑定class
对象语法
可以根据属性值true或false决定是否绑定
案例:根据isActive变量的值动态决定是否加入active的class
<body>
<div id="app"></div>
<template id="my-app">
<h2 :class="{ggg:isActive}">{{msg}}</h2>
<button @click="isActive=!isActive">切换</button>
</template>
<script src="./lib/vue.global.js"></script>
<script>
const app = Vue.createApp({
template: '#my-app',
data() {
return {
msg: 'hello,msg!',
isActive: true
};
},
methods: {
},
})
app.mount('#app')
</script>
</body>
数组语法
我们可以把一个数组传给 :class,以应用一个 class 列表
<template id="my-app">
<!-- 字符串 -->
<h2 :class="['aaa','bbb']">{{msg}}</h2>
<!-- 变量 -->
<h2 :class="['aaa','bbb',ccc]">{{msg}}</h2>
<!-- 三元运算符 -->
<h2 :class="['aaa',score < 60 ? 'red':'']">{{score}}</h2>
<!-- 对象 -->
<h2 :class="['aaa',{red: score < 60}]">{{score}}</h2>
</template>
③ 绑定style
<body>
<div id="app"></div>
<template id="my-app">
<!-- 注意:下划线改驼峰 -->
<h2 :style="{color:'red',fontSize:'55px',backgroundColor:'yellow'}">{{msg}}</h2>
<!-- 变量 -->
<h2 :style="obj">{{msg}}</h2>
<h2 :style="{color:'red',fontSize: size+'px',backgroundColor:'yellow'}">{{msg}}</h2>
<button @click="size++">变大</button>
</template>
<script src="./lib/vue.global.js"></script>
<script>
const app = Vue.createApp({
template: '#my-app',
data() {
return {
msg: 'hello,msg!',
obj: { color: 'red', 'font-size': '55px', 'background-color': 'blue' },
size: 65
};
},
methods: {
},
})
app.mount('#app')
</script>
</body>
绑定一个对象
如果我们希望将一个对象的所有属性,绑定到元素上的所有属性,应该怎么做呢
<body>
<div id="app"></div>
<template id="my-app">
<!-- 动态绑定属性名和属性值 -->
<div :[stuid]="stuname" aaa="giu">{{ msg }}</div>
<button @click="changeAttr">修改属性</button>
<h2 v-bind="info"></h2>
</template>
<script src="./lib/vue.global.js"></script>
<script>
const app = Vue.createApp({
template: '#my-app',
data() {
return {
msg: 'hello,msg!',
stuid: "S2002666",
stuname: '张三',
info:{
name:'zisi',
age:18
}
};
},
methods: {
},
})
app.mount('#app')
</script>
</body>
3.7 v-on 事件处理
-
v-on:click
可以写成**@click
**,是它的语法糖写法 -
一个事件,可以绑定多个方法。绑定一个方法时,()可以省略。绑定多个方法时,方法要加**()**
给事件绑定的方法传参写法
事件对象
v-on修饰符
-
.stop
- 阻止事件冒泡 (相当于调用 event.stopPropagation() ) -
.prevent
- 阻止事件默认行为(相当于调用 event.preventDefault() ) -
.once
- 只触发一次回调 -
键盘事件
- 当事件是从特定按键触发时才触发回调 (绑定键盘事件,例如@keyup),Vue 为一些常用的按键提供了别名.enter 、.tab 、.delete (捕获“Delete”和“Backspace”两个按键) 、.esc 、.space 、.up 、.down 、.left 、.right 等等
<body>
<div id="app"></div>
<template id="my-app">
<div class="father" @click="father">
<!-- @click.stop 阻止事件冒泡 -->
<div class="son" @click.stop="son"></div>
</div>
<!-- @click.prevent 阻止事件默认行为 -->
<a href="http://www.jd.com" @click.prevent="go">go to jd</a>
<h2>号码:{{phone}}</h2>
<!-- 键盘松开就会触发 -->
<input type="text" @keyup="changePhone">
<!-- 按下回车才会触发事件 -->
<input type="text" @keyup.enter="changePhone">
</template>
<script src="./lib/vue.global.js"></script>
<script>
const app = Vue.createApp({
template: '#my-app',
data() {
return {
inputValue: "",
phone: 1888888888
};
},
methods: {
father() {
alert("i am father!")
},
son() {
alert("i am son!")
},
changePhone(e) {
this.phone = e.target.value
},
go() {
alert('哈哈哈,你被阻止了')
}
},
})
app.mount('#app')
</script>
</body>
3.8 v-if 和 v-show 条件渲染
① v-if
-
当条件为false时,其判断的内容完全不会被渲染或者会被销毁掉
-
当条件为true时,才会真正渲染条件块中的内容
② v-show
③ v-if 和 v-show区别
在用法上的区别:
-
v-show 是不支持template;
-
v-show 不可以和v-else一起使用
本质的区别:
-
v-show元素无论是否需要显示到浏览器上,它的DOM实际都是有存在的,只是通过CSS的display属性来进行切换;
-
v-if 当条件为false时,DOM是不存在的
开发中如何进行选择呢?
- 如果我们的原生需要在显示和隐藏之间频繁的切换,那么使用 v-show
- 如果不会频繁的发生切换,那么使用 v-if
3.9 v-for 列表渲染
-
v-for的基本格式是
item in 数组
,数组通常是来自 data 或者 props。item是我们给每项元素起的一个别名,这个别名可以自定来定义 -
在遍历一个数组的时候,如果需要拿到数组的索引,可以使用格式:
(item, index) in 数组
,注意上面的顺序:数组元素项item是在前面的,索引项index是在后面的
<template id="my-app">
<h2>电影列表</h2>
<ul>
<li v-for="movie in movies">{{index+1}} -- {{movie}}</li>
</ul>
</template>
<template id="my-app">
<h2>电影列表</h2>
<ul>
<li v-for="(movie,index) in movies">{{index+1}}、{{movie}}</li>
</ul>
</template>
- v-for也支持遍历 对象 ,并且支持有一二三个参数
- 一个参数: “value in object”;
- 二个参数: “(value, key) in object”;
- 三个参数: “(value, key, index) in object”;
<template id="my-app">
<h2>person</h2>
<ul>
<li v-for="(item,key,index) in person">{{index+1}} -- {{key}} -- {{item}}</li>
</ul>
</template>
<script>
const app = Vue.createApp({
template: '#my-app',
data() {
return {
person:{
name:'zhangsan',
age:18,
height:188
}
};
},
})
app.mount('#app')
</script>
补充:数组更新检测
变更方法
Vue 将被侦听的数组的变更方法进行了包裹,所以它们也将会触发视图更新
<script>
const app = Vue.createApp({
template: '#my-app',
data() {
return {
arr: [6, 8, 5, 1,9]
};
},
methods: {
changeArr() {
// this.arr.push(66,77,88)
// 从数组最后删除一个元素
// this.arr.pop()
// 从数组最前面删除一个元素
// this.arr.shift()
// 数组头添加元素
// this.arr.unshift(1)
// 指定删除, splice(索引,个数); 新增:splice(索引,个数,新增)
// this.arr.splice(1, 1,66,77)
// this.arr.sort((a, b) => a - b)
this.arr.reverse()
}
},
})
app.mount('#app')
</script>
不变更方法
3.10 v-model – 数据双向绑定⭐⭐
<body>
<div id="app"></div>
<template id="my-app">
<h2>{{msg}}</h2>
<input type="text" v-model="msg">
</template>
<script src="./lib/vue.global.js"></script>
<script>
const app = Vue.createApp({
template: '#my-app',
data() {
return {
msg: 'hello,msg!'
};
},
})
app.mount('#app')
</script>
</body>
原理
<body>
<div id="app"></div>
<template id="my-app">
<h2>{{msg}}</h2>
<input type="text" :value="msg" @input="msg=$event.target.value">
</template>
<script src="./lib/vue.global.js"></script>
<script>
const app = Vue.createApp({
template: '#my-app',
data() {
return {
msg: 'hello,msg!'
};
},
})
app.mount('#app')
</script>
</body>
diff算法
4、计算属性和监听属性
4.1、计算属性—computed
什么是计算属性
计算属性的重点突出在 属性
两个字上(属性是名词),首先它是个 属性
其次这个属性有 计算
的能力(计算是动词),这里的 计算
就是个函数;简单点说,它就是一个能够将计算结果缓存起来的属性(将行为转化成了静态的属性),仅此而已;
4.2、监听属性 —watch
基础用法
immediate 立即执行
deep 深度监听
$watch API
this.$watch()
返回一个函数,调用这个函数就会停止监听
<body>
<div id="app"></div>
<template id="my-app">
<h2>{{info.name}}</h2>
<button @click="startListen">开始监听</button>
<button @click="stopListen">停止监听</button>
<button @click="info.name='lisi'">修改info</button>
</template>
<script src="./lib/vue.global.js"></script>
<script>
var unwatch = null;
const app = Vue.createApp({
template: '#my-app',
data() {
return {
msg: 'hello,msg!',
info: {
name: 'kobe',
age: 21,
height: 191
}
};
},
methods: {
startListen() {
console.log('开始监听。。。。');
unwatch = this.$watch('info', (newValue) => {
console.log(newValue);
}, { deep: true, immediate: false })
},
stopListen(){
console.log('停止监听。。。。');
unwatch()
}
},
})
app.mount('#app')
</script>
</body>
4.3 watch与computed的区别
- computed是计算属性,watch是监听一个值的变化而执行对应的回调
- computed函数所依赖的属性不变的时候会使用缓存;watch每次监听的值发生变化时候都会调用回调
- computed的函数内必须调用return;watch可以没有
- computed一般用在 当一个属性受多个属性影响的时候(例如:购物车总价格);watch用在 当一条数据影会响多条数据的时候(例如:搜索城市天气)
- computed函数不能有异步操作;watch可以
5、组件化开发🎯
vue.js 有两大法宝,一个是数据驱动,另一个就是组件化,那么问题来了,什么叫做组件化,为什么要组件化?接下来我就针对这两个问题一一解答,所谓组件化,就是把页面拆分成多个组件,每个组件依赖的 CSS、JS、模板、图片等资源放在一起开发和维护。 因为组件是资源独立的,所以组件在系统内部可复用,组件和组件之间可以嵌套,如果项目比较复杂,可以极大简化代码量,并且对后期的需求变更和维护也更加友好。
组件开发三要素:
prop
, 自定义事件 , slot
是组成组件的三个重要因素。
prop
用于定义组件的属性。- 自定义事件用于触发组件的事件。
slot
用于组件功能的扩展。
注意 : 一个组件的 data
选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝
5.1、组件注册
① 全局组件
Vue.component(tagName组件名, options)
进行全局注册,例如
Vue.component('my-component', {
// 选项
})
这些组件是全局注册的。也就是说它们在注册之后可以用在任何新创建的 Vue 根实例 (new Vue
) 的模板中。
② 局部组件
- 局部组件注册在某个vue对象中,
- 只有注册过该局部组件的vue对象才能使用这个局部组件
// 定义组件
var ComponentA = { /* ... */ }
var ComponentB = { /* ... */ }
// 使用的组件
new Vue({
el: '#app',
components: {
'component-a': ComponentA,
'component-b': ComponentB
}
})
注意局部注册的组件在其子组件中*不可用*。
区别:全局组件是挂载在
Vue.options.components
下,而局部组件是挂载在vm.$options.components
下,这也是全局注册的组件能被任意使用的原因。
5.2、组件间通信
在学习组件间通信前,先明白什么是父组件,什么是子组件。我们将某段代码封装成一个组件,而这个组件又在另一个组件中引入,而引入该封装的组件的文件叫做父组件,被引入的组件叫做子组件。
-
父组件传递给子组件:通过props属性,子组件自定义属性(props)
-
子组件传递给父组件:通过$emit触发事件
① 父传子 — props属性
什么是props
-
props是组件上注册的一些自定义属性(attribute);
-
父组件可以通过在子组件标签上给自定义属性(attribute)赋值,来达到传递信息给子组件
-
子组件可以直接取出这些属性对应的值
-
props有两种常见的用法:
方式一:字符串数组 :数组中的字符串就是自定义属性(attribute)的名称;
方式二:对象类型 :对象类型我们可以在指定attribute名称的同时,指定它需要传递的类型、是否是必须的、默认值等等;
可以绑定静态属性(写死的数据)和动态属性(数据可变)
父组件向子组件传递数据:
- 传递静态数据 ,在组件使用标签上声明静态数据
key=value
在子组件定义内部使用props声明接收数据 - 动态属性:
:key=""
进行绑定
ShowInfo.vue
子组件
<template>
<div>
<h2>{{title}}</h2>
<p>
{{message}}
</p>
</div>
</template>
<script>
export default {
data() {
return {};
},
// 自定义属性
props: ['title', 'message'],
};
</script>
<style scoped></style>
App.Vue
父组件中引用 ShowInfo.vue
子组件
<template>
<div>
<show-info :title="title" :message="message"></show-info>
</div>
</template>
<script>
import ShowInfo from './components/ShowInfo.vue'
export default {
data() {
return {
title:'二十大',
message:`提出到2035年我国发展的总体目标,指明未来五年全面建设社会主义现代化国家主要目标任务;`
};
},
components:{
ShowInfo
}
};
</script>
<style scoped></style>
单向数据流
所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外变更父级组件的状态,从而导致你的应用的数据流向难以理解。
额外的,每次父级组件发生变更时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。
② 子传父 — 事件传值$emit
- 在子组件标签上定义传递事件 ,如
@key=value
形式,@传递事件名=父组件传递事件名
- 在子组件中通过
this.$emit('事件传递名')
调用父组件事件 - 通过
this.$emit('事件传递名')
传递事件时,可以携带子组件中的data数据,并且父组件事件函数接收
案例1
Tabbar.vue
<template>
<div class="tabbar">
<template v-for="(item, index) in tabs" :key="index">
<div class="tab" @click="tabChange(index)">
<span :class="{ active: index === currentIndex }">{{ item }}</span>
</div>
</template>
<!-- <div class="tab"><span>平板</span></div>
<div class="tab"><span>手机</span></div> -->
</div>
</template>
<script>
export default {
props: ["tabs"],
emits: ["tabClick"],
data() {
return {
currentIndex: 0,
};
},
methods: {
tabChange(index) {
this.currentIndex = index;
this.$emit("tabClick", index);
},
},
};
</script>
<style scoped>
.tabbar {
width: 300px;
margin: 0 auto;
display: flex;
cursor: pointer;
text-align: center;
}
.tab {
flex: 1;
}
.active {
border-bottom: 5px solid red;
}
</style>
App.vue
<template>
<div class="app">
<Tabbar :tabs="tabs" @tab-click="tabChange"></Tabbar>
<h2>{{ info[currentIndex] }}</h2>
</div>
</template>
<script>
import Tabbar from "./components/Tabbar.vue";
export default {
data() {
return {
tabs: ["电脑", "手机", "平板"],
info: ["电脑页面", "手机页面", "平板页面"],
currentIndex: 0,
};
},
methods: {
tabChange(index) {
this.currentIndex = index;
},
},
components: {
Tabbar,
},
};
</script>
<style scoped>
.app {
width: 800px;
margin: 0 auto;
}
</style>
效果:点击切换Tabbar,并且下面也会随之改变
③ provide/inject
④ 兄弟组件通信
5.3、插槽
什么是插槽?
相当于一个占位符,用来扩展组件,使组件更加灵活
在 2.6.0 中,我们为具名插槽和作用域插槽引入了一个新的统一的语法 (即
v-slot
指令)。它取代了slot
和slot-scope
这两个目前已被废弃但未被移除且仍在文档中的 attribute。新语法的由来可查阅这份 RFC。
具名插槽
带有名字的插槽
默认插槽
在没有指定插槽name时,会替换slot里面内容
6、Vue生命周期钩子函数
七、Vue-CLI — Vue脚手架
Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统,提供:
- 通过
@vue/cli
实现的交互式的项目脚手架。- 通过
@vue/cli
+@vue/cli-service-global
实现的零配置原型开发。- 一个运行时依赖 (@vue/cli-service),该依赖:
- 可升级;
- 基于 webpack 构建,并带有合理的默认配置;
- 可以通过项目内的配置文件进行配置;
- 可以通过插件进行扩展。
- 一个丰富的官方插件集合,集成了前端生态中最好的工具。
- 一套完全图形化的创建和管理 Vue.js 项目的用户界面。
7.1、安装
注:Vue CLI 4.x 需要 Node.js v8.9 或更高版本 (推荐 v10 以上)。
npm install -g @vue/cli
# OR
yarn global add @vue/cli
7.2、创建一个项目
# 命令行输入
vue create hello-world(项目名称)
通过可视化页面创建项目:
# 命令行输入
vue ui
7.3、运行及打包
# 运行
npm run serve
默认端口:localhost:8080
# 打包
npm run build
打包好会生成一个dist文件夹,里面就是打包好的html css js 代码
九、VueX — 状态管理
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
如果您的应用够简单,您最好不要使用 Vuex。一个简单的 store 模式 (opens new window)就足够您所需了。但是,如果您需要构建一个中大型单页应用,您很可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择。
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
},
mutations: {
},
actions: {
},
modules: {
}
})
state:
💁♂️:同来定义一些组件共享数据
state: {
count: 0,
},
如何使用?
在任何组件都可以通过this.$store.state.count
或者$store.state.count
获取
Mutations
💁♂️:用来对共享数据状态修改的方法
在Mutations里面定义的方法,都有一个默认参数,默认参数会将状态对象传递给自定义方法
mutations: {
increCount(state) {
state.count ++
}
},
在组件中通过this.$store.commit("methodsName")
调用Mutations里的methodsName
方法
注意:
可以通过this.$store.commit
传递参数,但commit
只有两个参数,因此想要传递多个参数时,要将多个参数包装成一个对象,如何再传递
Getters
💁♂️:用来对共享数据计算的方法,相当于组件中computed
属性
使用:this.$store.getters.计算属性
Actions
Modules
参考文章:
评论区