目录
1,vuex
1.1,vuex介绍
官网介绍:Vuex 是一个专为 Vue.js 应用程序开发的状态(数据)管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
个人理解:就是一个‘’仓库‘’,只不过vuex里面存储的是数据。
1.2,vuex的各个模块
- state:用于数据的存储,
- getters:如vue的计算属性一样,可以对state的数据进行二次封装,
- mutations:同步操作,改变state数据的唯一途径,
- actions:异步操作,类似于mutation,用于提交mutation来改变状态,
- modules:将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter。
1.3,Vuex实例应用
- 创建store目录
store目录结构
- store/index.js
// store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import getters from './getters'
Vue.use(Vuex)
//把modules下的所有文件导入
const modulesFiles = require.context('./modules', true, /\.js$/)
// you do not need `import app from './modules/app'`
// it will auto require all vuex module from modules file
const modules = modulesFiles.keys().reduce((modules, modulePath) => {
// set './app.js' => 'app'
const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
const value = modulesFiles(modulePath)
modules[moduleName] = value.default
return modules
}, {})
const store = new Vuex.Store({
modules,
getters
})
export default store
- main.js
//main.js
把store导入到main中。
import store from './store'
//在vue全局对象上注册store(相当于挂载到全局对象Vue上)
new Vue({
el: '#app',
router,
store,
components: { App },
template: '<App/>'
});
- 数据初始化
// ./modules/login.js
//数据初始化
const state = {
account:'',
password:'',
}
//修改数据的唯一方法(同步)
const mutations = {
SET_ACCOUNT: (state, account) => {
// 将组件的数据存放于state
state.account = account
},
SET_PASSWORD: (state, password) => {
// 将组件的数据存放于state
state.password = password
},
}
//提交mutation,改变数据,
const actions = {
/*alterAccount({ commit }, v) {
commit('SET_ACCOUNT', v)
},*/
}
/*
* namespaced: true:使其成为带命名空间的模块。当模块被注册后,
* 它的所有 getter、action 及 mutation 都会自动根据模块注册的路径调整命名。
* */
export default {
namespaced: true,
state,
mutations,
actions
}
- 存,取值
<template>
<div class="root">
<h1>comA页面</h1>
<button @click="sendBData">把数据存到store中,然后在comB页面展示</button>
<p>接收来自comB的数据:{{BMessage}}</p>
</div>
</template>
<script>
export default {
name: 'comA',
data() {
return {
AMessage:'大威天龙'
};
},
computed:{
BMessage() {
// 取值,this.$store.state.
return this.$store.state.login.password;
}
},
methods:{
sendBData(){
//同步存值
//this.$store.commit(值在store中的mutations的方法名,值)。
// this.$store.commit("login/SET_ACCOUNT", this.AMessage);
//异步存值
//this.$store.dispatch(值在store中的actions的方法名,值)。
this.$store.dispatch("login/getAccount", this.AMessage);
}
}
};
</script>
<style scoped>
.root{
border: solid 3px red;
margin-bottom: 20px;
}
</style>
2,组件插槽
组件标签中的内容默认情况下会被忽略,不会自动显示在组件的模板中。如果需要在组件的模板中显示组件标签的内容,则必须在模板中使用slot标签指定显示的位置。
标签插槽的传值也可以绑定父组件中的数据。
在组件的方法中,可以通过this.$slots访问组件的插槽数据。
console.log(this.$slots);
2.1,具名插槽
如果插槽传递的数据是多部分的,在子组件的模板中需要显示在不同的地方,那么就要把每一部分内容单独放到一个标签中,并为这个标签设置slot属性slot=xxx,然后在子组件模板中要显示这个内容的slot标签设置name=xxx。
//父组件
<span slot="title">{{t1}}</span>
//子组件
<h1>
<slot name="title"></slot>
</h1>
如果某个插槽内容仅仅需要传递数据,不需要传递包裹数据的标签,那么可以使用template标签,在插槽数据渲染时template标签会被删除,在template标签中 slot=“xxx” 可以写为v-slot:xxx 。
<template v-slot:subtitle>{{t2}}</template>
//未设置slot属性的内容,会被显示到匿名插槽中。
<span>{{content}}</span>
2.2,插槽作用域
如果组件内部提供了slot传值,那么使用这个组件时就可以在组件标签内部使用v-lost:xxx="yyy"的形式使用这个传值,其中xxx是slot的name,yyy是传值的对象,slot标签所传的值都包含在yyy对象中。
v-slot:指令可以缩写为#。
v-slot指令的值本质上是一个形参名字,所以可以进行解构。
<template #text="{t1,n1}">
<p>{{t1}}</p>
<p>{{n1}}</p>
</template>
<-- slot标签可以通过v-bind指令进行数据绑定,所绑定的数据可以在父组件中的本组件标签的内容中使用。-->
<slot name="text" :t1="txt" :n1="num"></slot>
3,自定义指令
Vue.directive全局注册一个自定义指令:
1参:指令名字,
2参:指令的配置对象。
Vue.directive("myif",{
//配置对象中的inserted方法,当本指令被插入到某个标签上时调用
inserted(el,dir){}
})
//使用: v-xxx。
<h1 v-myif="flag">根组件1</h1>
4,vue动画
4.1,vue过渡动画
transition标签可以为条件渲染的标签执行切换时添加动画。 transition标签必须配合6个class使用,用于指定动画的方式。
如果页面中多个trnasition标签要执行不同的动画方式,那么需要为这些transition标签设置不同的name属性。
/*Html部分*/
<transition name='titleOne'>
<div v-show="flag" id="box"></div>
</transition>
//css部分
/* 离场动画开始时(开始的瞬间)元素的样式 */
.v-leave{
opacity: 1;
}
/* 离场动画过程中元素的样式 */
.v-leave-active{
transition: all 2s;
position: absolute;
}
/* 离场动画结束时元素的样式 */
.v-leave-to{
opacity: 0;
}
/* 入场动画开始时的样式 */
.v-enter{
opacity: 0;
}
/* 入场动画过程中的样式 */
.v-enter-active{
transition: opacity 2s;
position: absolute;
}
/* 入场动画结束时元素的样式 */
.v-enter-to{
opacity: 1;
}
transition标签中只能包含一个子元素,如果是多个子元素需要使用transition-group标签,transition-group标签的子元素必须包含key属性。
<transition-group>
<div key="1" v-show="flag" class="item">11111</div>
<div key="2" v-show="!flag" class="item2">22222</div>
</transition-group>
4.2,vue关键帧动画
ransition标签也可以使用关键帧动画。
leave-active-class设置:离场的关键帧动画的class,
enter-active-class:入场关键帧动画。
<transition
leave-active-class="shakeout"
enter-active-class="eject"
>
<div id="box" v-show="flag"></div>
</transition>
transition可以使用第三方提供的关键帧动画。
4.3,js动画
transition标签还可以使用js动画,需要绑定leave和enter事件,在leave事件函数中执行离场动画,在enter事件函数中执行入场动画。
<transition
@leave="boxLeave"
@enter="boxEnter"
>
<div id="box" v-show="flag"></div>
</transition>
动画事件函数中会传递两个参数:
1参:要做动画的元素,
2参:动画结束时需要调用的回调函数。
boxLeave(el,cb){});
5,在组件上使用 keep-alive
keep-alive,在vue中保存组件的状态,对组件进行缓存,常在列表页使用。
例子:当查看完某一列表详情页时,返回列表页,需要回到原来的位置,并保持页面的状态。
<div>
<keep-alive>
<router-view/>
</keep-alive>
</div>
6,mixin(混入)
一个混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项。
当组件和混入对象含有同名选项时,以组件的数据优先。
//mixin.js
//第1步,创建混入对象
export default {
data () {
return {
name:'mixinObj',
num:10,
}
},
mounted() {
console.log('minixMounted')
},
methods: {
foo: function () {
console.log('foo')
},
conflicting: function () {
console.log('from mixin')
}
}
}
<script>
/* 第2步,导入 */
import mixin from './mixin.js'
export default {
name: 'HelloWorld',
data() {
return {
msg: 'Welcome to Your Vue.js App',
name:'HelloWorld',
}
},
created() {
/* 第4步,使用 */
/* 例子-1 */
console.log(this.$data)
/* 例子-1控制台输出
* {
* msg:'Welcome to Your Vue.js App',
* name:'HelloWorld',
* num:10,
* }
* */
/* 例子-2 */
/* this.foo();
this.conflicting();
console.log(this.num)*/
},
/* 第3步,注册 */
mixins: [mixin],
methods:{
bar: function () {
console.log('bar')
},
conflicting() {
console.log('from self')
}
},
}
</script>