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>
来源:oschina
链接:https://my.oschina.net/u/4349250/blog/3485928