新闻头条案例

  1. 1. 一:Vue文件
    1. 1.0.0.1. vue.config.js
    2. 1.0.0.2. App.vue
    3. 1.0.0.3. TopNews.vue
    4. 1.0.0.4. TypeNews.vue
    5. 1.0.0.5. NewsList.vue
  • 2. 二、setup语法糖
    1. 2.0.0.1. vue.config.js
    2. 2.0.0.2. App.vue
    3. 2.0.0.3. TopNews.vue
    4. 2.0.0.4. TypeNews.vue
    5. 2.0.0.5. NewsList.vue

  • 一:Vue文件

    vue.config.js
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    const { defineConfig } = require('@vue/cli-service')
    module.exports = defineConfig({
    transpileDependencies: true,
    devServer: {
    port: 8080,
    proxy: {
    '/juheNews': {
    // target: 'http://api.tianapi.com', //需要跨域的url
    target: 'http://v.juhe.cn',
    ws: true, //代理webSocket
    changeOrigin: true, //允许跨域
    pathRewrite: {
    '^/juheNews':'' //重写路径
    }
    }
    }
    }
    })

    注: target: ‘http://v.juhe.cn', 地址

    App.vue
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    <template>
    <div id="app">
    <header>新闻头条</header>
    <nav>
    <ul>
    <li
    :class="{ navinit: isActive == 'topNews' }"
    @click="changeNav('topNews')"
    >
    头条新闻
    </li>
    <li
    :class="{ navinit: isActive == 'typeNews' }"
    @click="changeNav('typeNews')"
    >
    分类新闻
    </li>
    </ul>
    </nav>
    <router-view />
    </div>
    </template>

    <script>
    import { reactive, toRefs } from "vue";
    import { useRouter } from "vue-router";

    export default {
    setup() {
    //初始化路由组件
    const router = useRouter();
    const state = reactive({
    isActive: "topNews",
    });

    const path = location.href.substring(location.href.lastIndexOf("/") + 1);
    state.isActive = path == "" ? "topNews" : path;

    function changeNav(param) {
    state.isActive = param;
    if (param == "topNews") {
    router.push("/topNews");
    } else if (param == "typeNews") {
    router.push("/typeNews");
    }
    }

    return {
    ...toRefs(state),
    changeNav,
    };
    },
    };
    </script>

    <style>
    /******************** css reset ********************/
    html,
    body,
    div,
    header,
    nav,
    h1,
    h2,
    h3,
    h4,
    h5,
    h6,
    ul,
    li {
    margin: 0;
    padding: 0;
    font-family: "微软雅黑";
    }
    ul {
    list-style: none;
    }
    a {
    text-decoration: none;
    }

    header {
    width: 100%;
    height: 48px;
    background-color: #e03d3e;

    display: flex;
    justify-content: center;
    align-items: center;

    font-size: 20px;
    color: #fff;
    /*设置字间距*/
    letter-spacing: 4px;
    }
    nav {
    width: 100%;
    height: 56px;
    display: flex;
    justify-content: center;
    align-items: center;
    }
    nav ul {
    width: 160px;
    height: 26px;

    display: flex;
    justify-content: space-between;
    }
    nav ul li {
    width: 70px;
    height: 26px;

    display: flex;
    justify-content: center;
    align-items: center;
    }
    .navinit {
    color: #e03d3e;
    border-bottom: solid 2px #e03d3e;
    }
    </style>
    TopNews.vue
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    <template>
    <div>
    <img src="../assets/6.png" />
    <NewsList :data="newsList"></NewsList>
    </div>
    </template>

    <script>
    import { reactive, toRefs } from "vue";
    import NewsList from "@/components/NewsList";
    import axios from "axios";

    export default {
    setup() {
    const state = reactive({
    newsList: [],
    });

    const init = () => {
    axios
    .get("/juheNews/toutiao/index", {
    params: {
    key: "你的key",
    type: "top",
    page_size: 5,
    },})
    .then((response) => {
    console.log(response)
    state.newsList = response.data.result.data;
    })
    .catch((error) => {
    console.log(error);
    });
    };

    init();

    return {
    ...toRefs(state),
    };
    },
    components: {
    NewsList,
    },
    };
    </script>

    <style scoped>
    img {
    width: 100%;
    height: 250px;
    display: block;
    }
    </style>
    TypeNews.vue
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    <template>
    <div>
    <div class="news-img">
    <a :href="news.url">
    <img :src="news.thumbnail_pic_s" />
    </a>
    </div>
    <div class="type-news">
    <ul>
    <li
    v-for="item in typeList"
    :key="item.id"
    :class="{ typeinit: isAlive == item.id }"
    @click="change(item.id)"
    >
    {{ item.name }}
    </li>
    </ul>
    </div>
    <NewsList :data="newsList"></NewsList>
    </div>
    </template>

    <script>
    import axios from 'axios'
    import {reactive, toRefs} from "vue";
    import NewsList from "@/components/NewsList";
    export default {
    name: "TypeNews",
    setup() {
    const state = reactive({
    typeList: [
    { id: "guonei", name: "国内" },
    { id: "guoji", name: "国际" },
    { id: "yule", name: "娱乐" },
    { id: "tiyu", name: "体育" },
    { id: "junshi", name: "军事" },
    { id: "keji", name: "科技" },
    { id: "caijing", name: "财经" },
    { id: "youxi", name: "游戏" },
    { id: "qiche", name: "汽车" },
    { id: "jiankang", name: "健康" },
    ],
    isAlive: "guonei",
    newsList: [],
    news: {},
    });

    getNews("guonei");

    function getNews(type) {
    axios.get("/juheNews/toutiao/index", {
    params: {
    type: type,
    key: '你的key',
    page_size: 5,
    },
    }).then((resp=>{
    state.newsList = resp.data.result.data;
    state.news =
    state.newsList[Math.floor(Math.random() * state.newsList.length)];
    })).catch((error=>{
    console.log(error)
    }))
    }

    function change(id) {
    state.isAlive = id;
    getNews(id);
    }

    return {
    ...toRefs(state), change,
    };
    },
    components: {
    NewsList
    }

    }
    </script>

    <style scoped>
    .news-img img {
    width: 100%;
    height: 200px;
    display: block;
    }
    .type-news {
    width: 100%;
    margin-top: 8px;
    }
    .type-news ul {
    width: 100%;

    display: flex;
    justify-content: center;
    flex-wrap: wrap;
    }
    .type-news ul li {
    box-sizing: border-box;
    width: 48px;
    height: 22px;
    border: solid 1px #e03d3e;
    border-radius: 11px;
    margin: 5px 10px;

    font-size: 14px;
    color: #e03d3e;

    display: flex;
    justify-content: center;
    align-items: center;
    }

    .typeinit {
    background-color: #e03d3e;
    color: #fff !important; /*!important:将优先级提升最高*/
    }
    </style>
    NewsList.vue
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    <template>
    <div>
    <ul>
    <li
    v-for="item in newsArr"
    @click="toNews(item.url)"
    :key="item.uniquekey"
    >
    <div class="img-box">
    <img :src="item.thumbnail_pic_s" />
    </div>
    <div class="text-box">
    <h3>{{ item.title }}</h3>
    <p>{{ item.author_name }} {{ item.date }}</p>
    </div>
    </li>
    </ul>
    </div>
    </template>

    <script>
    import { reactive, toRefs, computed } from "vue";

    export default {
    props: {
    data: Array,
    },
    setup(props) {
    const state = reactive({
    //将父组件传过来的数据中的title进行在加工处理
    newsArr: computed(() => {
    let arr = props.data;
    for (let i = 0; i < arr.length; i++) {
    if (arr[i].title.length > 24) {
    arr[i].title = arr[i].title.substr(0, 24) + "...";
    }
    }
    return arr;
    }),
    });

    function toNews(url) {
    location.href = url;
    }

    return {
    ...toRefs(state),
    toNews,
    };
    },
    };
    </script>

    <style scoped>
    ul {
    width: 100%;
    }
    ul li {
    box-sizing: border-box;
    padding: 6px;
    width: 100%;
    height: 93px;

    display: flex;
    border-bottom: dashed 1px #aaa;

    user-select: none;
    cursor: pointer;
    }
    ul li .img-box {
    flex: 0 0 100px;
    height: 80px;
    }
    ul li .img-box img {
    width: 100px;
    height: 80px;
    }
    ul li .text-box {
    flex: 1;
    box-sizing: border-box;
    padding-left: 10px;
    }
    ul li .text-box h3 {
    font-size: 16px;
    font-weight: 300;
    }
    ul li .text-box p {
    font-size: 14px;
    text-align: right;
    }
    </style>

    二、setup语法糖

    vue.config.js
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    const { defineConfig } = require('@vue/cli-service')

    module.exports = defineConfig({
    transpileDependencies: true,
    devServer: {
    port: 8080,
    proxy: {
    '/juheNews': {
    // target: 'http://api.tianapi.com', //需要跨域的url
    target: 'http://v.juhe.cn',
    ws: true, //代理webSocket
    changeOrigin: true, //允许跨域
    pathRewrite: {
    '^/juheNews':'' //重写路径
    }
    }
    }
    }

    }
    )
    App.vue
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    <template>
    <div id="app">
    <header>新闻头条</header>
    <nav>
    <ul>
    <li :class="{navinit: isActive=='topNews'}" @click="changeNav('topNews')">
    头条新闻
    </li>
    <li :class="{navinit: isActive=='typeNews'}" @click="changeNav('typeNews')">
    分类新闻
    </li>
    </ul>
    </nav>
    <router-view></router-view>
    </div>
    </template>

    <script setup>
    import {ref} from "vue";
    import {useRouter} from "vue-router";

    const router = useRouter();
    const isActive = ref("topNews");
    const path = location.href.substring(location.href.lastIndexOf('/')+1);
    isActive.value = path == ""?"topNews": path;

    const changeNav = (param) => {
    isActive.value = param;
    if (param=="topNews") {
    router.push("/topNews")
    } else if (param== "typeNews") {
    router.push("/typeNews")
    }
    };


    </script>

    <style>
    /******************** css reset ********************/
    html,
    body,
    div,
    header,
    nav,
    h1,
    h2,
    h3,
    h4,
    h5,
    h6,
    ul,
    li {
    margin: 0;
    padding: 0;
    font-family: "微软雅黑";
    }
    ul {
    list-style: none;
    }
    a {
    text-decoration: none;
    }

    header {
    width: 100%;
    height: 48px;
    background-color: #e03d3e;

    display: flex;
    justify-content: center;
    align-items: center;

    font-size: 20px;
    color: #fff;
    /*设置字间距*/
    letter-spacing: 4px;
    }
    nav {
    width: 100%;
    height: 56px;
    display: flex;
    justify-content: center;
    align-items: center;
    }
    nav ul {
    width: 360px;
    height: 26px;
    display: flex;
    justify-content: space-between;
    }
    nav ul li {
    width: 70px;
    height: 26px;
    display: flex;
    justify-content: center;
    align-items: center;
    }
    .navinit {
    color: #e03d3e;
    border-bottom: solid 2px #e03d3e;
    }
    </style>
    TopNews.vue
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    <template>
    <div>
    <img src="../assets/carousel/star3.jpg" />
    <NewsList :data="state.newsList"></NewsList>
    </div>
    </template>

    <script setup>
    import axios from "axios";
    import {reactive} from "vue";
    import NewsList from "@/components/NewsList";

    name: "TopNews";

    const typeList = [
    { id: "guonei", name: "国内" },
    { id: "guoji", name: "国际" },
    { id: "yule", name: "娱乐" },
    { id: "tiyu", name: "体育" },
    { id: "junshi", name: "军事" },
    { id: "keji", name: "科技" },
    { id: "caijing", name: "财经" },
    { id: "youxi", name: "游戏" },
    { id: "qiche", name: "汽车" },
    { id: "jiankang", name: "健康" },
    ];

    const state = reactive({
    newsList: []
    });

    axios
    .get("/juheNews/toutiao/index", {
    params: {
    key: "你的key",
    type: "top",
    page_size: 10,
    }
    })
    .then((response) => {
    console.log(response)
    state.newsList = response.data.result.data;
    })
    .catch((error) => {
    console.log(error);
    });


    </script>

    <style scoped>
    img {
    width: 100%;
    height: 200px;
    display: block;
    justify-content: center;

    }
    </style>
    TypeNews.vue
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    <template>
    <div>
    <div class="news-img">
    <a :href="news.url">
    <img :src="news.thumbnail_pic_s" />
    </a>
    </div>
    <div class="type-news">
    <ul>
    <li
    v-for="item in typeList"
    :key="item.id"
    :class="{ typeinit: isAlive == item.id }"
    @click="change(item.id)"
    >
    {{ item.name }}
    </li>
    </ul>
    </div>
    <NewsList :data="state.newsList"></NewsList>
    </div>
    </template>

    <script setup>
    import axios from 'axios';
    import {reactive, ref} from "vue";
    import NewsList from "@/components/NewsList";

    name: "TypeNews";

    const typeList = [
    { id: "guonei", name: "国内" },
    { id: "guoji", name: "国际" },
    { id: "yule", name: "娱乐" },
    { id: "tiyu", name: "体育" },
    { id: "junshi", name: "军事" },
    { id: "keji", name: "科技" },
    { id: "caijing", name: "财经" },
    { id: "youxi", name: "游戏" },
    { id: "qiche", name: "汽车" },
    { id: "jiankang", name: "健康" },
    ];

    const isAlive = ref("guonei");
    const state = reactive({
    newsList: []
    });
    const news = ref({});

    const getNews = (type) => {
    axios
    .get("/juheNews/toutiao/index", {
    params: {
    type: type,
    key: "你的key",
    },
    })
    .then((response) => {
    state.newsList = response.data.result.data;
    news.value = state.newsList[Math.floor(Math.random() * state.newsList.length)];
    })
    .catch((error) => {
    console.log(error);
    });
    }

    getNews("guonei");

    const change = (id)=> {
    isAlive.value = id;
    getNews(id)
    }

    </script>

    <style scoped>
    .news-img img {
    width: 100%;
    height: 200px;
    display: block;
    }
    .type-news {
    width: 100%;
    margin-top: 8px;
    }
    .type-news ul {
    width: 100%;

    display: flex;
    justify-content: center;
    flex-wrap: wrap;
    }
    .type-news ul li {
    box-sizing: border-box;
    width: 48px;
    height: 22px;
    border: solid 1px #e03d3e;
    border-radius: 11px;
    margin: 5px 10px;

    font-size: 14px;
    color: #e03d3e;

    display: flex;
    justify-content: center;
    align-items: center;
    }

    .typeinit {
    background-color: #e03d3e;
    color: #fff !important; /*!important:将优先级提升最高*/
    }
    </style>
    NewsList.vue
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    <template>
    <div>
    <ul>
    <li
    v-for="item in newsArr"
    @click="toNews(item.url)"
    :key="item.uniquekey"
    >
    <div class="img-box">
    <img :src="item.thumbnail_pic_s" />
    </div>
    <div class="text-box">
    <h3>{{ item.title }}</h3>
    <p>{{ item.author_name }} {{ item.date }}</p>
    </div>
    </li>
    </ul>
    </div>
    </template>

    <script setup>
    import { reactive, computed } from "vue";

    const myProps = defineProps({
    data: Array,
    });

    const newsArr = reactive(
    computed(() => {
    let arr = myProps.data;
    for (let i = 0; i < arr.length; i++) {
    if (arr[i].title.length > 24) {
    arr[i].title = arr[i].title.substr(0, 24) + "...";
    }
    }
    return arr;
    })
    );

    const toNews = (url) => {
    location.href = url;
    }
    </script>

    <style scoped>
    ul {
    width: 100%;
    }
    ul li {
    box-sizing: border-box;
    padding: 6px;
    width: 100%;
    height: 93px;

    display: flex;
    border-bottom: dashed 1px #aaa;

    user-select: none;
    cursor: pointer;
    }
    ul li .img-box {
    flex: 0 0 100px;
    height: 80px;
    }
    ul li .img-box img {
    width: 100px;
    height: 80px;
    }
    ul li .text-box {
    flex: 1;
    box-sizing: border-box;
    padding-left: 10px;
    }
    ul li .text-box h3 {
    font-size: 16px;
    font-weight: 300;
    }
    ul li .text-box p {
    font-size: 14px;
    text-align: right;
    }
    </style>