前端有道 前端有道
导航
算法
开发
  • Git

    • Git导读
  • 收藏夹 (opens new window)
  • 工具库 (opens new window)
  • netlify Vuepress (opens new window)
  • vercel Vuepress (opens new window)
  • Vuepress2.0 (opens new window)
  • netlify Vuepress2.0 (opens new window)
留言区
娱乐
关于
  • 时间轴
  • 标签
  • 分类

星野

给岁月以文明
导航
算法
开发
  • Git

    • Git导读
  • 收藏夹 (opens new window)
  • 工具库 (opens new window)
  • netlify Vuepress (opens new window)
  • vercel Vuepress (opens new window)
  • Vuepress2.0 (opens new window)
  • netlify Vuepress2.0 (opens new window)
留言区
娱乐
关于
  • 时间轴
  • 标签
  • 分类
  • 基础知识

  • 工程化

  • 组件库

  • CSS

  • ES6-ES12

  • JavaScript

  • Vue2

  • Vue3

    • Vue3开发知乎日报
      • 项目界面
      • 前言
      • 个人建议
      • 项目实战
        • 初始化项目
        • 静态页面
        • 项目结构
        • 项目 Vue3.0 API 知识点
      • 实战
        • 时间处理
        • 请求接口
        • 初始化轮播图
        • 详情页的功能
      • 完整的项目
        • 总结
    • Vue3入门
  • webpack

  • 浏览器

  • 开发
  • Vue3
星野
2022-01-14
0
目录

Vue3开发知乎日报

# Vue3 beta 开发知乎日报

vue

# 项目界面

一个简单的小项目,基于Vue3.0 + axios + swiper实现。让大家对 Vue3.0 API 有一些新的认识。

zhihu

# 前言

Vue3.0 个人觉得学习挺容易的,Vue2.0 水平怎么样,Vue3.0 也就差不多那样,所以 Vue2.0 学的不太好的同学还是回去补一补,现阶段急于学习 Vue3.0 反而容易造成知识混淆。很多写法和 Vue2.0 相似,学习成本不高,但是很多底层东西进行的重构,所以目前不建议直接使用在公司项目上。

# 个人建议

目前 Vue3.0 开发版接近尾声,预计下个月就上线稳定版,存在以下问题,不建议在公司项目直接使用,估计还的等一段时间吧。

  • "vue-router": "^4.0.0-alpha.6" 还在开发中。这个阶段还未定型,今天解决的 BUG 可能明天就是另外的 Bug。
  • 第三方库还未兼容到 Vue3.0 意想不到的兼容性等问题。
  • Vue3.0 API 部分功能还未完善,Vue2.0 和 Vue3.0 去实现。
  • 遇到技术难点,需要花大把时间去琢磨。一些问题涉及基础的东西,底子不牢,也能难查出问题所在。

综上所述,用在公司项目上,估计得折腾得够呛,或者未能按时间开发完成,产品问题多还会被扣奖金绩效等,吃力不讨好。

但是做为先行者去学习和开发项目,收益颇丰,更加能体会 Vue 开发者如何去架构和设计思想所在。

# 项目实战

Vue 3.0 在兼容 2.x 基础上做改进。且能使用 Vue 3.0 新特性。

# 初始化项目

1、安装 vue-cli3

npm install -g @vue/cli

2、创建项目

vue create zhihu

Vue CLI v4.4.6
? Please pick a preset:
  default (babel, eslint)
> Manually select features

babel:javascript转译器,将最新版的js语法(es6、es7)转换为现阶段浏览器可以兼容的js代码
typescript:使用 TypeScript 书写源码
PWA:渐进式WEB应用
Router:使用vue-router
Vuex:使用vuex
CSS Pre-processors:css预处理器
Linter / Formatter:代码规范标准
Unit Testing:单元测试
E2E Testing:e2e测试

? Please pick a preset: Manually select features
? Check the features needed for your project:
 (*) Babel
 ( ) TypeScript
 ( ) Progressive Web App (PWA) Support
 (*) Router
 ( ) Vuex
>(*) CSS Pre-processors
 ( ) Linter / Formatter
 ( ) Unit Testing
 ( ) E2E Testing

3、Vue 版本升级

vue add vue-next
// 将Vue 2.6.x版本升级到

查看项目package.json

  "dependencies": {
     "vue": "^3.0.0-beta.1",
     "vue-router": "^4.0.0-alpha.6"
    },
    "devDependencies": {
    "@vue/cli-plugin-babel": "~4.4.0",
    "@vue/cli-plugin-eslint": "~4.4.0",
    "@vue/cli-plugin-router": "~4.4.0",
    "@vue/cli-service": "~4.4.0",
    "@vue/compiler-sfc": "^3.0.0-beta.1",
    "@vue/eslint-config-prettier": "^6.0.0",
    "babel-eslint": "^10.1.0",
    "eslint": "^6.7.2",
    "eslint-plugin-prettier": "^3.1.3",
    "eslint-plugin-vue": "^7.0.0-alpha.0",
    "less": "^3.0.4",
    "less-loader": "^5.0.0",
    "prettier": "^1.19.1",
    "vue-cli-plugin-vue-next": "~0.1.3"
  },

vue-router 还在开发中,vue-cli-plugin-vue-next 用来处理 Vue3.0 编译相关语法。

# 静态页面

项目布局,静态页面,略过

# 项目结构

.
├── src
│   ├── api
│   ├── assets
│   ├── components
│   ├── router
│   ├── utils
│   ├── views
│   ├── App.vue
│   └── main.js
├── public
├── vue.config.js
└── package.json
  • src/api: 用于存放接口和管理。
  • src/assets: 静态资源目录。
  • src/components: 用于存放全局组件。
  • src/router: 用于存放路由相关的文件。
  • src/utils: 用于存放工具类相关的文件
  • src/views: 用于存放视图相关组件。

# 项目 Vue3.0 API 知识点

# setup

setup 函数是一个新的组件选项。作为在组件内使用 Composition API 的入口点。

生命周期

创建组件实例,然后初始化 props ,紧接着就调用 setup 函数。从生命周期钩子的视角来看,它会在 beforeCreate 钩子之前被调用。

注意事项:

this 不能使用,了解 Vue2.0 的同学应该知道,在这生命周期之间。data()数据还未生成,所以 this.xx不能调用的。

# 响应式数据

Vue2.0 存放在data() {return {} } 就可以直接调用,而 Vue3.0 则需要通过ref或者reactive 来声明响应式数据。

ref

接受一个参数值并返回一个响应式且可改变的 ref 对象。ref 对象拥有一个指向内部值的单一属性 .value。

const count = ref(0)
console.log(count.value) // 0

count.value++
console.log(count.value) // 1

如果传入 ref 的是一个对象,将调用 reactive 方法进行深层响应转换。

reactive

接收一个普通对象然后返回该普通对象的响应式代理。

const obj = reactive({ count: 0 })

# 计算属性 computed

computed 传入一个 getter 函数,返回一个默认不可手动修改的 ref 对象。

const count = ref(1)
const plusOne = computed(() => count.value + 1)

console.log(plusOne.value) // 2

# watch

watch 需要侦听特定的数据源,并在回调函数中执行副作用。

const count = ref(0)
watch(count, (count, prevCount) => {
  /* ... */
})

以上教程皆来自 Vue 组合式 API (opens new window)

# 实战

项目如果太抠细节的去讲,不知道从何说起,以下主要分为几个功能阐述这个项目。想了解项目更多细节,可以克隆我的项目,运行调试。

# 时间处理

src/utils/index.js

function formatTime(time) {
  let arr = [];
  time = time.toLocaleDateString();
  time.replace(/\d+/g, (val) => {
    val = val < 2 ? `0${val}` : val;
    arr.push(val);
  });
  return arr;
}
function convertTime(time) {
  time = time.replace(/^(\d{4})(\d{2})(\d{2})$/g,(_,g1,g2,g3)=>{
    return `${g1}/${g2}/${g3}`
  })
  return new Date(time);
}

export default {
  formatTime,
  convertTime,
};

formatTime()中的参数time为new Date()的标准日期格式,然后通过toLocaleDateString()转成2020/7/21,在依次添加到数组里面。

在不同环境下,输出不同结果。`toLocaleDateString`
 // 浏览器
["2020", "7", "21"]

// [Running] node
[ '7', '21', '2020']

convertTime方法:将格式20200721转成2020/07/21的正则表达式。

应用

import utils from "../utils";

const state = reactive({
  date: new Date(),
  bannerData: [],
  newsData: []
});

let day = computed(() => utils.formatTime(state.date)[2]);
let month = computed(() => utils.formatTime(state.date)[1]);

return {
 day,
 month
};

通过计算属性,计算出几月份和几日。写法不像 Vue2.0 直接包裹在computed里面。

# 请求接口

