欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

vue3+node(koa2)写一个网站-前端篇

程序员文章站 2022-03-21 11:30:01
采用vue-cli 4.5.0生成项目目录。新版本的脚手架生成的项目 main.js与之前旧版本略有不同,新版本如下://main.jsimport { createApp } from 'vue';import App from './App.vue';import router from './router';// 法一const app = createApp(App);app.use(router)app.mount('#app')//法二//createApp(App...

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;

 

本文地址:https://blog.csdn.net/weixin_41804429/article/details/108950088