Vue-入门到实战(六)

Vue.js - day6

注意:

有时候使用npm i node-sass -D装不上,这时候,就必须使用 cnpm i node-sass -D

在普通页面中使用render函数渲染组件

<div id="app">
    <p>444444</p>
  </div>

  <script>

    var login = {
      template: '<h1>这是登录组件</h1>'
    }

    // 创建 Vue 实例,得到 ViewModel
    var vm = new Vue({
      el: '#app',
      data: {},
      methods: {},
      render: function (createElements) { // createElements 是一个 方法,调用它,能够把 指定的 组件模板,渲染为 html 结构
        return createElements(login)
        // 注意:这里 return 的结果,会 替换页面中 el 指定的那个 容器
      }
    });
  </script>
  

在webpack中配置.vue组件页面的解析

// 总结梳理: webpack 中如何使用 vue :
// 1. 安装vue的包:  cnpm i vue -S
// 2. 由于 在 webpack 中,推荐使用 .vue 这个组件模板文件定义组件,所以,需要安装 能解析这种文件的 loader    cnpm i vue-loader vue-template-complier -D
// 3. 在 main.js 中,导入 vue 模块  import Vue from 'vue'
// 4. 定义一个 .vue 结尾的组件,其中,组件有三部分组成: template script style
// 5. 使用 import login from './login.vue' 导入这个组件
// 6. 创建 vm 的实例 var vm = new Vue({ el: '#app', render: c => c(login) })
// 7. 在页面中创建一个 id 为 app 的 div 元素,作为我们 vm 实例要控制的区域;

  1. 运行cnpm i vue -S将vue安装为运行依赖;

  2. 运行cnpm i vue-loader vue-template-compiler -D将解析转换vue的包安装为开发依赖;

  3. 运行cnpm i style-loader css-loader -D将解析转换CSS的包安装为开发依赖,因为.vue文件中会写CSS样式;

  4. webpack.config.js中,添加如下module规则:


module: {

    rules: [

      { test: /\.css$/, use: ['style-loader', 'css-loader'] },

      { test: /\.vue$/, use: 'vue-loader' }

    ]

  }

  1. 创建App.js组件页面:
    <template>
      <!-- 注意:在 .vue 的组件中,template 中必须有且只有唯一的根元素进行包裹,一般都用 div 当作唯一的根元素 -->
      <div>
        <h1>这是APP组件 - {{msg}}</h1>
        <h3>我是h3</h3>
      </div>
    </template>

    <script>
    // 注意:在 .vue 的组件中,通过 script 标签来定义组件的行为,需要使用 ES6 中提供的 export default 方式,导出一个vue实例对象
    export default {
      data() {
        return {msg: 'OK'}
      }
    }
    </script>

    <style scoped>//scoped:当前这个区域,局部的意思
    
    h1 {color: red;}
    
    </style>

  1. 创建main.js入口文件:

    // 导入 Vue 组件

    import Vue from 'vue'

// 注意: 在 webpack 中, 使用 import Vue from 'vue' 导入的 Vue 构造函数,功能不完整,只提供了 runtime-only 的方式,并没有提供 像网页中那样的使用方式;
// import Vue from '../node_modules/vue/dist/vue.js'
// 回顾 包的查找规则:
// 1. 找 项目根目录中有没有 node_modules 的文件夹
// 2. 在 node_modules 中 根据包名,找对应的 vue 文件夹
// 3. 在 vue 文件夹中,找 一个叫做 package.json 的包配置文件
// 4. 在 package.json 文件中,查找 一个 main 属性【main属性指定了这个包在被加载时候,的入口文件】

    // 导入 App组件

    import App from './components/App.vue'



    // 创建一个 Vue 实例,使用 render 函数,渲染指定的组件

    var vm = new Vue({

      el: '#app',

      render: c => c(App)

    });

  1. webpack4版本时,会报错vue-loader was used without the corresponding plugin. Make sure to include VueLoaderPlugin in your webpack config.,需要修改webpack.config.js配置:
 var VueLoaderPlugin = require('vue-loader/lib/plugin')
 
 plugins:[
        new VueLoaderPlugin()
    ],

