Vue之Vuex
Vue之Vuex
Vue全家桶
vue + vue-router + vuex 更能体现vue的mvvm设计模式,其中:
vuex相当于mvvm中的View视图
vue-router相当于ViewModel控制器
vuex相当于Model数据模型
vue全家桶,基本上网页上什么都可以实现
为什么要使用Vuex
解决组件间传值的复杂性,vuex好比一个商店任何组件都可以进去拿东西
安装Vuex
npm install vuex --save
前后端分离项目
现在用vue + vue-router + vuex做一个项目:
webpack
从今以后就要用vue-cli里的webpack模板了
vue init webpack
npm run dev启动
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 $ from 'jquery' // 这种奇葩的语法是因为webpack帮你导入了里面的文件 import router from './router' import Vuex from 'vuex' // 如果在模块化构建系统中,请确保在开头调用了 Vue.use(Vuex) Vue.use(Vuex) const store = new Vuex.Store({ state: { // 这里面的状态,跟每个组件的数据属性有关系 allList:[], note:{ title:'', content:'', markdown:'' } }, mutations: { // 更改 Vuex 的 store 中的状态的唯一方法是提交 mutation getAllDatas (state) { $.ajax({ url:'http://127.0.0.1:9527/api/comments/', methods:'get', success:function(data){ state.allList = data; } }) }, addOneNote (state,newData){ state.allList = newData; } }, actions:{ addOneNote(context,json){ $.ajax({ url:"http://127.0.0.1:9527/api/comment/create/", methos:'post', data:json, success:function(data){ contenx.commit('addOneNote',data) }, error:function(err){ console.log(err); } }) } } }) Vue.config.productionTip = false /* eslint-disable no-new */ new Vue({ el: '#app', router, store, components: { App }, template: '<App/>' })
App.vue
<template> <div id="app"> <Vheader/> <router-view/> </div> </template> <script> // 下载:npm install bootstrap@3 --save默认下载的最新版本是4的所以要加个@3 // 引入:bootstrap在这里引入即可 import 'bootstrap/dist/css/bootstrap.min.css' import Vheader from './components/Vheader.vue' import $ from 'jquery' export default { name: 'App', components:{ Vheader }, created(){ // DOM创建之前执行的方法 }, mounted(){ // 另一个生命周期方法,和上面的created方法相反,DOM加载完了执行 // DOM加载完了再把数据渲染进去 // var _this = this; // $.ajax({ // url:'http://127.0.0.1:9527/api/comments/', // methods:'get', // success:function(data){ // // 这里面的this并不是全局对象vue // console.log(this); // _this.$store.state.allList = data; // } // }) this.$store.commit('getAllDatas'); } } </script> <style> </style>
index.js
import Vue from 'vue' import Router from 'vue-router' import Vmain from '@/components/Vmain' import Vnote from '@/components/Vnote' // @的是webpack设置的别名:/当前项目/src // import HelloWorld from '@/components/HelloWorld' Vue.use(Router) // 抛出一个router对象 export default new Router({ routes: [ { path: '/', name: 'Vmain', component: Vmain }, { path: '/note', name: 'Vnote', component: Vnote }, ] })
Vnote组件集
Vnote > VnoteShow > VnoteList > VnoteItem
Vnote:
<template> <div class="container"> <div class="row"> <div class="col-md-3"> <div class="panel panel-default"> <div class="panel-heading"> <h3 class="panel-title">我的笔记列表</h3> </div> <div class="panel-body"> <!-- 笔记列表 --> <VnoteShow></VnoteShow> </div> </div> </div> <div class="col-md-9"> <div class="panel panel-default"> <div class="panel-heading"> </div> <div class="panel-body"> <!-- markdown编辑器 --> <Vmark></Vmark> </div> </div> </div> </div> </div> </template> <script> import Vmark from './Vmarked.vue' import VnoteShow from './VnoteShow.vue' export default{ name:'Vnote', data(){ return { noteList:[ {id:1,title:'今天很辛苦',content:'你说哈利'}, {id:2,title:'今天很辛苦2',content:'你说哈利2'} ] } }, components:{ Vmark, VnoteShow } } </script> <style scoped> </style>
VnoteShow
<template> <div> <VnoteList></VnoteList> </div> </template> <script> import VnoteList from './VnoteList.vue' export default{ name:'', data(){ return{ } }, components:{ VnoteList } } </script> <style scoped> </style>
VnoteList
<template> <div> <ul> <VnoteItem v-for = '(item,index) in getAllDatas' :item = 'item'></VnoteItem> </ul> </div> </template> <script> import VnoteItem from './VnoteItem.vue' export default{ name:'', data(){ return{ } }, components:{ VnoteItem }, computed:{ getAllDatas(){ this.$store.state.allList = [{title:'123',content:'123'},{title:'123',content:'123'}]; console.log(this.$store.state.allList); return this.$store.state.allList } } } </script> <style scoped> </style>
VnoteItem
<template> <li> <h2>{{item.title}}</h2> <p>{{item.content}}</p> </li> </template> <script> export default{ name:'', data(){ return{ } }, props:{ item:Object }, } </script> <style scoped> </style>
Vmarked
<template> <div class="wrap"> 请输入文章标题<input type="text" v-model='titleHandler' /> <button class="btn btn-success" @click='addOneNote'>提交</button> <div class="mark"> <textarea rows="10" cols="100" class="editor" v-model = 'markdownHandler'></textarea> <div class="show" v-html = 'markedValue' ref='t'></div> </div> </div> </template> <script> import $ from 'jquery' import Marked from 'marked' export default { name:'Vcontent', data(){ return { markValue:'', } }, methods:{ addOneNote(){ var json = { title:this.titleHandler, markdown:this.markdownHandler, content:this.$refs.t.innerText } // 这个是触发mutaions中的方法,这个方法有局限性,只限于同步操作 // this.$store.commit('addOneNote',json) this.$store.dispatch('addOneNote',json) } }, computed:{ titleHandler:{ set:function(newValue){ this.$store.state.note.title = newValue }, get:function(){ console.log(this.$store.state.note.title) return this.$store.state.note.title; } }, markdownHandler:{ set:function(newValue){ this.$store.state.note.markdown = newValue }, get:function(){ console.log(this.$store.state.note.markdown) return this.$store.state.note.markdown; } }, markedValue(){ return Marked(this.markdownHandler) } } } </script> <style scoped> .t { width: 300px; height: 100px; } .mark{ width:800px; height: 400px; margin: 0 auto; } .editor,.show{ float: left; width: 395px; height: 400px; border: 1px solid #666; } </style>