项目分析六

一、文章详情——创建组件并配置路由

// 1.创建文件,src/views/article/index.vue



// 2.在src/router/index.vue中将文章详情页配置到一级路由
const routes = [
  .....
  {
    path: '/article/:articleId',
    name: 'article',
    component: () => import('@/views/article'),
    props: true,  // 动态路径参数的解耦:将路由动态参数映射到组件的 props 中,更推荐这种做法
  }
];
// 3.配置跳转路由,在src/components/article-item/index.vue中
// 4.页面布局




二、获取文章数据

// 1.封装请求,在src/api/article.js中
export const getArticleById = (articleId) => {
  return request({
    method: 'GET',
    url: `/v1_0/articles/${articleId}`,
  })
};
// 2.获取文章信息,在src/views/article/index.vue中
// 2.1.导入请求方法
import { getArticleById } from '@/api/article'

export default {
  name: 'ArticlePage',
  components: {},
  props: {
    articleId: {
      type: String,
      required: true
    }
  },
  data () {
    return {
       article: {} // 2.2.定义变量来储存数据
    }
  },
  computed: {},
  watch: {},
  created () {
    // 2.4. 调用方法  
    this.loadArticle()
  },
  mounted () {},
  methods: {
    // 2.3. 定义获取数据请求方法  
    async loadArticle () {
      try {
        // 2.3.1 发送请求  
        const { data } = await getArticleById(this.articleId)
        console.log(data) 
        // 2.3.3 成功赋值
        this.article = data.data
        console.log(this.article) 
      } catch (err) {
        // 2.3.2 失败处理  
        console.log(err)
        this.$toast("获取数据失败");
      }
    }
  }
}
// 3.渲染数据到页面

{{ article.title }}

三、处理加载情况

// 1. 在src/views/article/index.vue中的data中定义变量

  data() {
    return {
      ...
      loading: true, // 加载中的 loading 状态
      errStatus: 0, // 失败的状态码
    };
  },
// 2.在src/views/article/index.vue中
async loadArticle () {
      // 2.1 展示 loading 加载中
      this.loading = true
      try {
        const { data } = await getArticleById(this.articleId)

        // if (Math.random() > 0.5) {
        //   JSON.parse('dsankljdnskaljndlkjsa')
        // }

        // 赋值
        this.article = data.data

      } catch (err) {
        if (err.response && err.response.status === 404) {
          this.errStatus = 404
        }
      }
      // 2.2无论成功还是失败,都需要关闭 loading
      this.loading = false
    },
// 3.在在src/views/article/index.vue中判断

...
...
...
...

四、处理内容的样式

// 1. 将github-markdown-css样式文件放到src/views/article中,与index.vue同级

// 2.在src/views/article/index.vue中引用


// 3.添加到标签中
 
 
正文结束
// 4.postcss.config.js文件中添加忽略
module.exports = {
  plugins: {
    
      ....
      propList: ['*'],
      // 配置不要转换的样式资源
      exclude: 'github-markdown'  // 添加忽略文件
    }
  }
}

// 5.注意,一定要重启项目,否则不会起作用

五、点击图片预览

// 1. 使用vant组件库中的 ImagePreview 图片预览 组件

// 2. 增加ref属性, 在src/views/article/index.vue中
// 3.导入ImagePreview 图片预览 组件插件,在src/views/article/index.vue中 import { ImagePreview } from 'vant' // 4. methods: { async loadArticle() { this.loading = true; try { const { data } = await getArticleById(this.articleId); // console.log(data); data.data.content = data.data.content.replaceAll('https://images.weserv.nl/?url=','') this.article = data.data; // 初始化图片点击预览 console.log(this.$refs["article-content"]); // 这里没有内容 // 这个时候其实找不到 这个refs引用的,原因是因为v-if的渲染其实需要时间,我们视图还没有立即更新完成。 // 使用定时器,延迟更新( setTimeout 0 会把要做的事情放在异步队列的最后面执行! ) setTimeout(() => { console.log(this.$refs["article-content"]); // 这里有内容 this.previewImage(); }, 0); } catch (err) { // this.$toast("获取数据失败"); if (err.response && err.response.status === 404) { this.errStatus = 404; } } this.loading = false; }, previewImage() { // 得到所有的 img 节点 const articleContent = this.$refs["article-content"]; // 获取到了容器节点 const imgs = articleContent.querySelectorAll("img"); // 获取所有 img 地址 const images = []; imgs.forEach((img, index) => { images.push(img.src); // 给每个 img 注册点击事件,在处理函数中调用预览 img.onclick = () => { ImagePreview({ // 预览的图片地址数组 images, // 起始位置,从 0 开始 startPosition: index, }); }; }); }, },

你可能感兴趣的:(vue.js)