在使用webpack构建的Vue项目中使用模板对象?

  1. webpack.config.js中添加resolve属性:
resolve: {
    alias: {
      'vue$': 'vue/dist/vue.esm.js'
    }
  }

ES6中语法使用总结

  1. 使用 export defaultexport 导出模块中的成员; 对应ES5中的 module.exportsexport

  2. 使用 import ** from **import '路径' 还有 import {a, b} from '模块标识' 导入其他模块

  3. 使用箭头函数:(a, b)=> { return a-b; }

// 这是 Node 中向外暴露成员的形式:
// module.exports = {}

// 在 ES6中,也通过 规范的形式,规定了 ES6 中如何 导入 和 导出 模块
//  ES6中导入模块,使用   import 模块名称 from '模块标识符'    import '表示路径'

// 在 ES6 中,使用 export default 和 export 向外暴露成员:
var info = {
  name: 'zs',
  age: 20
}

export default info

/* export default {
  address: '北京'
} */

// 注意: export default 向外暴露的成员,可以使用任意的变量来接收
// 注意: 在一个模块中,export default 只允许向外暴露1次
// 注意: 在一个模块中,可以同时使用 export default 和 export 向外暴露成员



export var title = '小星星'
export var content = '哈哈哈'

// 注意: 使用 export 向外暴露的成员,只能使用 { } 的形式来接收,这种形式,叫做 【按需导出】
// 注意: export 可以向外暴露多个成员, 同时,如果某些成员,我们在 import 的时候,不需要,则可以 不在 {}  中定义
// 注意: 使用 export 导出的成员,必须严格按照 导出时候的名称,来使用  {}  按需接收;
// 注意: 使用 export 导出的成员,如果 就想 换个 名称来接收,可以使用 as 来起别名;




// 在Node中 使用 var 名称 = require('模块标识符')
// module.exports 和 exports 来暴露成员

在vue组件页面中,集成vue-router路由模块

vue-router官网

npm install vue-router

  1. 导入路由模块:

import VueRouter from 'vue-router'

  1. 安装路由模块:

Vue.use(VueRouter);

  1. 导入需要展示的组件:

import login from './components/account/login.vue'

import register from './components/account/register.vue'

  1. 创建路由对象:

var router = new VueRouter({

  routes: [

    { path: '/', redirect: '/login' },

    { path: '/login', component: login },

    { path: '/register', component: register }

  ]

});

  1. 将路由对象,挂载到 Vue 实例上:

var vm = new Vue({

  el: '#app',

  // render: c => { return c(App) }

  render(c) {

    return c(App);

  },

  router // 将路由对象,挂载到 Vue 实例上

});

  1. 改造App.vue组件,在 template 中,添加router-linkrouter-view

    <router-link to="/login">登录</router-link>

    <router-link to="/register">注册</router-link>



    <router-view></router-view>

组件中的css作用域问题

<style lang="scss" scoped>
/* 
普通的 style 标签只支持 普通的 样式,如果想要启用 scss 或 less ,需要为 style 元素,设置 lang 属性 
只要 咱们的 style 标签, 是在 .vue 组件中定义的,那么,推荐都为 style 开启 scoped 属性*/
body {
  div {
    font-style: italic;
  }
}
</style>

抽离路由为单独的模块

1.main.js

// 导入 自定义路由模块
import router from './router.js'

2.router.js

import VueRouter from 'vue-router'

// 导入 Account 组件
import account from './main/Account.vue'
import goodslist from './main/GoodsList.vue'

// 导入Account的两个子组件
import login from './subcom/login.vue'
import register from './subcom/register.vue'

