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 {
300px;
height: 100px;
}
.mark{
800px;
height: 400px;
margin: 0 auto;
}
.editor,.show{
float: left;
395px;
height: 400px;
border: 1px solid #666;
}
</style>