Vue教程,从入门到精通
Vue是渐进式框架?
- 渐进式意味着你可以将Vue作为应用的一部分嵌入进去,带来丰富的交互体验;
- 如果你希望将更多业务逻辑使用Vue实现,能够使用Vue的核心库以及其生态系统;
- Core+Vue-router+Vuex,满足各种各样需求。
Vue特点\高级功能
- 解耦视图和数据;
- 可复用组件;
- 前端路由技术;
- 状态管理;
- 虚拟DOM
安装Vue
-
CDN引入
<!-- 开发环境版本,包含了有帮助的命令行警告 --> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <!-- 生产环境版本,优化了尺寸和速度 --> <script src="https://cdn.jsdelivr.net/npm/vue"></script>
-
下载和引用
<!-- 开发环境版本 --> https://vuejs.org/js/vue.js <!-- 生产环境版本 --> https://vuejs.org/js/vue.min.js
-
NPM
<!-- 最新稳定版 --> npm install vue
Hello Vue初体验
<body>
<div id="app">
{{ message }}
</div>
<script src="../../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
});
</script>
</body>
Vue列表展示
<body>
<div id="app">
<div>{{ message }}</div>
<ul>
<li v-for="(item, i) in movies" :key="i">{{ item }}</li>
</ul>
</div>
<script src="../../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
movies: ['星际穿越', '钢铁侠', '盗梦空间', '死侍']
}
});
</script>
</body>
计数器
<body>
<div id="app">
<h2>当前计数:{{ counter }}</h2>
<button @click="add">+</button>
<button @click="sub">-</button>
</div>
<script src="../../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
counter: 0
},
methods: {
add() {
this.counter++
},
sub() {
if(this.counter !== 0){
this.counter--
}else{
this.counter = 0
}
}
}
});
</script>
</body>
Vue MVVM
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dAIwrqlH-1614003939266)(C:\Users\10131\AppData\Roaming\Typora\typora-user-images\image-20210211110927286.png)]
Vue生命周期
Vue每个组件都是独立的,每个组件都有一个属于它的生命周期,从一个组件创建、数据初始化、挂载、更新、销毁,这就是一个组件所谓的生命周期。
Vue生命周期函数
插值操作
- {{}}
- v-html
- v-text
- v-pre
- v-cloak
<body>
<div id="app">
<h3>{{ message }}</h3>
<h3 v-once>{{ message }}</h3>
<h3 v-html="url"></h3>
<h3 v-text="message"></h3>
</div>
<script src="../../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '安娜',
url: '<a href="https://www.bilibili.com/">bilibili</a>'
}
});
</script>
</body>
v-bind
动态属性绑定
<body>
<div id="app">
<img :src="imgUrl" alt="">
</div>
<script src="../../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
imgUrl: 'https://i2.hdslb.com/bfs/face/c850c18ae6b507d0ef34837f53a51090b6a7451f.jpg@96w_96h_1c.webp'
}
});
</script>
</body>
<body>
<div id="app" v-cloak>
<!-- 对象语法 -->
<p :class="{active: isActive, line: isLine}">{{ message }}</p>
<button @click="turnActive">turn</button>
<hr color="black">
<!-- 数组语法 -->
<p :class="['active', 'line']">{{ message }}</p>
<p :class="getClasses()">{{ message }}</p>
</div>
<script src="../../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
isActive: true,
isLine: true,
message: 'fuck you',
active: 'aaa',
line: 'bbb'
},
methods: {
turnActive() {
this.isActive = !this.isActive
this.isLine = !this.isLine
},
getClasses() {
return [this.active, this.line]
}
}
});
</script>
</body>
v-bind和v-for结合
<!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">
<link rel="stylesheet" href="../../css/global.css">
<title>Document</title>
<style>
.fontcolor {
color: red;
font-weight: bold;
font-size: 30px;
}
</style>
</head>
<body>
<div id="app">
<ul>
<li v-for="(item, i) in movies" :key="i" :class="{fontcolor: index === i}" @click="changeStyle(i)">{{ item }}</li>
</ul>
</div>
<script src="../../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
movies: ['海王', '进击的巨人', '火影忍者', '守望先锋'],
index: -1
},
methods: {
changeStyle(i) {
this.index = i
}
}
});
</script>
</body>
</html>
计算属性
<body>
<div id="app">
<h2>总价格:{{ totalPrice }}</h2>
</div>
<script src="../../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
overwatch: [
{ id: 1, name: 'genji', price: 110 },
{ id: 2, name: 'ana', price: 112 },
{ id: 3, name: 'mercy', price: 113 },
{ id: 4, name: 'doomfist ', price: 114 },
{ id: 5, name: 'mccree ', price: 115 },
{ id: 6, name: 'reaper', price: 116 },
{ id: 7, name: 'tracer', price: 117 }
]
},
computed: {
totalPrice() {
let result = 0
// for(let i in this.overwatch){
// this.overwatch[i].price
// }
// for(let ow of this.overwatch){
// ow.price
// }
for(let i = 0; i < this.overwatch.length; i++) {
result += this.overwatch[i].price
}
return result
}
}
});
</script>
</body>
计算属性的setter/getter
<body>
<div id="app">
<p>{{ fullName }}</p>
</div>
<script src="../../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
firstName: 'genji',
lastName: 'ana'
},
methods: {
},
// 属性一般没有set方法,只读属性
computed: {
fullName: {
set(newValue) {
const name = newValue.split(' ')
this.firstName = name[0]
this.lastName = name[1]
},
get() {
return this.firstName + ' ' + this.lastName
}
}
}
});
</script>
</body>
let/var/const
var | let | const |
---|---|---|
函数作用域 | 块级作用域 | 块级作用域 |
变量提升 | 不存在变量提升 | 不存在变量提升 |
值可更改 | 值可更改 | 值不可更改 |
v-on修饰符
<body>
<div id="app">
<!-- stop 阻止冒泡 -->
<div @click="divClick">
<button @click.stop="btnClick">按钮</button>
</div>
<!-- prevent 阻止默认事件 -->
<form action="baidu">
<input type="submit" value="提交" @click.prevent="submitClick">
</form>
<input type="text" @keyup.enter="keyUp">
<!-- once 仅点击一次 -->
<button @click.once="btnsClick()">按钮</button>
<!-- native 监听组件根元素的原生事件 -->
</div>
<script src="../../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
methods: {
btnClick() {
console.log('btnClick');
},
divClick() {
console.log('divClick');
},
submitClick() {
console.log('submitClick');
},
keyUp() {
console.log('keyUp');
},
btnsClick() {
console.log("btnsClick");
}
}
});
</script>
</body>
v-if/v-else-if/v-else
<body>
<div id="app">
<h2 v-if="isShow">{{ message }}</h2>
<button @click="isShow = !isShow">点击</button>
</div>
<script src="../../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好',
isShow: false
}
});
</script>
</body>
登录切换案例
<body>
<!-- key解决组件复用 -->
<!-- v-if: 当条件为false时,包含v-if指令的元素,根部不存在DOM中(操作DOM),v-show则是存在DOM中,仅隐藏(操作样式),切换频率高,使用v-show,反之v-if -->
<div id="app">
<span v-if="isUser">
<label for="username">用户账号</label>
<input type="text" id="username" placeholder="用户账号" key="username">
</span>
<span v-else>
<label for="username">用户邮箱</label>
<input type="text" id="useremial" placeholder="用户邮箱" key="useremial">
</span>
<button @click="isUser = !isUser">切换类型</button>
</div>
<script src="../../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
isUser: true
}
});
</script>
</body>
v-for
<body>
<div id="app">
<!-- 获取对象 -->
<ul>
<li v-for="item in info">{{ item }}</li>
</ul>
<!-- 获取key和value -->
<ul>
<li v-for="(value, key) in info">{{ value }} -- {{ key }}</li>
</ul>
<!-- 获取key、value和index -->
<ul>
<li v-for="(value, key, index) in info">{{ value }} -- {{ key }} -- {{ index }}</li>
</ul>
</div>
<script src="../../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
info: {
name: 'genji',
age: '18',
height: 1.6
}
}
});
</script>
</body>
v-model双向数据绑定/实现原理
<body>
<div id="app">
<input type="text" v-model="message">
<h2>{{ message }}</h2>
<!-- v-model实现原理 v-bind + v-on -->
<input type="text" :value="message" @input="valueChange">
<h2>{{ message }}</h2>
</div>
<script src="../../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好'
},
methods: {
valueChange(event) {
this.message = event.target.value
}
}
});
</script>
</body>
v-model结合radio
<body>
<div id="app">
<label for="male">
<input type="radio" id="male" value="男" v-model="sex">男
</label>
<label for="female">
<input type="radio" id="female" value="女" v-model="sex">女
</label>
<h2>您的性别是:{{sex}}</h2>
</div>
<script src="../../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
sex: '男'
}
});
</script>
</body>
v-model结合checkbox
<body>
<div id="app">
<!-- checkbox单选框 -->
<label for="agree">
<input type="checkbox" id="agree" v-model="isAgree">同意协议
</label>
<h2>您选择的是:{{isAgree}}</h2>
<button :disabled="!isAgree">下一步</button>
<br>
<!-- checkbox多选框 -->
<label for="hero">
<input type="checkbox" value="ana" v-model="heroes">ana
<input type="checkbox" value="hanzo" v-model="heroes">hanzo
<input type="checkbox" value="mercy" v-model="heroes">mercy
<input type="checkbox" value="genji" v-model="heroes">genji
</label>
<h2>您选择的是:{{heroes.join(' ')}}</h2>
</div>
<script src="../../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
isAgree: false,
heroes: []
}
});
</script>
</body>
v-model结合select
<body>
<div id="app">
<!-- 选择一个 -->
<select name="abcd" id="" v-model="abcd">
<option value="a">a</option>
<option value="b">b</option>
<option value="c">c</option>
<option value="d">d</option>
</select>
<h2>您选择的是:{{abcd}}</h2>
<br>
<!-- 选择多个 -->
<select name="abcds" id="" v-model="abcds" multiple>
<option value="a">a</option>
<option value="b">b</option>
<option value="c">c</option>
<option value="d">d</option>
</select>
<h2>您选择的是:{{abcds.join(' ')}}</h2>
</div>
<script src="../../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
abcd: 'b',
abcds: []
}
});
</script>
</body>
v-model修饰符
<body>
<div id="app">
<!-- 1. lazy -->
<input type="text" v-model.lazy="message">
<h2>{{message}}</h2>
<!-- 2. number -->
<input type="text" v-model.number="age">
<h2>{{age}}---{{typeof age}}</h2>
<!-- 3. trim -->
<input type="text" v-model.trim="name">
<h2>{{name}}---{{typeof name}}</h2>
</div>
<script src="../../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: 'hello',
age: 0,
name: ''
}
});
</script>
</body>
组件化开发
- 开发出一个个独立可复用的小组件来构造应用;
- 任何应用都能被抽象成一个组件树。
组件化基本使用
<body>
<div id="app">
<my-cpn></my-cpn>
</div>
<script src="../../js/vue.js"></script>
<script>
// 1.创建组件构造器对象
const cpnC = Vue.extend({
template:`
<div>
<h2>ana</h2>
<p>overwatch</p>
<p>overwatch</p>
<p>overwatch</p>
</div>`
})
// 2.注册组件(全局组件)
Vue.component('my-cpn', cpnC)
const app = new Vue({
el: '#app',
// 局部注册
components: {
cpn: cpnC
}
});
</script>
</body>
父组件/子组件
<body>
<div id="app">
<my-ow>
<cpn></cpn>
</my-ow>
</div>
<script src="../../js/vue.js"></script>
<script>
// 1.创建组件构造器对象
const cpnC = Vue.extend({
template:`
<div>
<h2>ana</h2>
<p>overwatch</p>
<p>overwatch</p>
<p>overwatch</p>
</div>`
})
// 创建第二个组件
const ow = Vue.extend({
template: `
<div>
<h2>守望先锋</h2>
<p>斯巴拉西</p>
<cpn></cpn>
</div>
`,
components: {
cpn: cpnC
}
})
// 2.注册组件
Vue.component('my-ow', ow)
const app = new Vue({
el: '#app'
});
</script>
</body>
注册组件语法糖
<body>
<div id="app">
<my-cpn></my-cpn>
</div>
<script src="../../js/vue.js"></script>
<script>
// 1.创建组件构造器对象
// const cpnC = Vue.extend()
// 2.注册组件
Vue.component('my-cpn',
{
template:`
<div>
<h2>ana</h2>
<p>overwatch</p>
<p>overwatch</p>
<p>overwatch</p>
</div>`
})
const app = new Vue({
el: '#app'
});
</script>
</body>
组件模板抽离
<body>
<div id="app">
<my-ow></my-ow>
</div>
<script src="../../js/vue.js"></script>
<!-- <script type="text/x-template" id="ow">
<div>
<h2>overwatch</h2>
<p>斯巴拉西</p>
</div>
</script> -->
<template id="ow">
<div>
<h2>overwatch</h2>
<p>斯巴拉西</p>
</div>
</template>
<script>
// 1.创建组件构造器对象
// const cpnC = Vue.extend()
// 2.注册组件
Vue.component('my-ow', { template: '#ow'})
const app = new Vue({
el: '#app'
});
</script>
</body>
组件数据的存放
- 组件对象也有一个data属性,以及methods等属性;
- data属性必须是一个函数;
- 函数返回一个对象,对象内部保存着数据。
父传子props
<body>
<div id="app">
<cpn :c-info="info" :child-my-message="message"></cpn>
</div>
<script src="../../js/vue.js"></script>
<template id="cpn">
<div>
<h2>{{cInfo}}</h2>
<h2>{{childMyMessage}}</h2>
</div>
</template>
<script>
const cpn = {
template: '#cpn',
props: {
cInfo: {
type: Object,
default() {
return {}
}
},
childMyMessage: {
type: String,
default() {
return {}
}
}
}
}
const app = new Vue({
el: '#app',
data: {
info: {
name: 'tkx',
age: 22,
height: 1.73
},
message: 'aaaa'
},
components: {
cpn
}
});
</script>
</body>
子传父(事件传值)
<body>
<div id="app">
<cpn @item-click="cpnClick"></cpn>
</div>
<template id="cpn">
<div>
<button v-for="item in categories" :key="item.id" @click="btnClick(item)">{{item.name}}</button>
</div>
</template>
<script src="../../js/vue.js"></script>
<script>
const cpn = {
template: '#cpn',
data() {
return {
categories: [
{ id: '1', name: 'lizeyan' },
{ id: '2', name: 'hanzo' },
{ id: '3', name: 'genji' },
{ id: '4', name: 'mercy' }
]
}
},
methods: {
btnClick(item) {
// 发射 自定义事件
this.$emit('item-click', item)
}
}
}
const app = new Vue({
el: '#app',
methods: {
cpnClick(item) {
console.log(item);
}
},
components: {
cpn
}
});
</script>
</body>
父访问子(children/refs)
<body>
<div id="app">
<cpn></cpn>
<cpn></cpn>
<cpn ref="aaa"></cpn>
<button @click="btnClick">按钮</button>
</div>
<template id="cpn">
<div>
<h2>我是子组件</h2>
</div>
</template>
<script src="../../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好'
},
methods: {
btnClick() {
console.log(this.$children);
this.$children[0].showMessage()
// $refs => 对象类型,默认是一个空对象 ref='***'
console.log(this.$refs.aaa);
}
},
computed: {
},
components: {
cpn: {
template: '#cpn',
methods: {
showMessage() {
console.log('showmessage');
}
}
}
}
});
</script>
</body>
子访问父(parent/root)
<body>
<div id="app">
<cpn></cpn>
</div>
<template id="cpn">
<div>
<h2>我是子组件</h2>
<button @click="btnClick">按钮</button>
</div>
</template>
<script src="../../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好'
},
components: {
cpn: {
template: '#cpn',
methods: {
btnClick() {
console.log(this.$parent);
console.log(this.$root);
}
}
}
}
});
</script>
</body>
插槽slot
<!-- 基本使用 -->
<body>
<div id="app">
<cpn><button>我是button元素</button></cpn>
</div>
<template id="cpn">
<div>
<div>我是div元素</div>
<slot>我是slot元素</slot>
<h2>我是h2元素</h2>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
const cpn = Vue.extend({
template: '#cpn',
})
const app = new Vue({
el: '#app',
components: {
cpn
}
});
</script>
</body>
<!-- 具名插槽 -->
<body>
<div id="app">
<cpn>
<div slot="center">
<h2>中间被替换</h2>
</div>
</cpn>
</div>
<template id="cpn">
<div>
<slot name="left">我是左边</slot>
<slot name="center">我是中间</slot>
<slot name="right">我是右边</slot>
</div>
</template>
<script src="../../js/vue.js"></script>
<script>
const cpn = Vue.extend({
template: '#cpn'
})
const app = new Vue({
el: '#app',
components: {
cpn
}
});
</script>
</body>
作用域插槽
<div id="app">
<cpn v-show="isShow"><template slot-scope="scope"></template></cpn>
</div>
CommonJS
// 模块化两个核心:导入和导出
// CommonJS导出
module.exports = {
flag: true,
test(a, b) {
return a + b
},
demo(a, b) {
return a * b
}
}
//CommonJS导入
let { test, demo, flag } = require('moduleA');
// 等同于
let _mA = require('moduleA');
let test = _mA.test;
let demo = _mA.demo;
let flag = _mA.flag;
webpack安装
-
安装node.js
-
全局安装webpack
npm install webpack@3.6.0 -g npm install webpack@3.6.0 --save-dev
-
打包js文件
webpack ./src/main.js ./dist/bundle.js
配置
// webpack.config.js
const path = require('path')
module.export = {
entry: path.resolve(__dirname, 'dist'),
output: {
// 绝对路径 动态获取
path: '',
filename: 'bundle.js'
}
}
//package.json
npm init
"build": "webpack"
npm run build
loader安装
-
npm install --save-dev css-loader,;
-
webpack.config.js配置
module: { rules: [ { test: /\.css$/, use: ['style-loader', 'css-loader'] } ] }
webpack-less文件处理
-
npm install --save-dev less-loader less;
-
webpack.config.js配置
module: { rules: [{ test: /\.less$/, loader: 'less-loader' // 将 Less 编译为 CSS }] }
webpack图片文件处理
-
npm install url-loader --save-dev、npm install file-loader --save-dev
-
webpack.config.js配置
module: { rules: [{ test: /\.(png|jpg|gif)$/i, use: [{ loader: 'url-loader', options: { limit: 8192 } }] }] }
babel配置
npm install -D babel-loader @babel/core @babel/preset-env
// webpack.config.js配置
module: {
rules: [
{
test: /\.m?js$/,
// exclude: 排除
// include: 包含
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
}
]
}
webpack使用vue配置
npm install vue --save
npm install vue-loader vue-template-compiler --save-dev
// 1. runtime-only -> 代码中,不可以有任何的template 2. runtime-compiler -> 代码中,可以有template,因为有compiler可以用于编译template
// webpack.config.js配置
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
}
Vue脚手架
初始化项目
// 2.0
vue init webpack my-project
// 3.0
vue create my-project
vue-router
-
基本使用
-
嵌套路由
-
参数传递
params的类型: 配置路由格式: /router/:id 传递的方式: 在path后面跟上对应的值 传递后形成的路径: /router/123, /router/abc this.$router.push('/user/' + this.userId) query的类型: 配置路由格式: /router, 也就是普通配置 传递的方式: 对象中使用query的key作为传递方式 传递后形成的路径: /router?id=123, /router?id=abc this.$router.push({path: '/user', query: { name: 'lizeyan', age: 22, height: 1.73 }})
-
导航守卫
// 挂载路由导航守卫 router.beforeEach((to, from, next) => { // to: 将要访问的路径 // from: 代表从哪个路径跳转而来 // next: 是一个函数,表示放行 // next() 放行 next('/login') 强制跳转 if (to.path === '/login') return next() // 获取token const tokenStr = window.sessionStorage.getItem('token') if (!tokenStr) return next('/login') next() })
-
keep-alive
keep-alive 是 Vue 内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染,它们有两个非常重要的属性:
-
include - 字符串或正则表达,只有匹配的组件会被缓存;
-
exclude - 字符串或正则表达式,任何匹配的组件都不会被缓存;
-
router-view 也是一个组件,如果直接被包在 keep-alive 里面,所有路径匹配到的视图组件都会被缓存
<keep-alive exclude="Profile,User"> <router-view> <!-- 所有路径匹配到的视图组件都会被缓存 --!> </router-view> </keep-alive>
-
-
懒加载
// 方式一: 结合Vue的异步组件和Webpack的代码分析 const Home = resolve => { require.ensure(['../components/Home.vue'], () => { resolve(require('../components/Home.vue')) })}; // 方式二: AMD写法 const About = resolve => require(['../components/About.vue'], resolve); // 方式三: 在ES6中, 我们可以有更加简单的写法来组织Vue异步组件和Webpack的代码分割 const Home = () => import('../components/Home.vue')
r o u t e r 和 router和 router和route区别
- r o u t e r 为 V u e R o u t e r 实 例 , 想 要 导 航 到 不 同 U R L , 则 使 用 router为VueRouter实例,想要导航到不同URL,则使用 router为VueRouter实例,想要导航到不同URL,则使用router.push方法;
- $route为当前router跳转对象里面可以获取name、path、query、params等 。
Promise
Promise是异步编程的一种解决方案,它有三种状态:
- pending:等待状态,比如正在进行网络请求,或者定时器没有到时间;
- fulfill:满足状态,当我们主动回调了resolve时,就处于该状态,并且会回调.then();
- reject:拒绝状态,当我们主动回调了reject时,就处于该状态,并且会回调.catch()。
Promise链式调用
<script>
new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Hello World')
}, 1000)
}).then(data => {
console.log(data);
return data + '111'
}).then(data => {
console.log(data);
return data + '222'
}).then(data => {
console.log(data);
return Promise.reject(data + 'error')
}).then(data => {
// 这部分代码不执行
console.log(data);
return data + '333'
}).catch(data => {
console.log(data);
return data + '444'
}).then(data => {
console.log(data);
});
</script>
Promise.all()
<script>
Promise.all([
new Promise((resolve, reject) => {
setTimeout(() => {
resolve('result1')
}, 2000)
}),
new Promise((resolve, reject) => {
setTimeout(() => {
resolve('result2')
}, 1000)
})
]).then(results => {
console.log(results);
});
</script>
vuex
vuex是实现组件全局状态(数据)管理的一种机制,可以方便的实现组件之间数据的共享
使用vuex统一管理状态的好处:
- 能够在vuex中集中管理共享的数据,易于开发和后期维护;
- 能够高效的实现组件之间的数据共享,提高开发效率;
- 存储在vuex中的数据都是响应式的,能够实时保持数据与页面的同步。
import { createStore } from 'vuex'
export default createStore({
// 创建store数据源,提供唯一的公共数据,所有共享数据都要统一放到Store的State中进行存储
state: {
count: 0
},
// Mutations用于变更Store中的数据,不能在mutations执行异步操作
mutations: {
add(state) {
state.count++
},
add(state, step) {
state.count += step
}
},
// 用于处理异步操作,通过触发mutations间接变更数据
actions: {
},
modules: {
},
// 对store的数据加工
getters: {
}
})