src/api/目录下的axios.js 对axios进行二次封装,zhihu.js相关的知乎日报接口。 index.js对多个接口进行整合。

// zhihu.js
import axios from './axios'

function API_LATEST(){
  return axios.get('/news/latest')
}
function API_DETAIL(id){
  return axios.get(`/news/${id}`)
}

export default {
  API_LATEST,
  API_DETAIL
}

// index.js
import zhihu from './zhihu'
export default { zhihu }

应用

import API from "../api";

export default {
  setup() {
    const state = reactive({
      bannerData: [],
      newsData: []
    });
     // 在渲染组件前,异步加载数据
    onBeforeMount(async () => {
      const { date, stories, top_stories } = await API.zhihu.API_LATEST();
      state.date = utils.convertTime(date);
      state.newsData.push({
        date: state.date,
        stories
      });
      state.bannerData = top_stories;
    });
    return {
      ...toRefs(state)
    };
  }

# 初始化轮播图

import { watch } from "vue";
function initSwiper() {
  new Swiper(".swiper-container", {
    loop: true,
    pagination: {
      el: ".swiper-pagination"
    }
  });
}
setup(props) {
 watch(
   () => props.bannerData,
   () => initSwiper()
 );
}

注意点:当获取轮播图的数据赋值到state上,此时数据还未渲染到组件上。

解决方法:

  • Vue2.0调用 Vue.nextTick API(在下次 DOM 更新循环结束之后执行延迟回调。)去执行初始化。
  • Vue3.0 通过watch 去监听数据改变,在执行初始化。

# 详情页的功能

点击列表详情页时候,需要携带一个文章的 ID 过去,去请求详情接口获取更多内容。 如果我上面说的setup()方法有印象的话,在setup()中不能调用this。 习惯了Vue2.0跳转方式this.$router.push({name: 'detail',params:{id: xx}}) Vue3.0 突然不知如何下手,好在 Vue2.0 还提供组件式跳转。

<router-link :to="{path:`/detail/${item.id}`}" </router-link>

获取路由的参数

Vue3.0 路由还在开发中,暂时还未能获取路由的参数 API,只能先用 Vue2.0 写法先代替了。

难点:如何在 Vue2.0 中修改 Vue3.0 的值,且还能被watch监听到。

解决方法:

直接用 Vue2.0 中实现功能。(嗯,我这是 Vue3.0 教程当然得用 Vue3.0 去实现咯)

我在 Vue3.0 中,我先声明了响应式数据,通过 Vue2.0 获取路由参数后,尝试this.id = xx 打印下log,输出 this 对象如下,功能实现了。

-w388

然而reactive的方式去声明响应式数据,其他不变,发现并能查到id。深入之后了解到ref和 Vue2.0 的data( return {} )底层原理都是基于Object.definedproperty实现,所以可以通过 this 去修改。reactive则式Prxoy实现的。还有 ref 中包裹是个对象话,也会通过Prxoy实现。

import { watch, toRefs, ref, reactive } from 'vue'
import API from '../api'
export default {
    setup() {
        let id = ref(0)
        let state = reactive({
            image: '',
            body: '',
            title: '',
            section: ''
        })
        watch(id, async () => {
            let { image, body, title, section } = await API.zhihu.API_DETAIL(id.value)
            state.image = image
            state.body = body
            ;(state.title = title), (state.section = section ? section.name : '佚名')
        })
        return {
            id,
            ...toRefs(state)
        }
    },
    beforeMount() {
        let { id } = this.$route.params
        this.id = id
    }
}

# 完整的项目

知乎日报 (opens new window)

# 总结

Vue3.0 实现知乎日报个人感觉还是不错,新写法或多或少有些不习惯,比如有个toRef少写 s,调试了半天也没报错,好在后面注意到了。多写几次后就会习惯,对比 Vue3.0 的各方面提升,一些写法的变化,无可厚非。所以还是尽快去熟悉 Vue3.0 的知识,等 UI 库等兼容 Vue3.0 版本上线就正式使用了。相信这一天很快来临。

参考链接:

  • http://www.javascriptpeixun.cn/course/1435/task/117818/show
上次更新: 2022/05/09, 06:48:29
Vue父子组件的生命周期
Vue3入门

← Vue父子组件的生命周期 Vue3入门→

最近更新
01
图解Git
05-10
02
关于 - 网站错误反馈
05-10
03
关于 - 赞赏❤️的用途
05-10
更多文章>
加入前端有道交流群 | Copyright © 2018-2025 星野 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式