编辑
##download: 2022全面升级!Vue3 + TS 仿知乎专栏企业级项目
Vue3全家桶vue-router和vuex使用
引入router很简单,创建一个VueRouter的实例,最重要的两个参数一个就是路由模式,一个就是路由配置(见下),创建好以后,扔到Vue实例的配置中就行,最终路由的所有相关信息都会挂在this.router直接访问。
require('es6-promise').polyfill(); //es6 promise
require('isomorphic-fetch'); //fetch库
import Vue from 'vue';
import VueRouter from 'vue-router';
import routes from './route-config.js'; //路由配置
import store from './store/index.js'; //store
import App from './views/App.vue'; //页面容器
Vue.use(VueRouter); //vue使用veux,vue-router 都是通过Vue这个对象上的use这个方法。
//创建路由
const router = new VueRouter({
mode: 'hash', //路由的模式
routes
});
//将store, router加入并生成应用
new Vue({
el: '#application',
store,
router,
render: h => h(App)
});
src/route-config.js
路由配置也很简单,文档有详细的例子。如果应用过大,打包到一个js文件里有点不合适,我们可以在这里引入页面的时候做页面的懒加载,就是code spliting。懒加载例子
import HomePage from './views/HomePage.vue'; //引入页面
import CounterPage from './views/CounterPage.vue';
//当然真正应用的路由不会这么简单,vue-router也提供动态路由,嵌套路由等等,详见vue-router文档
export default [
{ path: '/', component: HomePage },
{ path: '/counter', component: CounterPage}
];
src/store/index.js
同使用vue-router一样,先调一下use方法,然后新建一个Store实例,把state,actions,getters,mutations全扔进去。
最终将store抛出,会被用在新建vue实例的时候。同样store的所有相关会挂在this.store直接访问。
import Vue from 'vue';
import Vuex from 'vuex';
import actions from './actions/index.js';
import mutations from './mutations/index.js';
import * as getters from './getters/index.js';
Vue.use(Vuex);
//state
const state = {
count: 0, //counter actions 操作的值
pageData: {} //fetch action 操作的值
};
//把上面的融到一起
export default new Vuex.Store({
state,
actions,
getters,
mutations
});
src/views/App.vue
Vue3完成自定义Form组件
父子组件
插槽的用法-slot
跨组件传值-provide
跨组件通信--mmit
自定义props
自定义事件
首先我们定义一个父级容器存放我们所有的组件
定义父级容器的props
···
props: {
model: {
type: Object,
},
rules: {
type: Object,
},
}
···
定义父级容器的方法
emits: ["finish"],
复制代码
定义父级容器的校验方法
setup(props, ctx) {
const formMapKey = {};
for (let k of Object.keys(props.rules)) {
formMapKey[k] = true;
}
const formState = reactive(formMapKey);
// formState.username = false;
const validated = computed(() => {
let res = true;
for (let k in formMapKey) {
res = res && formMapKey[k];
}
return res;
});
const validate = (k) => {
let rules = null;
let model = null;
if (k === "") {
rules = props.rules;
model = props.model;
} else {
rules = { [k]: props.rules[k] };
model = { [k]: props.model[k] };
}
const validator = new Schema(rules);
const handleErrors = (errors, fields) => {
VueEvent.emit("validate", fields);
const keySet = new Set(Object.keys(fields));
for (let k in formState) {
if (keySet.has(k)) {
formState[k] = false;
} else {
formState[k] = true;
}
}
};
validator
.validate(model)
.then(() => {
// 课堂作业,找出我的bug修改
// validation passed or without error message
VueEvent.emit("validate", { [k]: [] });
})
.catch(({ errors, fields }) => {
return handleErrors(errors, fields);
});
};
const submit = (e) => {
validate("");
ctx.emit("finish");
};
onMounted(() => {
VueEvent.on("check", (k) => {
validate(k);
});
});
return {
submit,
validated,
};
},
复制代码
定义yue-ma-edu-form-item用于承载输入组件
通过provider跨组件传输数据
provide("name", props.name);
自定义输入组件 yue-ma-edu-input
复制代码
通过 const name = inject("name");获取父级组件传输的数据
监听跨组件事件
VueEvent.on("validate", (res) => {
if (res[name] !== undefined) {
if (res[name].length > 0) {
const error = res[name].pop();
msg.value = error.message;
} else {
msg.value = "";
}
}
});
Vue3企业级项目总结
vue3 项目开发 get 到的知识
刚开始用的时候,可怀念 vue2 了,我始终 get 不到 vue3 的精华,也理解不了网上说的组合式API 有多好。vue2 我是轻车熟路,vue3 我是面向文档开发。选择了用 vue3,就要去 get 他的精华,用着用着我发现真香,vue3 和 vite2 结合的项目惊讶到我了。
组合式 API 解决了什么问题?
在开始写项目的时候,我一直没有 get 到组合 API 的有优点,还没有了全局的 this,我就有点不开心了,但是随着项目越来越复杂,页面越来越大的时候我就发现组合 API 真香。特别喜欢。
vue2 数据定义在 data,方法在 method,中间可能还有 watch,computed 等等别的东西,数据定义和方法处理逻辑之间差了十万八千里,当逻辑复杂达到一定长度的时候,追踪一个变量的变化是一件非常头痛的事情,鼠标需要来回滚动。
有了组合 api,这个问题就解决了。所有相关的都可以写在一块。真好,它带来了一种全新的开发方式。如果你是 React 开发用户或者熟悉 React,那么 vue3 上手很快,你甚至都可以在页面中使用 hooks 的方式开发。由于这个项目使用场景比较小,所以在项目中并没有进行采用 hooks 的方式,后续有需要的时候可以考虑使用。了解更多关于组合式 API 请参考文档什么是组合式 API?