// 3. 创建路由对象
var router = new VueRouter({
  routes: [
    // account  goodslist
    {
      path: '/account',
      component: account,
      children: [
        { path: 'login', component: login },
        { path: 'register', component: register }
      ]
    },
    { path: '/goodslist', component: goodslist }
  ]
})

// 把路由对象暴露出去
export default router

使用 饿了么的 MintUI 组件

Github 仓储地址

Mint-UI官方文档

  1. 导入所有MintUI组件:

import MintUI from 'mint-ui'

  1. 导入样式表:

import 'mint-ui/lib/style.css'

  1. 在 vue 中使用 MintUI中的Button按钮和Toast弹框提示:

Vue.use(MintUI)

  1. 使用的例子:

<mt-button type="primary" size="large">primary</mt-button>

Mint-UI中按需导入的配置方式

import 'mint-ui/lib/style.css'

// 按需导入 Mint-UI组件
import { Button } from 'mint-ui'
// 使用 Vue.component 注册 按钮组件
Vue.component(Button.name, Button)

使用 MUI 代码片段

注意: MUI 不同于 Mint-UI,MUI只是开发出来的一套好用的代码片段,里面提供了配套的样式、配套的HTML代码段,类似于 Bootstrap; 而 Mint-UI,是真正的组件库,是使用 Vue 技术封装出来的 成套的组件,可以无缝的和 VUE项目进行集成开发;
因此,从体验上来说, Mint-UI体验更好,因为这是别人帮我们开发好的现成的Vue组件;
从体验上来说, MUI和Bootstrap类似;
理论上,任何项目都可以使用 MUI 或 Bootstrap,但是,MInt-UI只适用于Vue项目;

注意: MUI 并不能使用 npm 去下载,需要自己手动从 github 上,下载现成的包,自己解压出来,然后手动拷贝到项目中使用;

官网首页

文档地址

  1. 导入 MUI 的样式表:

import '../lib/mui/css/mui.min.css'

  1. webpack.config.js中添加新的loader规则:

{ test: /\.(png|jpg|gif|ttf)$/, use: 'url-loader' }

  1. 根据官方提供的文档和example,尝试使用相关的组件

将项目源码托管到oschina中

  1. 点击头像 -> 修改资料 -> SSH公钥 如何生成SSH公钥

  2. 创建自己的空仓储,使用 git config --global user.name "用户名"git config --global user.email ***@**.com 来全局配置提交时用户的名称和邮箱

  3. 使用 git init 在本地初始化项目

  4. 使用 touch README.mdtouch .gitignore 来创建项目的说明文件和忽略文件;

  5. 使用 git add . 将所有文件托管到 git 中

  6. 使用 git commit -m "init project" 将项目进行本地提交

  7. 使用 git remote add origin 仓储地址将本地项目和远程仓储连接,并使用origin最为远程仓储的别名

  8. 使用 git push -u origin master 将本地代码push到仓储中

App.vue 组件的基本设置

  1. 头部的固定导航栏使用 Mint-UIHeader 组件;

  2. 底部的页签使用 muitabbar;

  3. 购物车的图标,使用 icons-extra 中的 mui-icon-extra mui-icon-extra-cart,同时,应该把其依赖的字体图标文件 mui-icons-extra.ttf,复制到 fonts 目录下!

  4. 将底部的页签,改造成 router-link 来实现单页面的切换;

  5. Tab Bar 路由激活时候设置高亮的两种方式:

  • 全局设置样式如下:

	.router-link-active{

     	color:#007aff !important;

   }

  • 或者在 new VueRouter 的时候,通过 linkActiveClass 来指定高亮的类:

	// 创建路由对象

   var router = new VueRouter({

     routes: [

       { path: '/', redirect: '/home' }

     ],

     linkActiveClass: 'mui-active'

   });

实现 tabbar 页签不同组件页面的切换

  1. 将 tabbar 改造成 router-link 形式,并指定每个连接的 to 属性;

  2. 在入口文件中导入需要展示的组件,并创建路由对象:


    // 导入需要展示的组件

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

    import Member from './components/member/member.vue'

    import Shopcar from './components/shopcar/shopcar.vue'

    import Search from './components/search/search.vue'



    // 创建路由对象

    var router = new VueRouter({

      routes: [

        { path: '/', redirect: '/home' },

        { path: '/home', component: Home },

        { path: '/member', component: Member },

        { path: '/shopcar', component: Shopcar },

        { path: '/search', component: Search }

      ],

      linkActiveClass: 'mui-active'

    });

使用 mt-swipe 轮播图组件

  1. 假数据:
{
  "data": {
    "message": [{
      "url": "http://www.itcast.cn/images/slidead/BEIJING/2017440109442800.jpg",
      "image": "http://www.itcast.cn/images/slidead/BEIJING/2017440109442800.jpg",
    }, {
      "url": "http://www.itcast.cn/images/slidead/BEIJING/2017511009514700.jpg",
      "image": "http://www.itcast.cn/images/slidead/BEIJING/2017511009514700.jpg",
    }, {
      "url": "http://www.itcast.cn/images/slidead/BEIJING/2017421414422600.jpg",
      "image": "http://www.itcast.cn/images/slidead/BEIJING/2017421414422600.jpg",
    }],
  }
}

  1. 自定义图片懒加载指令v-lazyload

2.1安装

npm install vue-lazyload --save

2.2引入

import VueLazyLoad from 'vue-lazyload'
Vue.use(VueLazyLoad)

or 

Vue.use(VueLazyload, {
  preLoad: 1.3,
  error: 'dist/error.png',//图片要自己放入
  loading: 'dist/loading.gif',//图片要自己放入
  attempt: 1
})

  1. 引入轮播图组件:

<!-- Mint-UI 轮播图组件 -->

  <template>
  <div>
    <!-- 轮播图区域 -->
    <mt-swipe :auto="4000">
      <mt-swipe-item v-for="item in lunbotuList" :key="item.url">
          <img v-lazy="item.image" alt="">
      </mt-swipe-item>
    </mt-swipe>
  </div>
</template>

<script>
import { Toast } from "mint-ui"

export default {
    data(){
        return{
           lunbotuList:[]
        }
    },
    created(){
        this.getLunbotu();
    },
    methods:{
      getLunbotu(){
          this.$http.get("https://www.easy-mock.com/mock/5c41678a0bb19c6a02e0175b/vuedemo/api/lunbo").
          then( result => {
              if(result.status === 200){
                  this.lunbotuList = result.data.data.message
              }else{
                  Toast("加载轮播图失败")
              }
          })
      }
    }
}
</script>

<style lang="scss" scoped>
.mint-swipe{
    height: 200px;

    .mint-swipe-item{

    &:nth-child(1){ background-color: red }
    &:nth-child(2){ background-color: blue }
    &:nth-child(3){ background-color: cyan }
}
img{
    width: 100%;
    height: 100%;
}
}

</style>


.vue组件中使用vue-resource获取数据

  1. 运行cnpm i vue-resource -S安装模块

  2. 导入 vue-resource 组件


import VueResource from 'vue-resource'

  1. 在vue中使用 vue-resource 组件

Vue.use(VueResource);

封装读取文件的方法

// 需求:你要封装一个方法,我给你一个要读取文件的路径,你这个方法能帮我读取文件,并把内容返回给我

const fs = require('fs')
const path = require('path')

// 这是普通读取文件的方式
/* fs.readFile(path.join(__dirname, './files/1.txt'), 'utf-8', (err, dataStr) => {
  if (err) throw err
  console.log(dataStr)
}) */

