也是对xhr的封装。是一个插件库。官方已经不再维护。推荐axios。
Vue.use(vueResource);
应用插件后,vc上有$http:
多个子组件需要展示不同的内容.
在父组件的模板里写内容,子组件申明一个插槽。内容会在插槽中显示。
父组件解析完结构再传过去。
- {{ item }}
当使用template时,可用v-slot:name.指明插槽位置。
{{title}}
(也可以有名字)
数据在子组件,结构需要由父组件决定。
需求第一次是无序,第二次是有序,第三次是h4。
可以在app组件传递数据,子组件根据数据进行条件渲染。
弊端是需要写的判断太多。
使用插槽:如果此时games数据不在app里,无法使用。
现需要app组件获取子组件里的数据。
App里面需要使用Category组件,组件里有一个插槽,且在App里需要数据,数据来自于定义插槽的组件。
数据是一个对象,属性名是games,值是数组。所以
{{title}}
- {{ item }}
- {{ item }}
{{ item }}
刷新页面时,vue实例重新加载,从而,store也被重置了。store是用来存储组件状态的,而不是用来做本地数据存储的。所以,对于不希望页面刷新之后被重置的数据,使用本地存储来进行存储。
获取数据的时候,在state和cookie中都保存一份。
在Vue的created钩子中,重新commit store中的方法,从cookie中获取数据设置到state中。
共享数据---全局事件总线实现,bcd需要访问到a里面的x,则需要在bcd中给$bus绑定事件和回调。a中触发事件并传递参数,bcd中触发回调,获取参数。
如果此时bcd中都需要修改x这个数据,此时a需要x修改的值,则此时在a中绑定事件和回调,获取参数,触发回调,在bcd中触发事件,传递参数给a。
共享数据---vuex实现
sum =:{{sum}}
在组件中操作,调用dispatch("操作",数据),Actions是一个object对象,Actions里有个key叫"操作",value是一个函数,函数就会被调用,且会收到数据,在这个函数里面,调用commit,Mutations也是一个object对象,Mutations里也有个key叫"操作",value是一个函数,该函数会得到state和数据,在该函数写state.sum += 2,底层自动mutate,State里面的sum就变为了2,然后render,重新解析组件。
Actions,里面可以发请求,从后端接口中获取数据。也可以进行逻辑判断,如奇数再加,等一等在加等。Vuex运行不通过Actions。
Mutations是真正操作数据的对象。
Actions,Mutations,State这三个对象都需要store进行管理。如store.dispatch,store.commit。
需要让所有的组件实例对象都能看见store。
把store传入创建实例的new Vue()的配置参数对象中,会出现在$options中,$options中出现了会在你Vue.use()时执行this.$store = $options.store的操作。
在组件中可使用 this 访问原型上的属性,template 拥有组件实例的上下文,
可直接通过 {{ $store.state.userName }} 访问,等价于 script 中的 this.$store.state.userName。
至于 {{ store.state.userName }},script 中的 data 需声明过 store 才可访问。
对比全局事件总线:
npm i vuex@3.
必须在创建store实例之前调用Vue.use(Vuex).
在脚手架中, import语句自动提前。
App,子组件上可以看见store。
index.js:
//该文件用于创建Vuex中最为核心的store
import Vuex from 'vuex'
import Vue from 'vue'
Vue.use(Vuex);//use Vuex后 ,在Vue配置项可以传入store。
//actions 用于响应组件中的动作
const actions = {};
//mutations 用于真正去操作数据
const mutations = {};
//state 用于存储数据
const state = {};
//创建并导出store
export default new Vuex.Store({
actions,mutations,state
});
main.js:
/*
该文件为入口文件
*/
import Vue from 'vue'
//引入App组件 所有组件的父组件
import App from './App.vue'
//引入store
import store from './store/index';
//关闭vue生产提示
Vue.config.productionTip = false
//创建vue实例对象
new Vue({
//将App组件放入容器中
render: h => h(App),
//store:{}, vm和vc都能看见
store,
beforeCreate() {
//安装全局事件总线
Vue.prototype.$bus = this;
},
}).$mount('#app')
若只是直接+和-则可以直接调用commit,
若有业务逻辑,则需要先调用dispatch。
methods: {
increment(){
this.$store.commit('PLUS',this.n);
},
decrement(){
this.$store.commit('REDUCE',this.n);
},
evenIncrement(){
this.$store.dispatch('evenPlus',this.n);
},
waitIncrement(){
this.$store.dispatch('waitPlus',this.n);
}
},
//actions 用于响应组件中的动作
const actions = {
//context:上下文对象
/*plus(context,value){
context.commit('PLUS',value)
},
reduce(context,value){
context.commit('REDUCE',value)
},*/
evenPlus(context,value){
if(!(context.state.sum%2)){
context.commit('PLUS',value)
}
},
waitPlus(context,value){
setTimeout(() => {
context.commit('PLUS',value)
}, 500);
}
};
//mutations 用于真正去操作数据
const mutations = {
PLUS(state,value){
state.sum += value;
},
REDUCE(state,value){
state.sum -= value;
}
};
//state 用于存储数据 响应式 getset
const state = {
sum:0,
};
Devtools和mutation交互。
为什么在actions中需要使用context而不是直接commit:
在actions的函数里面还可以调用dispatch,还需要context里面的state。
jiaOdd---demo1----demo2
为什么在actions中不能通过context.state直接操作数据:
此时页面会发生变化,开发者工具失效。
为什么不在组件中进行业务逻辑:
当业务非常复杂时,代码冗余太高,不存在复用。
此时所有涉及到该业务的都通过actions。
传递多个参数
let data = {form:form,router:this.$router,message:this.$message}
this.$store.dispatch('user/login',data)
计算属性:本组件复用
目前需要跨组件复用。
此时开发者工具也能看见getters
multiplySum =:{{$store.getters.bigSum}}
const getters = {
bigSum(state){
return state.sum*10;
}
}
//创建并导出store
export default new Vuex.Store({
actions,
mutations,
state,
getters
});
简化代码:
ES6语法:
只有当a是一个变量的时候才可以简写。
mapState接收一个对象(数组(名字一致))作为参数,返回的是一个对象:
两者效果相同:
computed:{
/*亲自去写计算属性
sum(){
return this.$store.state.sum;
},*/
//从state中读取数据,对象写法
//...mapState({sum:'sum',school:'school',subject:'subject'})
//从getters中读取数据,数组写法
...mapState(['sum','school','subject']),
...mapGetters(['bigSum'])
},
此时生成的increment是下面那个:
当绑定的事件不写小括号时,也会传参,参数是event。
所以需要这么传参:
也可以这么写:
methods: {
//commit 原始写法
/*
increment(){
this.$store.commit('PLUS',this.n);
},
decrement(){
this.$store.commit('REDUCE',this.n);
},*/
//生成对应的方法,方法中会调用commit去联系mutations 对象写法
...mapMutations({increment:'PLUS',decrement:'REDUCE'}),
//数组写法 (需要名字一致)
//...mapMutations(['PLUS','REDUCE']),
//dispatch 原始写法
/*evenIncrement(){
this.$store.dispatch('evenPlus',this.n);
},
waitIncrement(){
this.$store.dispatch('waitPlus',this.n);
}*/
//生成对应的方法,方法中会调用commit去联系actions 对象写法
...mapActions({evenIncrement:'evenPlus',waitIncrement:'waitPlus'}),
//数组写法 (需要名字一致)
//...mapMutations(['evenPlus','waitPlus']),
},
vuex中保存sum和persons,在Item中读取persons,在persons中读取sum。
Vuex:
const state = {
sum:0,
school:'atguigu',
subject:'前端',
persons:[{id:'001',name:'张三'}]
};
PersonList:
computed:{
/*personList(){
return this.$store.state.persons;
},*/
...mapState(['persons']),
sum(){
return this.$store.state.sum;
}
},
methods: {
add(){
const personObj = {id:nanoid(),name:this.name};
this.$store.commit('ADD_PERSON',personObj);
this.name = '';
},
},
ItemList:
computed:{
...mapState(['sum','school','subject','persons']),
...mapGetters(['bigSum'])
},
methods: {
//生成对应的方法,方法中会调用commit去联系mutations 对象写法
...mapMutations({increment:'PLUS',decrement:'REDUCE'}),
//生成对应的方法,方法中会调用commit去联系actions 对象写法
...mapActions({evenIncrement:'evenPlus',waitIncrement:'waitPlus'}),
},
store里有countOptions,personOptions。
$store.state:
$store.getters:
item.js:
//求和功能相关的配置
export default{
namespaced:true,
actions:{
evenPlus(context,value){
if(!(context.state.sum%2)){
context.commit('PLUS',value)
}
},
waitPlus(context,value){
setTimeout(() => {
context.commit('PLUS',value)
}, 500);
}
},
mutations:{
PLUS(state,value){
state.sum += value;
},
REDUCE(state,value){
state.sum -= value;
},
},
state:{
sum:0,
school:'atguigu',
subject:'前端',
},
getters:{
bigSum(state){
return state.sum*10;
}
},
}
persons.js:
import axios from "axios";
import { nanoid } from "nanoid";
//人员管理功能相关的配置
export default{
namespaced:true,
actions:{
addPersonWang(context,value){
if(value.name.indexOf('王') === 0){
context.commit('ADD_PERSON',value);
}else{
alert('添加的人需要姓王!')
}
},
addPersonSever(context){
axios.get('https://api.uixsj.cn/hitokoto/get?type=social').then(
response => {
context.commit('ADD_PERSON',{id:nanoid(),name:response.data});
},
error =>{
alert(error.message);
}
)
}
},
mutations:{
ADD_PERSON(state,value){
state.persons.unshift(value);
}
},
state:{
persons:[{id:'001',name:'张三'}]
},
getters:{
firstPersonName(state){
return state.persons[0].name;
}
},
}
index.js:
//该文件用于创建Vuex中最为核心的store
import Vuex from 'vuex'
import Vue from 'vue'
import countOptions from './item'
import personOptions from './persons'
Vue.use(Vuex);//use Vuex后 ,在Vue配置项可以传入store。
//创建并导出store
export default new Vuex.Store({
modules:{
countOptions,
personOptions
}
});
personList.vue:
人员列表
- {{p.name}}
sum:{{sum}}
列表中第一个人的名字:{{firstPersonName}}
ItemList.vue:
sum =:{{sum}}
multiplySum =:{{bigSum}}
I am at{{school}} learn {{subject}}
人数:{{persons.length}}
this.$store: