7

vue学习笔记三

vue 企业级的解决方案

  1. vue-router
  2. vuex

vue-router

vue路由,可以简单理解为,当访问某个地址时,渲染某个组件

  1. 使用路由
  1. 根据一个配置对象创建路由,得到路由对象
  2. 在创建vue实例时,将路由对象配置到实例配置的router中
  3. 在合适的位置写上router-view组件,表示路由匹配到的组件渲染的位置,它实际上是vue-router做好的一个组件,并且进行了全局注册

路由配置对象:

1) routes:路由规则配置
2) mode:模式配置
1. hash模式,兼容性最好,地址出现在#号后,切换地址不会导致页面刷新
2. history模式,使用的是HTML5 History API,地址直接变化,并且页面不刷新

  1. 导航

通常使用 router-link 来切换页面,它可以自动使用配置中的模式,并且不会刷新页面,本质上,就是生成a元素

router-link会自动给a元素添加样式,当前的地址如果匹配router-link中的to的地址,则会添加样式。

coding example
这个例子是在前面的例子基础上实现如下效果(有header中的首页和电影页的翻页、以及点击电影页中的某部电影会出现电影详情页的功能):
首页

电影页

电影详情页

1.首先增加router.js,在里面创建一个router对象,如下:

import Home from "./pages/index.js"
import Movie from "./pages/moviePage.js"
import MovieDetail from "./pages/movieDetail.js"

//路由配置
const router = new VueRouter({
    routes: [
        { path: "/", component: Home },
        { path: "/movie", component: Movie }
        { path: "/movie/:id", component: MovieDetail }
    ],
    mode: "hash"
})

export default router
     

2.在index.js里全局注册在router.js里创建好的router对象,这时候这个这个项目中所有的组件都可以使用路由

import app from "./app.js"
import router from "./router.js"

const template = `<app></app>`;

const config = {
    el: "#app",
    components: {
        app
    },
    template,
    router
}

3.修改根组件app.js,如下,其中上会渲染路由对象

import Header from "./components/header.js"

const template = `
    <div>
        <Header/>
        <RouterView></RouterView>
    </div>
`;

export default {
    template,
    components: {
        Header
    }
}

4.增加了pages这个文件夹,里面放了实现每种分页主件的js代码

  • index.js(首页)
const template = `
    <h1 style="text-align:center">首页</h1>
`;

export default {
    template
}
  • header.js
const template = `
    <nav>
        <router-link to="/">首页</router-link>
        <router-link to="/movie">电影页</router-link>
    </nav>
`;

export default {
    template
}
  • movie.js (电影页)
import pager from "../components/pager.js"
import movies from "../components/movieList.js"
import movieService from "../services/movieService.js"
import loading from "../components/loading.js"
const template = `
    <div>
        <movie-list :datas="datas"></movie-list>
        <pager 
        :value="page" 
        @input="handlePageChange"
        :total="total" 
        :page-size="pageSize" 
        :panelNumber="5"
        ></pager>
        <loading :show="isLoading"/>
    </div>
`;

export default {
    data() {
        return {
            page: 1,
            total: 0,
            pageSize: 3,
            isLoading: false,
            datas: []
        }
    },
    mounted() {
        this.setMovies();
    },
    methods: {
        async setMovies() {
            this.isLoading = true;
            window.onscroll = (e) => e.preventDefault();
            let datas = await movieService.getMovies(this.page, this.pageSize);
            this.total = datas.total;
            this.datas = datas.datas;
            this.isLoading = false;
        },
        handlePageChange(newPage) {
            this.page = newPage;
            this.setMovies();
        }
    },
    components: {
        pager,
        movieList: movies,
        loading
    },
    template
}
  • movieDetail.js(电影详情页)
import movieService from "../services/movieService.js"
import Loading from "../components/loading.js"
import MovieDetail from "../components/movieDetail.js"
const template = `
    <div class="data-container">
        <MovieDetail v-if="movieData" :data="movieData"/>
        <h1 v-if="!isLoading && !movieData">找不到这个电影</h1>
        <loading :show="isLoading" />
    </div>
`;

