不一样的 vue 实战 (3): 布局与组件

首先

首先:讲一句抱歉,周末俗事缠身,无力更博,只有今日发了。而且写博挺消耗精力的,你别看短短了几千字,需要反复的斟酌,反复的修改,如果有错误与不足的地方,请评论指正,谢谢!

前言

本文是结合官方的 api文档,进行渐进式学习,在实战中熟悉文档,在文档中理解实战。下面的代码中有详细的代码注释,和逻辑讲解,请仔细阅读。

3.1.1 什么是vue?

如果你还不知道什么Vue是干什么的,请参见什么是vue

3.1.2 项目结构

参考以下的目录结构,新建文件夹,下面打‘ * ’的为新建文件夹
<pre>
├── build // 构建服务和webpack配置
├── config // 项目不同环境的配置
├── dist // 项目build目录
├── index.html // 项目入口文件
├── package.json // 项目配置文件
├── src // 生产目录
│ ├── assets // 图片资源
│ ├── common * // 公共的css js 资源
│ ├── components // 各种组件
│ ├── moke * // 本地静态数据管理文件
│ ├── App.vue // 主页面
│ ├── vuex * // vuex状态管理器
│ ├── router // 路由配置器
│ └── main.js // Webpack 预编译入口

</pre>

3.1.3 Vue 实例

新增知识点

步骤

打开 /src/main.js 你会看到

import Vue from 'vue'   //引入vue模块
import App from './App'  //引入vue组件
import router from './router' // 引入路由配置文件

Vue.config.productionTip = false // 关闭生产模式下给出的提示

new Vue({  // 创建一个 Vue 的根实例
  el: '#app', //挂载id,这个实例下所有的内容都会在index.html 一个id为app的div下显示
  router, // 注入路由配置。
  template: '<App/>', //配置根模板 即打开页面显示那个组件
  components: { App } // 注入组件
})

3.1.4 Style

第一步 安装less

在终端上输入

npm install --save-dev less-loader style-loader less 

第二步 配置less

/build/webpack.base.conf.js 加上

module.exports = {
  module: {
    rules: [
      {   //把这个对象添加在里面
        test: /\.less$/,
        use: [
          'style-loader',
          { loader: 'css-loader', options: { importLoaders: 1 } },
          'less-loader'
        ]
      }
    ]
  }
}

第三步 下载style文件

因为本课程主要是针对Vue的实战,所以在这里不去讲解less的用法,如果感兴趣可以去less教程学习,也不会讲每个样式怎么写,请下载Style文件,到 src/common/下。

3.1.5 ‘.vue’文件

  • Vue自定义了一种后缀名名字为.vue文件,它将html, js, css 整合成一个文件,和里面 template script style三个区别分别依次对应。
<template>
<!--这里写 html -->
<template/>
<script>
 export default {};
 // 这里写js
</script>
<style lang = "less" scoped>
 <!--这里写css-->
</style>
  • 一个.vue 文件就等于单独组件。因为.vue文件是自定义的,浏览器不识别,所以要对该文件进行解析,在webpack构建中,需要安装vue-loader 对.vue文件进行解析。
  • template里面最外层必须是只有一个容器
  • script 中的 ** export default {}** 即导出这个组件,外部可以引用。
  • style 中的 lang 指额外表示支持的语言可以让编辑器识别,scoped 指这里写的css只适用于该组件。

3.1.6 新增layouts.vue(布局组件)

在学习了上一小节,我们知道了 .vue文件是做什么用,下面我们就尝试一下。

src/components/目录下新建一个文件 layouts.vue,并且复制以下代码。

<template>
  <section class="container" > <!--最外层容器-->
    <section class="menu"> <!--左边的容器-->
    </section>
    <section class="content-container"><!--右边的容器-->
    </section>
  </section>
</template>
<script>
  export  default {};
</script>

<style lang="less">
@import '../common/style/layouts.less';
</style>

3.1.7 修改router(路由)

vue-router有什么用?

它的作用在于路由设置,用于设置页面跳转时的路径设置,它的工作原理也很简,将组件(components)映射到路由(routes),然后告诉 vue-router 在哪里渲染它们。

新增知识点(必看):

第一步:

打开 src/router/index.js 文件
复制以下代码,替换老的代码。

import Vue from 'vue' // 导入Vue
import Router from 'vue-router' // 导入vue-router 库
import Layouts from '@/components/layouts' // 导入layouts.vue 组件

Vue.use(Router) //全局注册Router组件,它会绑定到Vue实例里面。

export default new Router({ // 创建 router 实例,然后传 `routes` 配置
  routes: [
    {
      path: '/',  //访问路径
      name: 'Layouts', // 路径名
      component: Layouts //访问的组件,即访问‘/’,它会加载 Layouts 组件所有的内容。
    }
  ]
})

第二步:

浏览器打开 http://localhost:8080/ 你将看到如下的显示,那么这一步你就完成了。

3.1.8 menu.vue(菜单组件)

新增知识点(必读)

第一步:

src/components/目录下新建一个文件 menu.vue,并且复制以下代码

<template>
  <div class="list-todos">  <!--菜单容器-->
      <a class="list-todo activeListClass list" > <!--单个菜单容器-->
        <span class="icon-lock" ></span>  <!--锁的图标-->
        <span class="count-list">1</span><!--数字-->
        星期一 <!--菜单内容-->
      </a>
    <a class=" link-list-new" > <!--新增菜单-->
      <span class="icon-plus">
      </span>
      新增
    </a>
  </div>
</template>
<script>
  export default {};
</script>

<style lang="less">
@import '../common/style/menu.less';
</style>

第二步:

