vue 3文档
采用vue-cli 4.5.0生成项目目录。项目中采用vue3的新语法来写代码,当然你还是用原来的vue 2.x语法也不会有问题。
新版本的脚手架生成的项目 main.js与之前旧版本略有不同,新版本如下:
//main.js import { createApp } from 'vue'; import App from './App.vue'; import router from './router'; // 法一 const app = createApp(App); app.use(router) app.mount('#app') //法二 //createApp(App).use(router).mount('#app')新版本中路由的使用方式也不太一样:
// router/index.js import { createRouter, createWebHashHistory } from 'vue-router'; import Home from '@/views/Home' const router = createRouter({ history: createWebHashHistory(), routes: [ { path: '', redirect: '/home' }, { path: '/home', name: 'home', component: Home } ] }); export default router; //页面中监听路由和使用路由的变化 import { watch } from "vue"; import { useRoute, useRouter } from "vue-router"; export default { name: "my-header", setup() { const route = useRoute(); const router = useRouter(); const activeRoute = ref(""); watch( () => route.path, (curPath) => { activeRoute.value = curPath; } ) function toPage(path) { router.push(path); } return { activeRoute, toPage }; } };vue3一个比较大的亮点就是composition api, 之前选项的写法只能数据写一块,处理逻辑写一块,维护起来效率不高。现在通过新语法,某个功能的数据和逻辑能封装到一块 维护性、复用性得到大大提高。 别说 用起来还真香。
// blog.js //获取博客相关的数据和逻辑封装到一起 import { ref } from "vue"; import { getBlogList } from "@/api/blog"; import { formatTime } from "@/utils"; export function getBlogListLogic() { const blogList = ref([]); async function getBlog(keyword) { const { data: { data, errno } } = await getBlogList({ keyword: keyword && keyword.value }); if (errno === 0) { data.forEach(item => { item.createtime = formatTime(item.createtime); }); blogList.value = data; } } return { blogList, getBlog }; } //页面中使用示例 import { ref, onMounted } from "vue"; import { useRouter } from "vue-router"; import { getBlogListLogic } from "@/common/blog"; export default { name: "Home", setup() { const keyword = ref(""); const router = useRouter(); const { blogList, getBlog } = getBlogListLogic(); function onSearch(key) { keyword.value = key; getBlog(keyword); } function toDetail(blog) { router.push({ path: "/blog/detail", query: { id: blog.id } }); } onMounted(() => { getBlog(); }); return { blogList, keyword, onSearch, toDetail }; } };有时候我们需要通过ref来获取元素或自定义组件的引用,在vue3语法中使用方式也不太一样了。
//xxx.vue <template> <div class="content-wrap"> <quill-editor :ref="q => quill = q" :value="postData.content" ></quill-editor> </div> </template> <script> import QuillEditor from "@/components/QuillEditor"; import { ref, reactive } from "vue"; export default { name: "handleblog", components: { QuillEditor }, setup() { const quill = ref(null); const postData = reactive({ description: "", title: "", content: "" }); async function onSaveClick() { //通过ref调用quill-eidtor组件中的getContent方法 postData.content = quill.value.getContent(); } return { quill, postData, onSaveClick }; } }; </script>setup函数也接受两个参数 props 和 context。 props是响应式的,context是普通的js对象包含3个属性 attrs, slots, emit。
export default { setup(props, context) { ... } } export default { setup(props, { attrs, slots, emit }) { //向外触发事件 emit('change') } }登录的处理。有些页面我门需要登录后才让访问,可以在路由导航守卫进行拦截判断是否登录,如果需要登录权限但没登录就去登录。接口报401的时候让跳转到登录页。
//router/index.js router.beforeEach((to, from, next) => { //因为如果登录了,服务端代码会加上cookie,所以可以通过有没有cookies来判断是否已登录 if (to.meta.needLogin && !getCookie('koa.sid')) { next('/login') } else { next() } }) //axios封装处 import Axios from 'axios'; import router from '@/router/index'; import { message } from 'ant-design-vue'; const fetch = Axios.create({ baseURL: '' }); fetch.interceptors.request.use(function (config) { return config; }, function (error) { return Promise.reject(error); }); // 添加响应拦截器 fetch.interceptors.response.use(function (response) { return response; }, function (error) { const { status, data } = error.response; switch (status) { case 401: message.warn(data.message) router.push('/login'); break; default: message.error(data.message) return Promise.reject(data); } }); export default fetch;