export default {
    template,
    data() {
        return {
            movieData: null,
            isLoading: false
        }
    },
    async mounted(){
        this.isLoading = true;
        this.movieData = await movieService.getMovie(this.$route.params.id);
        this.isLoading = false;
    },
    components: {
        MovieDetail,
        Loading
    }
}
  • services/movieServices.js
export default {
    async getMovies(page, pageSize) {
        const datas = await fetch("http://yuanjin.tech:5005/api/movie").then(resp => resp.json());
        console.log(datas);
        return {
            total: datas.length,
            datas: datas.data.slice((page - 1) * pageSize, page * pageSize)
        }
    },
    async getMovie(id) {
        const datas = await fetch("http://yuanjin.tech:5005/api/movie").then(resp => resp.json())
        return datas.data.find(item => item._id === id);
    }
}

创建电影详情页的代码详解

1.首先在router.js里创建一个路由,并在index.js里注册

{
    path: "/movie/:id", component: MovieDetail
}

2.然后在分页文件夹pages下movieDetail.js创建组件,其中,this.movieData = await movieService.getMovie(this.$route.params.id); 是获得这个路由的id

import movieService from "../services/movieService.js"
import Loading from "../components/loading.js"
import MovieDetail from "../components/movieDetail.js"
const template = `
    <div class="data-container">
        <MovieDetail v-if="movieData" :data="movieData"/>
        <h1 v-if="!isLoading && !movieData">找不到这个电影</h1>
        <loading :show="isLoading" />
    </div>
`;

export default {
    template,
    data() {
        return {
            movieData: null,
            isLoading: false
        }
    },
    async mounted(){
        this.isLoading = true;
        this.movieData = await movieService.getMovie(this.$route.params.id);
        this.isLoading = false;
    },
    components: {
        MovieDetail,
        Loading
    }
}

3.然后就渲染(在引入components文件夹下的几个组件后)

  • services/movieService.js
export default {
    async getMovies(page, pageSize) {
        const datas = await fetch("http://yuanjin.tech:5005/api/movie").then(resp => resp.json());
        console.log(datas);
        return {
            total: datas.data.length,
            datas: datas.data.slice((page - 1) * pageSize, page * pageSize)
        }
    },
    async getMovie(id) {
        const datas = await fetch("http://yuanjin.tech:5005/api/movie").then(resp => resp.json())
        return datas.data.find(item => item._id === id);
    }
}
  • components/loading.js
import modal from "./modal.js"

const template = `
    <modal v-if="show">
        <div class="loading">
            加载中...
        </div>
    </modal>
`;

export default {
    template,
    props: {
        show: {
            default: false
        }
    },
    components: {
        modal
    }
}
  • components/movieDetail.js
import movieService from "../services/movieService.js"
import Loading from "../components/loading.js"
import MovieDetail from "../components/movieDetail.js"
const template = `
    <div class="data-container">
        <MovieDetail v-if="movieData" :data="movieData"/>
        <h1 v-if="!isLoading && !movieData">找不到这个电影</h1>
        <loading :show="isLoading" />
    </div>
`;

export default {
    template,
    data() {
        return {
            movieData: null,
            isLoading: false
        }
    },
    async mounted(){
        this.isLoading = true;
        this.movieData = await movieService.getMovie(this.$route.params.id);
        this.isLoading = false;
    },
    components: {
        MovieDetail,
        Loading
    }
}

其中,要在components/movie.js要加入<router-link :to="'/movie/'+data._id"><h2 class="title">{{data.name}}</h2></router-link>

总结:从电影页中点击一下电影名称后, <router-link></router-link>就会由路由跳转页面,开始渲染./pages/movieDetail.js

posted @ 2020-09-04 14:54  ZenlenTim  阅读(83)  评论(0)    收藏  举报
分享到: