Vue绑定方式
v-model
v-model是专门用于input,select,textare等表单控件的绑定。它可以渲染变量在dom上,同时控件的value改变时,对应变量也会做出改变。(在表单控件或者组件上创建双向绑定)。
<input type="text" v-model="name">
<textarea v-model="message" placeholder="add multiple lines"></textarea>
<input type="checkbox" id="checkbox" v-model="checked">
<input type="radio" id="one" value="One" v-model="picked">
<select v-model="selected">
<option disabled value>请选择</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
v-bind
动态地绑定一个或多个特性,或一个组件 prop 到表达式。就是把属性变量化,class,style等可以根据变量来改变。同时也是父组件往子组件传值的方法。
<img v-bind:src="imageSrc" :title="imageNum">
v-bind:可以简写成:。例子中图片的地址和title都是来自于vue实例里的变量。
Vuex
vuex 是一个专门为vue.js应用程序开发的状态管理模式。
这个状态我们可以理解为在data中的属性,需要共享给其他组件使用的部分。
也就是说,是我们需要共享的data,使用vuex进行统一集中式的管理。
vuex周期的大概流程是,在vue实例中调用store下的state后,想要改变state,要先通过store.commit(有异步操作要先dispath)来改变state,从而在vue页面中渲染。
state
store里的数据源库(一个全局的data),可在全局调用$store.state访问。
每当 state 变化的时候, 都会重新求取计算属性,并且触发更新相关联的 DOM。
在store里
state:{
name:"张三"
}
vue实例
<div>用户名: {{$store.state.name}}</div>
引用vuex后,在项目任意vue实例里都可以访问到state的内容。
Getter
从 store 中的 state 中派生出一些状态。(可以认为是对数据获取之前的再次编译, store 的计算属性)。他并不会改变state本身。只有当它的依赖值发生了改变才会被重新计算。(类似于vue实例的computed)
Getter 接受 state 作为其第一个参数,可以访问store里的state
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
}
}
第二个参数是getters,可以访问到上下文的getters。
getters: {
doneTodosCount: (state, getters) => {
return getters.doneTodos.length
}
}
假如需要传参,可以通过方法访问
getters: {
getTodoById: (state) => (id) => {
return state.todos.find(todo => todo.id === id)
}
}
在vue实例中访问getters
computed:{
doneTodosCount () {
return this.$store.getters.doneTodosCount
}
}
mutation
mutation是更改 Vuex 的 store 中的状态的唯一方法。需要用store.commit()触发。
mutations:第一个参数是state,第二个参数是载荷(Payload)。即传参,在大多数情况下,载荷应该是一个对象。
非常重要的一点,mutation内必须是同步函数。
mutations: {
increment (state, payload) {
state.count += payload.amount
}
}
执行时store.commit()第一个参数是mutations的名称(字符串),第二个是载荷对象。
store.commit('increment', {
amount: 10
});
Action
Action是专门处理store异步操作的。
Action 提交的是 mutation,而不是直接变更状态。
Action 通过store.dispatch()触发。
actions第一个参数是context(上下文),第二个参数是载荷。
actions: {
incrementAsync ({ commit }) {
setTimeout(() => {
commit('increment')
}, 1000)
}
}
vue实例里执行action。
store.dispatch('incrementAsync', {
amount: 10
})
Module
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。
module 可以把store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter。
store.js
const moduleA = {
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: { ... },
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
在vue实例里访问时
$store.state.a // -> moduleA 的状态
$store.state.b // -> moduleB 的状态
这种写法下state会区分模块,但mutation和action的调用时,写法是一样的。
$store.commit(“set”);
$store.dispath(“set”);
命名空间
假如不同的模块里有出现相同名称的mutations,就会出现问题。为了避免,可以使用命名空间。
在每个模块下添加namespaced: true。即可实现命名空间。
const moduleA = {
namespaced: true,
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
namespaced: true,
state: { ... },
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
在vue实例中调用时改为
$store.commit(“a/set”);
$store.dispath(“b/set”);
vuex和data
vuex是全局存在的,对于一些只在一个vue页面(组件)中用到的信息,可以只存在对于的页面(组件)的data中。store中一般存放一些在多处会读取或者改写的信息,这样可以避免多层的父子传值。一般常见的存放在store里的有用户信息,标签信息等。这样可以在不同的地方操作标签。
例子:在一个项目中有一个右键弹出菜单的组件。组件需要传参,来决定传入内容。
store里
{
state:{
rightMenuData: [{
name: '刷新此窗口',
key: 'refresh'
},
{
name: '关闭此窗口',
key: 'close'
}, {
name: '关闭全部窗口',
key: 'closeAll'
}]
}
}
vue页面中
<right-menu
:menuData="rightMenuData"
:eventHandler="rightClickHandler"
v-on:handleSelect="handleRightSelect"
></right-menu>
列子中的菜单内容存在store里,在一个页面里调用了对应数据。可是实际上项目里只要一个页面需要用到这个数据。这种情况可以把数据只放到页面data里,避免store过于臃肿。
另一个例子:
vue页面中
mounted() {
let user = global.myLocalStorage.getItem("user");
if (user) {
user = JSON.parse(user);
this.sysUserName = user.name || "";
this.sysUserAvatar = user.avatar || "agree.bee.png";
}
//...省略部分
这里页面中用到一个用户信息,由于本地保存的关系,用户数据被存到localstorage里。然后项目在各处拿用户信息的时候会直接从localstorage里拿。这种情况,可以考虑,在页面打开时,只从localstorage拿一次数据,存在store里。在项目运行的过程中就可以直接在store里访问用户信息。
多个store运用
在一些大型应用中,有可能存在多个store的情况,来保持自身的store不受影响。
例子:A实例下面有多个vue子页面b,c,d。它们都需要有自己的store。则在内部Vue实例中new一个vuex.store,并存起来(不一定要存$store,可以是其他变量)。
beforeCreate(){
this.$store = new Vuex.store({
stata,
mutations,
actions
})
}
此时vue实例b,c,d中
this.$store
返回的应该是自己的store。
如果想要访问A页面原来的store,可以用$root,访问根部vue实例,由于他的this.$store并没有被重写,所以指向的还是原来全局的store。
this.$root.$store
发表回复