// 初衷: 给定文件路径,返回读取到的内容
// 我们可以规定一下, callback 中,有两个参数,第一个参数,是 失败的结果;第二个参数是成功的结果;
// 同时,我们规定了: 如果成功后,返回的结果,应该位于 callback 参数的第二个位置,此时, 第一个位置 由于没有出错,所以,放一个 null;  
//                    如果失败了,则 第一个位置放 Error对象,第二个位置放一个 undefined
function getFileByPath(fpath, callback) {
  fs.readFile(fpath, 'utf-8', (err, dataStr) => {
    // 如果报错了,进入if分支后,if后面的代码就没有必要执行了
    if (err) return callback(err)
    // console.log(dataStr)
    // return dataStr
    callback(null, dataStr)
  })
}

/* var result = getFileByPath(path.join(__dirname, './files/1.txt'))
console.log(result) */
getFileByPath(path.join(__dirname, './files/11.txt'), (err, dataStr) => {
  // console.log(dataStr + '-----')
  if (err) return console.log(err.message)
  console.log(dataStr)
})

封装读取文件的方法–提高版

// 需求:你要封装一个方法,我给你一个要读取文件的路径,你这个方法能帮我读取文件,并把内容返回给我

const fs = require('fs')
const path = require('path')


function getFileByPath(fpath, succCb, errCb) {
  fs.readFile(fpath, 'utf-8', (err, dataStr) => {
    if (err) return errCb(err)
    succCb(dataStr)
  })
}

// getFileByPath(path.join(__dirname, './files/11.txt'), function (data) {
//   console.log(data + '娃哈哈,成功了!!!')
// }, function (err) {
//   console.log('失败的结果,我们使用失败的回调处理了一下:' + err.message)
// })

// 需求: 先读取文件1,再读取文件2,最后再读取文件3
// 回调地狱
// 使用 ES6 中的 Promise,来解决 回调地狱的问题;
// 问: Promise 的本质是要干什么的:就是单纯的为了解决回调地狱问题;并不能帮我们减少代码量;
getFileByPath(path.join(__dirname, './files/1.txt'), function (data) {
  console.log(data)

  getFileByPath(path.join(__dirname, './files/2.txt'), function (data) {
    console.log(data)

    getFileByPath(path.join(__dirname, './files/3.txt'), function (data) {
      console.log(data)
    })
  })
})

Promise概念介绍

// 1. Promise 是一个 构造函数,既然是构造函数, 那么,我们就可以  new Promise() 得到一个 Promise 的实例;
// 2. 在 Promise 上,有两个函数,分别叫做 resolve(成功之后的回调函数) 和 reject(失败之后的回调函数)
// 3. 在 Promise 构造函数的 Prototype 属性上,有一个 .then() 方法,也就说,只要是 Promise 构造函数创建的实例,都可以访问到 .then() 方法
// 4. Promise 表示一个 异步操作;每当我们 new 一个 Promise 的实例,这个实例,就表示一个具体的异步操作;
// 5. 既然 Promise 创建的实例,是一个异步操作,那么,这个 异步操作的结果,只能有两种状态:
//  5.1 状态1: 异步执行成功了,需要在内部调用 成功的回调函数 resolve 把结果返回给调用者;
//  5.2 状态2: 异步执行失败了,需要在内部调用 失败的回调函数 reject 把结果返回给调用者;
//  5.3 由于 Promise 的实例,是一个异步操作,所以,内部拿到 操作的结果后,无法使用 return 把操作的结果返回给调用者; 这时候,只能使用回调函数的形式,来把 成功 或 失败的结果,返回给调用者;
// 6. 我们可以在 new 出来的 Promise 实例上,调用 .then() 方法,【预先】 为 这个 Promise 异步操作,指定 成功(resolve) 和 失败(reject) 回调函数;


// 注意:这里 new 出来的 promise, 只是代表 【形式上】的一个异步操作;
// 什么是形式上的异步操作:就是说,我们只知道它是一个异步操作,但是做什么具体的异步事情,目前还不清楚
// var promise = new Promise()


// 这是一个具体的异步操作,其中,使用 function 指定一个具体的异步操作
/* var promise = new Promise(function(){
  // 这个 function 内部写的就是具体的异步操作!!!
}) */

const fs = require('fs')

// 每当 new 一个 Promise 实例的时候,就会立即 执行这个 异步操作中的代码
// 也就是说,new 的时候,除了能够得到 一个 promise 实例之外,还会立即调用 我们为 Promise 构造函数传递的那个 function,执行这个 function 中的 异步操作代码;
/* var promise = new Promise(function () {
  fs.readFile('./files/2.txt', 'utf-8', (err, dataStr) => {
    if (err) throw err
    console.log(dataStr)
  })
}) */


// 初衷: 给路径,返回读取到的内容
function getFileByPath(fpath) {
  return new Promise(function (resolve, reject) {
    fs.readFile(fpath, 'utf-8', (err, dataStr) => {

      if (err) return reject(err)
      resolve(dataStr)

    })
  })
}

/* getFileByPath('./files/2.txt')
  .then(function (data) {
    console.log(data + '-------')
  }, function (err) {
    console.log(err.message)
  }) */

使用Promise解决回调地狱

const fs = require('fs')

function getFileByPath(fpath) {
  return new Promise(function (resolve, reject) {
    fs.readFile(fpath, 'utf-8', (err, dataStr) => {

      if (err) return reject(err)
      resolve(dataStr)

    })
  })
}

// 先读取文件1,在读取2,最后读取3
// 注意: 通过 .then 指定 回调函数的时候,成功的 回调函数,必须传,但是,失败的回调,可以省略不传
// 这是一个 错误的示范,千万不要这么用; 硬是把 法拉利,开成了 拖拉机;
/* getFileByPath('./files/1.txt')
  .then(function (data) {
    console.log(data)

    getFileByPath('./files/2.txt')
      .then(function (data) {
        console.log(data)

        getFileByPath('./files/3.txt')
          .then(function (data) {
            console.log(data)
          })
      })
  }) */

// 读取文件1
// 在上一个 .then 中,返回一个新的 promise 实例,可以继续用下一个 .then 来处理


// 如果 ,前面的 Promise 执行失败,我们不想让后续的Promise 操作被终止,可以为 每个 promise 指定 失败的回调
/* getFileByPath('./files/11.txt')
  .then(function (data) {
    console.log(data)

    // 读取文件2
    return getFileByPath('./files/2.txt')
  }, function (err) {
    console.log('这是失败的结果:' + err.message)
    // return 一个 新的 Promise
    return getFileByPath('./files/2.txt')
  })
  .then(function (data) {
    console.log(data)

    return getFileByPath('./files/3.txt')
  })
  .then(function (data) {
    console.log(data)
  }).then(function (data) {
    console.log(data)
  }) */

// console.log('OKOKOK')



// 当 我们有这样的需求: 哪怕前面的 Promise 执行失败了,但是,不要影响后续 promise 的正常执行,此时,我们可以单独为 每个 promise,通过 .then 指定一下失败的回调;

// 有时候,我们有这样的需求,个上面的需求刚好相反:如果 后续的Promise 执行,依赖于 前面 Promise 执行的结果,如果前面的失败了,则后面的就没有继续执行下去的意义了,此时,我们想要实现,一旦有报错,则立即终止所有 Promise的执行;

getFileByPath('./files/1.txt')
  .then(function (data) {
    console.log(data)

    // 读取文件2
    return getFileByPath('./files/22.txt')
  })
  .then(function (data) {
    console.log(data)

    return getFileByPath('./files/3.txt')
  })
  .then(function (data) {
    console.log(data)
  })
  .catch(function (err) { // catch 的作用: 如果前面有任何的 Promise 执行失败,则立即终止所有 promise 的执行,并 马上进入 catch 去处理 Promise中 抛出的异常;
    console.log('这是自己的处理方式:' + err.message)
  })

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值