9月8日vue学习笔记
发布时间:
本文字数:1,199 字 阅读完需:约 6 分钟
vuex状态管理
当写vue项目时,当涉及到频繁的组件之间的数据通讯、一个组件需要多次派发事件时,我们的代码就会变得复杂、冗余、难以维护。
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。我们可以把一些共享的数据保存至vuex中,方便各个组件修改或获取公共状态。
vuex使用单一状态树state对象来作为“唯一数据源”,专门用于存放数据。
• 在组件中访问state下的数据,通过this.$store.state
来访问
• 不能通过this.$store.state
进行赋值,会造成显示与存储不统一。
• 一般建议当需要访问state的属性时,通过计算属性访问,避免对数据赋值。
mutations组件:更新state中数据的核心机制,只有正确提交mutations,才能 保证state中的数据在个组件中渲染与存储一致。
安装
package.json
"dependencies": {
"axios": "^0.27.2",
"vue": "^2.5.2",
"vue-router": "^3.0.1",
"vuex": "^3.6.2" //添加依赖
},
运行 npm install
,即可
使用
新建store/index.js
文件
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state:{
loginName: ''
},
mutations:{
// 给state中的loginName赋值
loginName(state, param){
state.loginName = param
}
}
})
修改 index.js
文件
new Vue({
el: '#app',
router,
store,
components: { App },
template: '<App/>'
})
vuex持久化工具
package.json
"dependencies": {
"axios": "^0.27.2",
"vue": "^2.5.2",
"vue-router": "^3.0.1",
"vuex": "^3.6.2",
"vuex-persistedstate": "^4.1.0"
},
store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import createPersistedState from 'vuex-persistedstate'
Vue.use(Vuex)
export default new Vuex.Store({
state:{
loginName: ''
},
mutations:{
loginName(state, param){
state.loginName = param
}
},
plugins:[createPersistedState()] //持久化存储插件
})
components/Login.vue
<template>
<div>
<div class="user">
<div>账号:<input type="text" v-model="form.userId" ></div>
<div>密码:<input type="password" v-model="form.password" ></div>
<div><button @click="login">登录</button></div>
</div>
</div>
</template>
<script>
export default {
name: "Login",
data() {
return {
form:{
userId:'',
password: '',
} //引入form对象进行双向绑定,提交请求时只需提交form即可
}
},
methods:{
login(){
this.$axios({
url:'api/user/login',
method:'post',
data: this.form //提交form对象为json格式
}).then((result) => {
this.$store.commit('loginName', result.data.object.userName);
this.$router.push('Home');
}).catch((err) => {
console.info(err)
});
}
}
}
</script>
<style scoped>
/*scoped只在当前组件起作用,不影响父组件*/
</style>
components/Home.vue
<template>
<div>
主页组件,{{userName}}
<br>
{{this.$route.query.userName2}}
{{this.$store.state.loginName}}
<br>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: "Home",
data() {
return {
userName:''
}
},
created() {
this.userName = this.$route.params.userName
this.$router.push('User')
},
}
</script>
<style scoped>
</style>
效果,登录成功后将username存储,并显示在home主页中。持久化存储的作用在于刷新后存储的值还在。
使用computed :main.js
<template>
<div>
主页组件,{{userName}}
<br>
{{this.$route.query.userName2}}
<!-- {{this.$store.state.loginName}} -->
{{loginName}}
<br>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: "Home",
data() {
return {
userName:''
}
},
computed:{
loginName(){
return this.$store.state.loginName;
}
},
created() {
this.userName = this.$route.params.userName
this.$router.push('User')
},
}
</script>
<style scoped>
</style>
ElementUI
安装使用
- 执行
npm i element-ui -S
- 修改
main.js
import Vue from 'vue';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import App from './App.vue';
Vue.use(ElementUI);
new Vue({
el: '#app',
render: h => h(App)
});
这种写法
{
render:h=>h(App)
}
等价于
{
render:h=>{
return h(App);
}
}
等价于
{
render:function(h){
return h(App);
}
}
也就是
{
render:function(creatElement){
return creatElemnt(App);
}
}
render:h=>h(App) 这是:
1、ES6的写法,表示Vue实例选项对象的render方法作为一个函数,接受传入的参数h函数,返回h(App)的函数调用结果
2、Vue在创建Vue实例时,通过调用render方法来渲染实例的DOM树
3、Vue在调用render方法时,会传入一个createElement函数作为参数,也就是这里的h的实参是createElement函数,然后createElement会以App为参数进行调用
或者 main.js
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
import axios from 'axios'
import store from './store'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.config.productionTip = false
//设置axios为Vue的属性$axios
Vue.prototype.$axios = axios
Vue.use(ElementUI);
new Vue({
el: '#app',
router,
store,
components: { App },
template: '<App/>'
})
官方网站:https://element.eleme.cn/#/zh-CN
实例
home.vue
<template>
<div>
<el-container>
<el-header>{{loginName}}</el-header>
<el-container>
<el-aside width="240px">
<el-menu
default-active="User"
class="el-menu-vertical-demo"
background-color="#545c64"
text-color="#fff"
@select="menu"
active-text-color="#ffd04b">
<el-submenu index="1">
<template slot="title">
<i class="el-icon-s-tools"></i>
<span>系统设置</span>
</template>
<el-menu-item-group>
<el-menu-item index="Usersetting">用户设置</el-menu-item>
<el-menu-item index="Role" >角色设置</el-menu-item>
</el-menu-item-group>
</el-submenu>
<el-submenu index="2">
<template slot="title">
<i class="el-icon-s-check"></i>
<span>业务办理</span>
</template>
<el-menu-item-group>
<el-menu-item index="2-1">业务一</el-menu-item>
<el-menu-item index="2-2">业务二</el-menu-item>
</el-menu-item-group>
</el-submenu>
</el-menu>
</el-aside>
<el-main><router-view></router-view></el-main>
</el-container>
</el-container>
</div>
</template>
<script>
export default {
name: "Home",
computed:{
loginName() {
return this.$store.state.loginName;
}
},
methods: {
menu(index){
this.$router.push(index)
}
},
}
</script>
<style scoped>
.el-header{
height: 5vh
}
.el-aside{
height: 95vh;
background-color: #545c64;
}
.el-main{
height: 95vh
}
</style>
Usersetting.vue
<template>
<div>
<el-form :inline="true" :model="queryForm" class="demo-form-inline">
<el-form-item label="账号">
<el-input v-model="queryForm.userId" placeholder="账号"></el-input>
</el-form-item>
<el-form-item label="姓名">
<el-input v-model="queryForm.userName" placeholder="姓名"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="getList">查询</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
name: "UserSetting",
created() {},
data() {
return {
queryForm:{
userId:'',
userName:''
},
};
},
props: {},
methods: {
getList(){}
},
};
</script>
<style scoped></style>
login.vue
<template>
<div class="login">
<el-input placeholder="输入账号" v-model="form.userId" clearable></el-input>
<el-input placeholder="请输入密码" v-model="form.password" show-password></el-input>
<el-button type="success" @click="login" :loading="loading" :disabled="disabled">登录</el-button><br>
<el-button type="primary">注册</el-button>
</div>
</template>
<script>
import md5 from '../../static/md5';
export default {
name: "Login",
data() {
return {
form: {
userId: '',
password: '',
},
loading: false,
disabled: false,
}
},
methods: {
login() {
this.loading = true;
this.$axios({
url: 'api/user/login',
method: 'post',
data: this.form
}).then((result) => {
// this.loading = false;
// this.disabled = true;
this.$message({
message: '欢迎您'+result.data.object.userName+',登录成功',
type: 'success'
});
this.$store.commit('loginName', result.data.object.userName);
this.$router.push('Home');
}).catch((err) => {
// setTimeout(() => {
this.loading = false;
// }, 1000);
//
this.$message.error(err);
});
}
}
// methods: {
// toHome() {
// this.$router.push({ name: 'Home', params: { userName: '李雷' } })
// }
// },
}
</script>
<style scoped>
/*scoped只在当前组件起作用,不影响父组件*/
.login{
width: 300px;
margin: 10% auto;
text-align: center;
}
.el-input{
margin: 10px;
}
.el-button{
margin: 10px;
width: 100%;
}
</style>
router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import Login from '@/components/Login'
import Home from '@/components/Home'
import User from '@/components/sys/User'
import Role from '@/components/sys/Role'
import UserSetting from '@/components/sys/UserSetting'
Vue.use(Router)
export default new Router({
// mode: ,
routes: [
{
path:'/',
redirect:'/Login'
},
{
path:'/Login',
name:'Login',
component: Login
},{
path:'/Home',
name:'Home',
component: Home,
children: [
{
path:'/User',
name:'User',
component: User
},{
path:'/Role',
name:'Role',
component: Role
},{
path:'/UserSetting',
name:'UserSetting',
component: UserSetting
}
]
}
]
})
基本思路:把子页面放在children路由中,借助 @select="menu"
,实现点击目录,右侧跳转子页面,具体参考以上代码