这是我参与11月更文挑战的12天,活动详情查看:2021最后一次更文挑战
Vue Router
创建一个 demo 项目。
? Please pick a preset: Manually select features
? Check the features needed for your project: Choose Vue version, Babel, Router, Linter
? Choose a version of Vue.js that you want to start the project with 3.x
? Use history mode for router? (Requires proper server setup for index fallback in production) No
? Pick a linter / formatter config: Basic
? Pick additional lint features: Lint on save
? Where do you prefer placing config for Babel, ESLint, etc.? In dedicated config files
? Save this as a preset for future projects? No
路由是指根据 url 的不同展示不同的效果。
main.js 中引入了 router:
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
createApp(App).use(router).mount('#app')
router/index.js:
import { createRouter, createWebHashHistory } from 'vue-router'
import Home from '../views/Home.vue'
const routes = [
{
path: '/', // 路径
name: 'Home', // 路由名
component: Home // 组件
},
{
path: '/about',
name: 'About',
// 异步加载路由 访问其他页面时不加载当前组件,只有访问当前组件时才加载
// 通过异步加载路由可以加快首页加载速度,但访问当前组件时会加载当前的组件
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
}
]
const router = createRouter({
history: createWebHashHistory(),
routes
})
export default router
该文件中引入了 Home 和 About 组件:
// views/Home.vue
<template>
<div class="home">
<img alt="Vue logo" src="../assets/logo.png" />
</div>
</template>
<script>
export default {
name: "Home",
};
</script>
// views/About.vue
<template>
<div class="about">
<h1>This is an about page</h1>
</div>
</template>
App.vue:
<template>
<div id="nav">
<!-- router-link 是跳转路由的标签 -->
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</div>
<!-- router-view 用来展示路由的组件 -->
<router-view />
</template>
<style>...</style>
<router-link> 自定义组件使得 Vue Router 可以在不重新加载页面的情况下更改 url ,处理 url 的生成以及编码。
<router-view> 将显示与 url 对应的组件。
Vuex
创建一个 demo 项目。
? Please pick a preset: Manually select features
? Check the features needed for your project: Choose Vue version, Babel, Router, Vuex, Linter
? Choose a version of Vue.js that you want to start the project with 3.x
? Use history mode for router? (Requires proper server setup for index fallback in production) No
? Pick a linter / formatter config: Basic
? Pick additional lint features: Lint on save
? Where do you prefer placing config for Babel, ESLint, etc.? In dedicated config files
? Save this as a preset for future projects? No
mian.js:
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
createApp(App).use(store).use(router).mount('#app')
store/index.js:
import { createStore } from 'vuex'
export default createStore({
state: {
},
mutations: {
},
actions: {
},
modules: {
}
})
Vuex 是一个数据管理框架,当项目变得复杂时,我们需要在页面之间传递数据,如果使用原来组件传递数据的方法,可维护性较差。Vuex 创建了一个全局唯一的仓库,用来存放全局的数据。
定义全局数据
// store/index.js
import { createStore } from 'vuex'
export default createStore({
state: {
name: 'Jack'
},
mutations: {
},
actions: {
},
modules: {
}
})
在首页中通过 this.$store.state 使用数据:
// views/Home.vue
<template>
<div class="home">
<img alt="Vue logo" src="../assets/logo.png" />
<h1>{{ myName }}</h1>
</div>
</template>
<script>
export default {
name: "Home",
computed: {
myName() {
return this.$store.state.name;
},
},
};
</script>
修改全局数据
修改全局数据有一定的流程。在代码中如下:
// views/Home.vue
<template>
<div class="home">
<img alt="Vue logo" src="../assets/logo.png" />
<h1 @click="handleClick">{{ myName }}</h1>
</div>
</template>
<script>
export default {
name: "Home",
computed: {
myName() {
return this.$store.state.name;
},
},
methods: {
handleClick() {
// 第一步,Vuex 需要派发一个名为 change(名称自定)的 action
this.$store.dispatch("change");
},
},
};
</script>
// store/index.js
import { createStore } from 'vuex'
export default createStore({
state: {
name: 'Jack'
},
mutations: {
// 第四步,对应的 mutation 被执行
change() {
// 第五步,在 mutation 中修改数据
this.state.name = 'Joe'
}
},
actions: {
// 第二步, store 感知到你触发了一个叫做 change 的 action,执行 change
change() {
// 第三步,commit 一个名为 change 的改变,触发一个 mutation
this.commit("change")
}
},
modules: {
}
})
mutation 里建议只写同步代码,不写异步代码。可以在 action 里写异步代码。
如果只进行同步操作,可以跳过 action:
// views/Home.vue
<script>
export default {
name: "Home",
computed: {
myName() {
return this.$store.state.name;
},
},
methods: {
handleClick() {
// 跳过第一步和第二步
this.$store.commit("change");
},
},
};
</script>
dispatch 和 commit 方法可以为事件传参:
// views/Home.vue
methods: {
handleClick() {
this.$store.commit("change", "Hello World");
},
},
// store/index.js
import { createStore } from 'vuex'
export default createStore({
state: {
name: 'Jack'
},
mutations: {
// 第一个参数是 state,可以代替 this.state
change(state, str) {
state.name = str
}
},
actions: {
// 第一个参数是 store,可以代替 this
change(store, str) {
store.commit("change", str)
}
},
modules: {
}
})
在组合式 API 中使用 Vuex
在 About 页面点击相应位置, 2s 后修改全局数据 name :
// views/Home.vue
<template>
<div class="home">
<img alt="Vue logo" src="../assets/logo.png" />
<h1>{{ name }}</h1>
</div>
</template>
<script>
// 从 vuex 中引入 useStore
import { useStore } from "vuex";
import { toRefs } from "vue";
export default {
name: "Home",
setup() {
const store = useStore();
const { name } = toRefs(store.state);
return {
name,
};
},
};
</script>
// views/About.vue
<template>
<div class="about">
<h1 @click="handleClick">Click here to change the name after 2s.</h1>
<h1>{{ name }}</h1>
</div>
</template>
<script>
import { useStore } from "vuex";
import { toRefs } from "vue";
export default {
name: "Home",
setup() {
const store = useStore();
const { name } = toRefs(store.state);
const handleClick = () => {
// 调用 dispatch
store.dispatch("getData");
};
return {
name,
handleClick,
};
},
};
</script>
// store/index.js
import { createStore } from 'vuex'
export default createStore({
state: {
name: 'Jack'
},
mutations: {
changeName(state, str) {
state.name = str
}
},
actions: {
getData(store) {
setTimeout(() => {
// 调用 commit
store.commit('changeName', 'Hello World')
}, 2000);
}
},
modules: {
}
})
发送 ajax 请求
使用 axios 发送 ajax 请求,运行 npm install axios --save安装 axios。
在 store/index.js 中发送请求:
// store/index.js
import { createStore } from 'vuex'
import axios from "axios";
export default createStore({
state: {
name: 'Jack'
},
mutations: {
changeName(state, str) {
state.name = str
}
},
actions: {
getData(store) {
axios.get("...")
.then((response) => {
const msg = response.data.message;
store.commit('changeName', msg)
});
}
},
modules: {
}
})