vue脚手架 构建豆瓣App 第一天

课堂笔记:

项目结构分析:

项目入口:index.html(div#app)

全局vue组件:App.vue(template:div#app)

通过相同id的div,index.html与Appvue关联在了一起(具体怎么关联起来的,不需要关心)

App.vue中 写入公共部分(tabbar+router-view)

如何控制router-view的显示的内容呢?

router文件夹下index.js:配置路由的文件

先导入组件 import 自定义名字首字母大写 from "路径(同级文件前也要加./)"

然后将组件应用到routes中,进行路径分配

routes:[]

豆瓣app共有5个页面

都放在src文件下的pages文件夹下 这是自己创建的文件夹

Home-->home.vue

Audio-->audio.vue

Broadcast-->broadcast.vue

Group-->group.vue

Mine-->mine.vue

5个页面又分别由不同的小组件组装而成

这些小组件,我们可以将他们存放在components文件下,也可以存放在pages的目录中

------------------------------------------------------------------------------------------------------------------------------------------

以上是本节课的笔记:

下面来一些自己的总结:

创建项目:

  条件:node webpack vue-cli 记得提前安装好

1、首先创建一个文件夹 ,这个文件夹是存放项目的地方;

2、打开终端 cd到这个文件夹 (创建项目文件)

     vue init webpack douban (回车--router(yes)---no.....)

  3、cd到douban 安装依赖包

       npm install (会出现一个node-module文件 这里面存放着项目的依赖)

  4、启动项目

        npm run dev (在浏览器地址输入:localhost:8080 就可以打开项目了)

下面按照自己的来说一下今天说学到的东西:

   index.html是整个项目的入口,我们会发现body里面仅仅放了 <div ></div>这一个代码,很神奇吧(不用管怎么做到的),

   我们只需要知道index.html是和app.vue文件绑定在一起的,app.vue是全局组件,公有组件,都引入到app.vue里,就可以在任何页面显示(最典型的就是头部、和底部tabbar组件)。

  之后,我们在src里创建一个pages文件夹,这里面是存放豆瓣的5个页面,home、audio、broadcast、group、mine里面存放着格子的vue文件(大组件)。

  每个组件都有 template script style 三个板块组成,

  如果要在一个组件引入另一个组件 首先要引入

      import 起个名(首字母大写) from ‘路径’

  举个例子:

<script>

  import Item from './item.vue'//平级也要加./ 否则报错

  export default{

    components:{

      Item

    },

  }

</script> 

------------------------------不想写了 表达能力有限 现在把tabbar 组件 与 item组件的封装源码上来!!请看-----------------------

tabbar组件:

<template>

  <div class="tabbar">

    <Item txt="首页" mark="home" :sel="selected" @change="getVal">

      <img src="../assets/images/ic_tab_home_active.png" height="128" width="128" slot="activeImg"/>

      <img src="../assets/images/ic_tab_home_normal.png" height="128" width="128" slot="normalImg"/>

    </Item>

    <Item txt="书影音" mark="audio" :sel="selected" @change="getVal">

      <img src="../assets/images/ic_tab_subject_active.png" height="96" width="96" slot="activeImg"/>

      <img src="../assets/images/ic_tab_subject_normal.png" height="96" width="96" slot="normalImg"/>

    </Item>

    <Item txt="广播" mark="broadcast" :sel="selected" @change="getVal">

      <img src="../assets/images/ic_tab_status_active.png" height="96" width="96" slot="activeImg"/>

      <img src="../assets/images/ic_tab_status_normal.png" height="96" width="96" slot="normalImg"/>

    </Item>

    <Item txt="小组" mark="group" :sel="selected" @change="getVal">

      <img src="../assets/images/ic_tab_group_active.png" height="96" width="96" slot="activeImg"/>

      <img src="../assets/images/ic_tab_group_normal.png" height="96" width="96" slot="normalImg"/>

    </Item>

    <Item txt="我的" mark="mine" :sel="selected" @change="getVal">

      <img src="../assets/images/ic_tab_profile_active.png" height="128" width="128" slot="activeImg"/>

      <img src="../assets/images/ic_tab_profile_normal.png" height="128" width="128" slot="normalImg"/>

    </Item>

  </div>

</template>

<script>

  import Item from './item.vue'

  export default{

    components:{

      Item

    },

    data:function(){

      return {

        selected:"home"

      }

    },

    methods:{

    getVal:function(val){

          this.selected=val;

        }

      }

    }

</script>

<style>

  .tabbar{width:100%;height:64px;border-top:1px solid #ccc;}

</style>

-----------------------------------------------------item组件--------------------------------------------------------------

<template>

  <div class="itemWrap" @click="fn">

    <span v-show="bol"><slot name="activeImg"></slot><br></span>

    <span v-show="!bol"><slot name="normalImg"></slot><br></span>

    <span :class="{active:bol}">{{ txt }}</span>

  </div>

</template>

<script>

  export default{

    props:["txt","mark","sel"],

    computed:{

      bol:function(){

      if(this.mark==this.sel){return true;}

      return false;

      }

    },

    methods:{

      fn:function(){

        this.$emit("change",this.mark);

        this.$router.push('/'+this.mark);

      }

    }

  }

</script>

<style>

  .itemWrap{width:20%;float: left;}

  .itemWrap img{width:40px;height:40px;display: block;margin:0 auto;}

  .itemWrap span{font-size:12px;color:#666;}

  .itemWrap .active{color:#42bd56;}

</style>

------------------------------------------------总结一下 以上代码用到的知识点 然后睡觉--------------------------------------

以上代码主要实现 tabbar的切换 点击相应图标 切换到对应页面

路由重定向 是写在app。vue文件里的

  beforeCreate:function(){

    this.$router.push('/');

  }

在router文件下的index.js里配置5个页面的路由设置:

    

import Vue from 'vue'

import Router from 'vue-router'

import HelloWorld from '@/components/HelloWorld'

import Test from '../components/test.vue'

import Home from '../pages/Home/home.vue'

import Broadcast from '../pages/Broadcast/broadcast.vue'

import Audio from '../pages/Audio/audio.vue'

import Group from '../pages/Group/group.vue'

import Mine from '../pages/Mine/mine.vue'

Vue.use(Router)

export default new Router({

routes: [

{

path: '/',

name: 'Home',

component: Home

},

{

path: '/home',

name: 'Home',

component: Home

},

{

path: '/audio',

name: 'Audio',

component: Audio

},

{

path: '/broadcast',

name: 'Broadcast',

component: Broadcast

},

{

path: '/group',

name: 'Group',

component: Group

},

{

path: '/mine',

name: 'Mine',

component: Mine

}

]

})

----------------------------------------------------------------------------------------------------

点击对应图标 对应图标变成绿色(其实是显示active图片 隐藏 normal图片 这有v-show指令的布尔值控制)

主要用到的知识是子组件向父组件的逆向传值 我说一下思路

  正向传值(父-》子) 在子组件的props配置项里 定义一个变量 , 在父组件里调用时 , 当做属性绑定它 ,它的值写成父组件里的变量即可

  逆向传值(子-》父):这需要用到 创建自定义监听事件的方法:我来说一下思路

    首先 需要一个点击事件来触发,这个事件就绑定在item上就行,假设这个点击的函数为fn,在fn函数写:

      

methods:{

  fn:function(){

    this.$emit("change",this.mark);//创建自定义监听事件的方法,谁创建,谁就接收 第一个参数是自定义事件名称,第二个参数是要传的值

    this.$router.push('/'+this.mark);//实现页面切换

  }

}

自定义监听事件创建出来了,在父组件里调用子组件时,在子组件上绑定这个自定义创建的事件: @change="getval"

getval函数是在父组件里定义的,它的默认参数是子组件传来的值

在父组件的methods配置项中写:

  

methods:{

  getVal:function(val){//val默认是子组件里传来的值

    this.selected=val;

  }

}

----------------------下面来说一下,实现点击对应图标,对应图标变色的思路-----------------------------------

首先,在子组件里定义了一个mark变量,在父组件里调用子组件时,给mark传了不同的值,这里面传的是每个页面的路由地址(原来是传数字的,只不过这里要实现路由跳转,才传的每个页面的路由地址),这样就可以区分出每个item了,就是相当于给每个item做了一个标记。在父组件中定义了一个selected变量,

selected值是子组件被点击时传来的mark值,再把这个selected值,通过绑定属性的方式传给子组件,子组件有自己定义的sel变量来接收,之后判断子组件的mark值是否与sel值相等,其实至少是有一个item的mark值是和sel值相等的,因为点击item时,父组件会接收到一个子组件的mark值,而父组件又通过selected值传给了子组件的sel变量,这样就知道我们到底点击的是哪一个item了,然后让这个item的bol值变成true,而这个bol值,控制着每个item的两张图片的显示与隐藏,我们定义,有v-show指令控制,这样就成功实现了点击对应item,此item就变色的效果,路由的切换,随之实现。逻辑有点复杂。。。。。晚安!