我们在回到 Layouts.vue,并且新增以下打*代码。

<template>
    <section class="menu"> <!--左边的容器 里面加上组件 menus-->
     <menus></menus> <!-- * -->
    </section>
</template>

<script>
  import menus from './menus'; // * 导入刚才我们创建的 menus组件
  export  default {
    components: { // * 注册menus组件,让其可以在template调用
      menus
    }
  };
</script>

最后我们的 menu组件就注册成功啦,并且引用了它,你做的怎么样了呢?

3.1.9列表渲染

新增知识点(必读)

第一步:

回到 src/components/menu.vue,新增以下代码。

<template>
   <a class="list-todo list activeListClass" v-for="item in items"> <!-- v-for 列表渲染-->
     <span class="icon-lock" v-if="item.locked"></span> <!-- v-if 条件渲染-->
     <span class="count-list" v-if="item.count > 
     0">{{item.count}}</span>
     {{item.title}}   <!-- 数据绑定,看模板语法-->
   </a>
</template>
<script>
export default {
 data() { //data函数
   return {
     items: [{ title: '星期一', count: 1, locked: true }, //菜单的模拟数据
       { title: '星期二', count: 2, locked: true }, {
       title: '星期三', count: 3, locked: false
     }]
   };
 }
};
</script>

完成后你将会看到以下内容。

现在整个页面我们已经左边的菜单部分,下面就是完成右边的详情部分。

3.1.10 todo.vue (待办事项详情组件)

新增知识点(必读)

第一步:

src/components/ 目录下新建一个文件 todo.vue,复制以下代码。

<template>
 <div class="page lists-show"><!--最外层容器-->
   <nav><!--容器上半部分-->
     <div class="nav-group"> <!--移动端的菜单图标-->
       <a class="nav-item">
         <span class="icon-list-unordered">
         </span>
       </a>
     </div>
     <h1 class="title-page">
       <span class="title-wrapper">{{todo.title}}</span> <!-- 标题-->
       <span class="count-list">{{todo.count}}</span><!-- 数目-->
     </h1>
     <div class="nav-group right"><!-- 右边的删除,锁定图标容器-->
       <div class="options-web"> 
         <a class=" nav-item"> <!-- 锁定图标-->
           <span class="icon-lock" v-if="todo.locked"></span>
           <span class="icon-unlock" v-else>
           </span>
         </a>
         <a class=" nav-item"><!-- 删除图标-->
           <span class="icon-trash">
           </span>
         </a>
       </div>
     </div>
 
     <div class=" form todo-new input-symbol"> <!-- 新增单个代办单项输入框,监听了回车事件,双向绑定text值,监听了disabled属性,在todo.locked为true的情况下无法编辑-->
        <input type="text" v-model="text" placeholder='请输入'@keyup.enter="onAdd" :disabled="todo.locked" />
       <span class="icon-add"></span>
     </div>
   </nav>
   <div class="content-scrollable list-items">
     <!--容器下半部分-->
   </div>
 </div>
</template>
<script>
export default {
 data() {
   return {
     todo: { //详情内容
       title: '星期一',
       count: 12,
       locked: false
     },
     items: [ //代办单项列表
       { checked: false, text: '新的一天', isDelete: false },
       { checked: false, text: '新的一天', isDelete: false },
       { checked: false, text: '新的一天', isDelete: false }
     ],
     text: '' //新增代办单项绑定的值
   }
 },
 methods: {
   onAdd() {
     this.items.push({
       checked: false, text: this.text, isDelete: false
     }); // 当用户点击回车时候 ,给items的值新增一个对象,this.text 即输入框绑定的值
     this.text = ''; //初始化输入框的值。
   }
 }
}
</script>
<style lang = "less">
@import '../common/style/nav.less';
@import '../common/style/form.less';
@import '../common/style/todo.less';
</style>

第二步

打开 src/components/layouts.vue文件
新加入以下代码。

<template>
   <section class="content-container"><!--右边的容器-->
   <todo></todo>
   </section>
</template>
 <script>
  import todo from './todo';
 export  default {
   components: {
     todo  //新加的
   }
 };
</script>

最后:

3.1.11 item.vue(代办单项组件)

新增知识点

第一步:

src/components/ 目录下新建一个文件 item.vue,复制以下代码。

<template>
  <div class="list-item editingClass editing"> <!-- 最外层容器-->
    <label class="checkbox"> <!--自定义的多选框-->
      <input type="checkbox" v-model="item.checked"> <!--item.checked-->
      <span class="checkbox-custom"></span>
    </label>
    <input type="text" v-model="item.text" placeholder='写点什么。。。'>  <!--绑定item.text-->
    <a class="delete-item"> <!--删除图标-->
      <span class="icon-trash"></span>
    </a>
  </div>
</template>
<script>
export default {
  props: ['item']  //子组件显式的用 props 选项声明它期待获得的数据,
  这里申明 它想要一个叫做 ’item‘的数据。
};
</script>
<style lang="less">
@import '../common/style/list-items.less';
</style>

第二步:

打开 src/components/todo.vue文件
新加入以下代码

<template>
   <div class="content-scrollable list-items">
      <div v-for="item in items"> <!-- 这里`v-for`会循环我们在 `data`函数 事先定义好的 ’items‘模拟数据,循环后拿到单个对象,在通过prop把数据传输给子组件 item -->
       <item :item="item"></item>
     </div>
   </div>
</template>
 <script>
import item from './item';
 export  default {
   components: {  //新加components对象
     item  //新加的
   }
 };
</script>

最后

在新增的输入框里面,输入点东西,并且回车,看看有没有达到效果。


小结

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容