創(chuàng)建項(xiàng)目
vue create vuextest2
cd vuextest2
yarn serve
- 安裝vuex ,vue-router, element-ui
// 安裝 vuex
npm install vuex --save
//或
yarn add vuex
//安裝vue-router
npm install --save vue-router
//安裝element-ui
npm i element-ui -S
- 在src下創(chuàng)建router文件夾router/index.js
import Vue from "vue";
import Router from "vue-router";
// 引入組件
import Login from "@/components/login";
//注冊組件
Vue.use(Router);
//導(dǎo)出組件
export default new Router({
routes: [
{
path: "/",
name: "login",
component: Login
}
],
mode: "history" //去除地址欄中的#號
});
- main.js中引入路由
import router from "./router";
Vue.config.productionTip = false;
new Vue({
router,
render: h => h(App)
}).$mount("#app");
- 引入 Element
//在 main.js 中添加以下內(nèi)容:
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI)
- 引入重置樣式reset.css
在src下新建css/reset.css文件網(wǎng)上下載reset.css樣式,
在index.html中:
<link rel="stylesheet" href="../src/static/css/reset.css">
vue中的節(jié)點(diǎn)操作ref和this.$refs.名稱
<div id="app">
<input type="text" ref="input1" class="input1"/>
<button @click="add">添加</button>
</div>
<script>
new Vue({
el: "#app",
methods:{
add:function(){
this.$refs.input1.value ="22"; //this.$refs.input1 減少獲取dom節(jié)點(diǎn)的消耗
}
}
})
</script>
一般來講,獲取DOM元素筑悴,需document.querySelector(".input1")獲取這個dom節(jié)點(diǎn),然后在獲取input1的值较鼓。
但是用ref綁定之后立倍,我們就不需要在獲取dom節(jié)點(diǎn)了舍哄,直接在上面的input上綁定input1溪椎,然后$refs里面調(diào)用就行普舆。
然后在javascript里面這樣調(diào)用:this.$refs.input1 這樣就可以減少獲取dom節(jié)點(diǎn)的消耗了。
前后端數(shù)據(jù)交互--axios
- 安裝axios
npm i -S axios
- 在main.js中
// 引入axios
import axios from "axios";
// 掛載在vue的原型上校读,這樣每個vue實(shí)例都可以使用這個方法
Vue.prototype.axios = axios;
用node.js啟動一個后端服務(wù)接口
//全局安裝express
npm install express -g
npm install -g express-generator
//創(chuàng)建服務(wù)項(xiàng)目
express server -e
// 初始化項(xiàng)目
cd server
npm install
//啟動服務(wù)器
nodemon app
解決跨域問題 --- 配置代理
創(chuàng)建vue.config.js文件
module.exports = {
devServer: {
proxy: {
'/api': {
target: 'http://localhost:888',
ws: true,
changeOrigin: true,
pathRewrite: {
'^/api': '' //通過pathRewrite重寫地址,將前綴/api轉(zhuǎn)為/
}
}
}
}
//在頁面發(fā)起請求:
axios.get('/api/address').then(res => {
console.log(res)
})
此處改為請求https://jsonplaceholder.typicode.com/users接口數(shù)據(jù)
登錄成功后請求到數(shù)據(jù)祖能,利用vuex存儲數(shù)據(jù)
創(chuàng)建index.vue后臺頁面,然后配置路由
vue組件異步加載
- 使用() => import()
const ImportFuncDemo1 = () => import('../components/ImportFuncDemo1')
- 使用resolve => require(['./_account'], resolve)
- 使用Webpack 的內(nèi)置語句: import(*)
vuex數(shù)據(jù)處理
- 安裝
npm i vuex -S
創(chuàng)建store/store.js文件
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
const state = {
userInfo: {}
};
const mutations = {
SAVE_USERINFO(state, userInfo) {
state.userInfo = userInfo;
}
};
export default new Vuex.Store({
state,
mutations
});
在main.js中引入store
import store from "./store/store";
new Vue({
router,
store,
render: h => h(App)
}).$mount("#app");
一般在組件中觸發(fā)mutations
// login.vue中
_this.$store.commit("SAVE_USERINFO",response.data[0])
在刷新頁面后要確保數(shù)據(jù)依然存在,則需要在拿到數(shù)據(jù)后將其存入本地存儲
localStorage.setItem('userInfo',JSON.stringify(response.data[0]));
上面做法任然會在刷新后數(shù)據(jù)沒有歉秫,采取以下做法:直接將數(shù)據(jù)提交到store的state中,然后在mutations 中先將數(shù)據(jù)存到本地存儲养铸,然后再更新數(shù)據(jù).
const state = {
userInfo: JSON.parse(localStorage.getItem("userInfo"))
};
const mutations = {
SAVE_USERINFO(state, userInfo) {
// 先將數(shù)據(jù)存到本地存儲
localStorage.setItem("userInfo", JSON.stringify(userInfo));
state.userInfo = userInfo;
}
};
在組件中獲取state有兩種方式(home.vue)
第一種在組件中直接拿
<span>{{$store.state.userInfo.username}}</span>
第二種通過計(jì)算屬性computed獲取store的數(shù)據(jù)
computed: {
username() {
return this.$store.state.userInfo.username;
}
}
- mapState輔助函數(shù)(推薦使用)
import {mapState} from "vuex";
computed:{
...mapState({
userinfo:state => state.userInfo;
})
}
actions處理異步操作
// store.js
// 1. 在state中添加userList存儲用戶列表的數(shù)據(jù)
const state = {
userInfo: JSON.parse(localStorage.getItem("userInfo")),
userList: []
};
// 2. 在mutations中添加獲取用戶列表的函數(shù)
const mutations = {
GET_USERLIST(state,userlist){
state.userList = userlist;
}
}
// 定義actions,異步的雁芙,主要是用來commit mutations,再有mutations來改變狀態(tài)state
const actions = {
GET_USERLIST({ commit }) {
return new Promise((resolve, reject) => {
// 此處的請求為異步操作 為了能拿到數(shù)據(jù)钞螟,就在外面包一層promise
axios.get("https://jsonplaceholder.typicode.com/users").then(res => {
// console.log("獲取用戶數(shù)據(jù)", res.data);
commit("GET_USERLIST", res.data);
resolve();
});
});
}
};
//main.js觸發(fā)actions測試數(shù)據(jù)獲取
store.dispatch("GET_USERLIST").then(() => {
console.log("獲取數(shù)據(jù):", store.state.userList);
});
在用戶列表組件里兔甘,可在生命周期鉤子函數(shù)里去獲取數(shù)據(jù)
// userlist.vue
created(){
this.$store.dispatch("GET_USERLIST").then(()=>{
const data = this.$store.state.userList;
this.tableData = data;
})
}
可以用輔助函數(shù)來簡化操作:
import {mapState,mapActions} from "vuex";
// mapState
created() {
this.$store.dispatch("GET_USERLIST").then(() => {
// const data = this.$store.state.userList;
// this.tableData = data;
this.tableData = this.userList;
});
},
computed:{
// ...mapState(["userList"])
...mapState({
userList:state => state.userList;
})
}
//mapActions
created(){
this.GET_USERLIST().then(() => {
this.tableData = this.userList;
})
},
methods:{
...mapActions(["GET_USERLIST"]);
}
Getter
有時候我們需要從 store 中的 state 中派生出一些狀態(tài),例如對列表進(jìn)行過濾并計(jì)數(shù).
Vuex在store中定義的getters可以認(rèn)為是store的計(jì)算屬性鳞滨,getters的返回值會根據(jù)它的依賴被緩存起來洞焙,且只有當(dāng)它的以來至發(fā)生改變才會被重新計(jì)算。
Getter接受state作為第一個參數(shù)拯啦,Getter會暴露為store.getters對象澡匪,你可以以屬性的形式訪問這些值。
你也可以通過讓 getter 返回一個函數(shù)褒链,來實(shí)現(xiàn)給 getter 傳參唁情。在你對 store 里的數(shù)組進(jìn)行查詢時非常有用。
getters:{
getTodoById:(state) => (id) => {
return state.todos.find(todo => todo.id === id);
}
}
注意甫匹,getter 在通過方法訪問時甸鸟,每次都會去進(jìn)行調(diào)用,而不會緩存結(jié)果兵迅。
輔助函數(shù)mapGetters
mapGetters 輔助函數(shù)僅僅是將store中的getter映射到局部計(jì)算屬性: