vue+vuex+axios从webpack-server获取模拟数据存入vuex并取回展示到页面
时间:2017-03-23 20:09:04
阅读:426
评论:0
收藏:0
[点我收藏+]
标签:errno 文件中 div 第一个 渲染 getter fun pes vue
在vue项目中组件间相互传值或者后台获取的数据需要供多个组件使用的情况很多的话,有必要考虑引入vuex来管理这些凌乱的状态,今天这边博文用来记录这一整个的过程,后台api接口是使用webpack-server模拟的接口,这个前面的文章中有提到,需要的可以去翻阅。
整个的流程是在组件的created中提交dispatch,然后通过action调用一个封装好的axios然后再触发mutation来提交状态改变state中的数据,然后在组件的计算属性中获取state的数据并渲染在页面上
首先新需要在项目中安装vuex:
运行命令 npm install vuex --save-dev
在项目的入口js文件main.js中
import store from ‘/store/index‘
并将store挂载到vue上
new Vue({
el: ‘#app‘,
router,
store,
template: ‘<App/>‘,
render: (createElement) => createElement(App)
})
然后看下整个store的目录结构,modules文件夹用来将不同功能也面的状态分成模块,index.js文件夹是store的入口文件,types文件夹是定义常量mutation的文件夹
整个vuex的目录结构如下:
这里我新建了文件夹fetch用来编写所有的axios处理和axios封装
你用的是vuex,vuex主要是getter,state,actions, mutations四个部分,他不该在actions里直接返回,你可以在data里定义获取video就好了,当执行mounted时,会触发action里的getVideo方法,通过commit触发mutations来修改state里的值,然后就可以获取getter里的值了,在其他地方就可以用thisvideo这种形式了
vue中的异步问题困扰了好久,终于解决了,mark一下给需要的朋友。
项目开始使用vuex来解决组件之间变量传值的问题。但是用着用着出现了一个问题,子组件中用到mapboxMap属性,而mapboxMap属性值需要等待父组件初始化函数执行完之后才会有,这就存在一个异步的问题,页面已初始化加载的时候mapboxMap是为undefined,解决方法为在子组件中监听mapboxMap的值,具体方法如下:
父组件中:
子组件中
在vue 中,只有mutation 才能改变state mutation 类似事件,每一个mutation都有一个类型和一个处理函数,因为只有mutation 才能改变state, 所以处理函数自动会获得一个默认参数 state 所谓的类型其实就是名字,action去commit 一个mutation, 它要指定去commit哪个mutation, 所以mutation至少需要一个名字,commit mutation 之后, 要做什么事情,那就需要给它指定一个处理函数, 类型(名字) + 处理函数就构成了mutation 现在testjs添加mutation。
Vue 建议我们mutation 类型用大写常量表示,修改一下,把mutation 类型改为大写
action去commit mutations, 所以还要定义action testjs 里面添加actions
action 和mutions 的定义方法是类似的,我们要dispatch 一个action, 所以actions 肯定有一个名字,dispatch action 之后它要做事情,就是commit mutation, 所以还要给它指定一个函数。因为要commit mutation ,所以 函数也会自动获得一个默认参数context, 它是一个store 实例,通过它可以获取到store 实例的属性和方法,如 contextstate 就会获取到 state 属性, contextcommit 就会执行commit命令。
其实actions 还可以简写一下, 因为函数的参数是一个对象,函数中用的是对象中一个方法,我们可以通过对象的解构赋值直接获取到该方法。修改一下 actions
现在就剩下dispatch action 了。什么时候dispatch action 呢? 只有当我们点击按钮的时候 给按钮添加click 事件,在click 事件处理函数的中dispatch action
这个时候我们需要新建一个 *** 作组件,我们暂且命名为testvue
然后,我们在methods里面获取这两个 *** 作事件
当然上面这种写法比较麻烦,vuex还给我我们提供了mapActions这个函数,它和mapState 是一样的,把我们的 action 直接映射到store 里面的action中。
如果事件处理函数名字和action的名字不同,给mapActions
提供一个对象,对象的属性是事件处理函数名字, 属性值是 对应的dispatch 的action 的名字。
这时候我们单击按钮,就可以看到count 发生变化。
最后附一张简单的图形解析,看起来应该能更直观一点
Vuex是Vue官方推出的 一个 状态管理工具,其能生成一个单独的全局状态实例,其有以下特点:
注意事项 :版本号在362以下的vuex适用于vue2,若在vue2的工程项目中直接 npm i vuex -s 会报如下的错误
解决办法是指定版本号,vue2使用的版本目前最高支持到362,具体可在 更新记录 中进行查阅。
State相对于vuex来说就好比vue组件中的data,所以声明state必须是 纯粹的对象 (含有零个或多个的 key/value 对) ,在建立后,State数据会被转换为响应式的数据。
首先定义一个store,里面只包含State,然后我们将其注入到全局,下面一次进行以上三种形式的测试
1在vue组件中访问
注:由于不能修改store数据,所以一般不建议在data中访问store的数据,因为它没有缓存效果,一般在计算属性中获取state数据。
mapState 语法糖的主要作用是将store中的state映射到当前vue实例的computed中
在没有 mapState 时,我们获取state一般在computed中进行获取,对于获取多个state数据,那么我们就要写多个computed方法,如下
针对于写多个computed的繁琐和冗余,使用 mapState 可以帮助我们生成 计算属性 。
当映射的计算属性的名称与 state 的数据名称相同时,我们也可以给 mapState 传一个字符串数组。
mapState 返回的是一个对象,如果computed只包括 mapState ,那么直接写
如果你的computed还有其它store之外的属性,那么你需要使用剩余运算符,把mapState返回的对象和其它计算属性对象合并
先说问题,父组件利用props向子组件传值,浏览器
console
有这个值,但是获取不到内部的属性,困了我3个小时,真的
personal
console
以下为原代码
1、homevue(父组件)--personal是被传的参数
<!--子组件-->
<form-picker
class="form-picker"
:personal="personal"
>
</form-picker>
export
default
{
data(){
return{
personal:{
state:'',////判断是修改状态,还是新增状态
add/edit
data:[]
}
}
},
mounted(){
this$apipersonalsearchPersonalInfo(thisuserInfouserId)then((res)=>{
thispersonaldata
=
resdatadata
//这里给personal对象赋值接口传来的数据
})
},
}
2、formPicker
(子组件)
--接收personal
export
default
{
props:['active','personal'],
mounted(){
consolelog(149,thispersonal)
consolelog(150,thispersonalstate)
}
}
运行结果
明明149行有
state
值,150行输出却没有了,是不是超级奇怪
后面经过大佬的讲解,其实浏览器consolelog也是应该没有的
所以,其实我们子组件一开始根本就没有取到这个personal这个对象。
3、解决方法--使用watch
父组件
export
default
{
data(){
return{
personal:{
state:'',////判断是修改状态,还是新增状态
add/edit
data:[]
}
}
},
mounted(){
this$apipersonalsearchPersonalInfo(thisuserInfouserId)then((res)=>{
//thispersonaldata
=
resdatadata
//这里给personal对象赋值接口传来的数据
//使用以下方法重新赋值,上面方法watch监听不到,具体什么原因,我也不清楚,知道的告知我!谢谢
thispersonal
=
{
data:
resdatadata,
state:
'edit'
}
})
},
}
接下来子组件就能
watch
到
personal
了
子组件
watch:{
personal(newValue,oldValue){
consolelog(181,newValue)
},
/
输出
{
data:
resdatadata,
state:
'edit'
}
/
}
总结
以上所述是小编给大家介绍的解决vue组件props传值对象获取不到的问题,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!
您可能感兴趣的文章:vue20
子组件改变props值,并向父组件传值的方法详解vue父子组件间传值(props)vue之父子组件间通信实例讲解(props、$ref、$emit)vue组件中使用props传递数据的实例详解vue父组件向子组件(props)传递数据的方法vue父组件通过props如何向子组件传递方法详解详解vue2父组件传递props异步数据到子组件的问题
vuex是一个专门为vue构建的状态管理工具,主要是解决多组建状态共享的问题。强调的是集中式管理(组件与组件之间的关系变成了组建跟仓库之间的关系)。
vuex的核心包括:state(存放状态)、mutations(同步的更改状态)、actions(发送异步请求拿到数据)、getters(根据之前的状态发布新的状态)、modules(模块划分)
state发布一条新的数据,在getters里面更具状态派发新的状态,actions发送异步请求获取数据,然后再mutations里面同步的更新数据
使用场景:购物车的数据共享,登入注册
vuex的原理:
vuex实现了一个单项数据流,在全局又有一个state存放数据,当组建要更改state中的数据时,必须通过Mutation进行,mutation同时提供了订阅者模式供外部插件调用获取state数据的更新。而当所有异步 *** 作(常见于调用后台接口异步获取更新数据)或批量的同步 *** 作需要走Action,但Action也是无法直接修改state的,还是需要通过mutation来修改state的数据。最后根据state的变化,渲染到视图上。
vuex的使用
1、src目录下面新建一个vuex的文件夹
2、vuex 文件夹里面新建一个storejs
3、安装vuex
cnpm install vuex --save
4、在刚才创建的storejs引入vue 引入vuex 并且use vuex
import Vue from 'vue'
import Vuex from 'vuex'
Vueuse(Vuex)
5、定义数据
/1state在vuex中用于存储数据/
var state={
count:1
}
6、定义方法 mutations里面放的是方法,方法主要用于改变state里面的数据
var mutations={
incCount(){
++statecount;
}
}
暴露
const store = new VuexStore({
state,
mutations,
getters
})
export default store;
组建里面的使用
1引入 store
import store from '/vuex/storejs';
2、注册
export default{
data(){
return {
msg:'我是一个home组件',
value1: null,
}
},
store,
methods:{
incCount(){
this$storecommit('incCount'); /触发 state里面的数据/
}
}
}
3、获取state里面的数据
this$storestate数据
4、触发 mutations 改变 state里面的数据
this$storecommit('incCount');
getters,有点类似计算属性,改变state里面count数据的时候,会出发getters里面的方法,获取新值
var getters={
computedCount:(state)=>{
return statecount2
});
页面使用:this$storegetterscomputedCount
action
action类似于mutation,不同在于,
action 提交的事mutation,而不是直接改变状态(也就是state里面的值)。
action 可以包含任意异步 *** 作
var actions={
acctionsincCount:(context)=>{
contextcommit('incCount');
});
页面使用:this$storedispatch()
Vuex是vue官方的一款状态管理工具,什么是状态呢?我们在前端开发中有一个概念:数据驱动,页面中任意的显示不同,都应该有一条数据来控制,而这条数据又叫做state,状态。
在vue中。组件间进行数据传递、通信很频繁,而父子组件和非父子组件的通信功能也比较完善,但是,唯一困难的就是多组件间的数据共享,这个问题由vuex来处理
vue提供的一个全局的状态管理工具,主要处理项目中多组件间状态共享
因为在组件中可以通过this storestate来使用state中管理的数据
但是我们发现,这样使用的话,当state的数据更改的时候,vue组件并不会重新渲染
也就是说,如果想要在组件中响应式的使用的时候,我们需要通过计算属性(computed)来使用
这样的写法很无趣,而且如果使用的状态较多会产生冗余的感觉,所以vuex提供了mapState辅助函数,帮助我们在组件中获取并使用vuex的store中保存的状态
所以我们可以这样写:
但是如果组件中已经有了num这个数据了,而state中的数据名字也叫num就会照成冲突,这个时候我们可以在组件使用state的时候,给状态起个别名:
但是,有的时候我们在组件中还有自己的业务逻辑需要用到计算属性:
有的时候,我们需要根据state中的某一个状态派生出一个新的状态,例如,我们state中有一个num,在某些组件中需要用到是num的二倍的一个状态,我们就可以通过getters来创建
创建了之后,在组件中通过this$storegettersdoubleNum来获取里面的数据
当然vuex也提供了mapGetters辅助函数来帮助我们在组件中使用getters里的状态,且,使用的方法和mapState一模一样
我们不能直接在组件中更改state:this$storestatenum=2,而是需要使用mutations来更改,mutations也是一个纯对象,里面包含很多更改state 的方法,这些方法的形参接收到state,在函数体里更改,这时,组件用到的数据也会更改,实现响应式。
但是我们也不能直接调用mutations 的方法,需要使用this$storecommit来调用,第一个参数为调用的方法名,第二げ参数为传递参数
vuex提供了mapMutations方法来帮助我们在组件中调用mutations 的方法,使用方法和mapState、mapGetters一样
Action 类似于 mutation,不同在于:
Action 提交的是 mutation,而不是直接变更状态。
Action 可以包含任意异步 *** 作。
也就是说,如果有这样的需求:在一个异步处理之后,更改状态,我们在组件中应该先调用actions,来进行异步动作,然后由actions调用mutation来更改数据
如上,actions的方法中可以进行异步的动作,且形参会接收store,从中取出commit方法用以调用mutations的方法
在组件中通过this$storedispatch方法调用actions的方法
当然也可以使用mapMutations来辅助使用
组件使用数据且通过异步动作更改数据的一系列事情:
1生成store,设置state
2在根实例中注入store
3组件通过计算属性或者mapState来使用状态
4用户产生 *** 作,调用actions的方法,然后进行异步动作
5异步动作之后,通过commit调用mutations的方法
6mutations方法被调用后,更改state
7state中的数据更新之后,计算属性重新执行来更改在页面中使用的状态
8组件状态被更改创建新的虚拟dom
9组件的模板更新之后重新渲染在dom中
vuex的使用:
目前市场上有两种使用vuex的情况,
第一种:将需要共享、需要管理的状态放入vuex中管理,也就是说在必要时使用
第二种:将所有的数据都交由vuex管理,由vuex来承担更多的责任,组件变得更轻量级,视图层更轻
在实现回到顶部功能的时候,我们写了一个backTop组件,接下来需要通过监听windowscroll事件来控制这个组件显示隐藏
写了一个v-back-top指令,就是将回到顶部功能做成一个指令,哪个组件或者dom需要使用到回到顶部,就加上这个指令就可以,设置不同的参数来控制在不同的情况下触发
组件库就是通用组件的集合
pc:element-ui iview
mobile: mint-ui
当我们在使用一些插件的时候,经常需要在dom更新完成后进行必要 *** 作,但是在vue中提供的api只有updated钩子函数,而在这个函数里,任意数据的变化导致的dom更新完成都会触发,所以很可能会造成无关数据的影响,而使用监听的话只能监听到数据的变化,此时dom还没有更新,我们只能强行使用setTimeout来处理
这里推荐大家使用nextTick全局方法:
在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。
v-for='n in 10' n会打印1-10
通用:beforeCreate/created/beforeMount/mounted/beforeUpdate/updated/beforeDestroy/destroyed
路由守卫:beforeRouteEnter/beforeRouteUpdate (22 新增)/beforeRouteLeave
v-if是真正的条件渲染,会确保在切换中条件块内的事件监听、子组件都会适当的被销毁和重建
v-show总是将节点渲染在dom中,只是基于css:display来控制节点的显示和隐藏
v-if有更高的切换开始,v-show有更高的初始渲染开销
v-if是惰性的,初始条件为假,就不会渲染
axios请求的时候不会带上cookie,不会影响带宽,可以通过withCredentials:true来设置
对axios 的请求头进行设置:
axiosdefaultsheaders = {'Content-Type':''}
vue20不在更新维护vue-resource,官方推荐使用axios
6为了让组件可以组合,我们需要一种方式来混合父组件的内容与子组件自己的模板。这个过程被称为内容分发 (即 Angular 用户熟知的“transclusion”)。Vuejs 实现了一个内容分发 API,参照了当前 Web Components 规范草案,使用特殊的 <slot> 元素作为原始内容的插槽。
全局:Vuecomponent(name,Vueextend({}))
局部:{ components:{name:Vueextend({})} }
假设我们有一个数据为num,还希望拥有一个数据为doublenum,而且希望doublenum的值永远都是num的二倍
方法:
prop是单向绑定的,父组件属性变化,传递给子组件,但是,子组件数据变化,不能直接传递给父组件,也就是数据的流行是从父组件流向子组件的,为了防止子组件修改父组件的数据(会让应用的数据流变的更难开发、更新、维护)
使用了vuex工具的时候,store中数据在组件中使用的过程也是单向数据流,state->vue component->actions->mutations->state->vue component
当数据改变之后,vue会创建新的虚拟dom来和原来的虚拟dom做对比,在创建新的虚拟的dom的时候,会根据key来查找在原来的虚拟dom中有没有某个部分,如果原来的有,这次的也需要,就会实现复用,而且在做diff对比的时候,如果有key会加快对比的查找速度,提高性能
尽量循环的时候不要将key设置为数组的索引,因为当删除某一个元素的时候,就会导致删除位置下面的所有元素的key值都与上一次虚拟dom的key值不同,导致复用失败,这个时候我们最好使用关键的唯一的,例如id这样的数据作为key
如果数据变化只是值的变化而不是条数和位置的变化,可以使用索引作为key
Vueuse会查找插件对象里的install方法去执行,并且给install方法里传入Vue对象
很多情况下,一个应用会有PC和移动端两个版本,而这两个版本因为差别大,内容多,所以不能用响应式开发但是单独开发,而域名只有一个,用户进入域后直接返回对应设备的应用,做法主要有两种:
以上就是关于vue中为什么我模拟的数据goods页面取不到,在app.vue中就能取到全部的内容,包括:vue中为什么我模拟的数据goods页面取不到,在app.vue中就能取到、vue 如何在mounted方法里获取actions里请求的回调函数、vue中监听Vuex中state内的变量,实现异步赋值等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)