Webpack+Vue.js快速入门
Pawn Lv2

总有一些孤独需要一个人承受

webpack+Vue.js开发准备

1、webpack简介

官方网站为:https://github.com/webpack/webpack

webpack是一个打包工具,可以把js、css、node、module、coffeescrip、scss/less、图片等都打包在一起。

webpack的安装与使用

通过node.js以及npm包管理工具完成安装:

$  npm install -g webpack

安装weibpack-cli

$ npm install webpack-cli

安装webpack-dev-server

$ npm install webpack-dev-server  -g
  • -g: 代表全局安装
Vue安装

安装Vue和Vue-cli是一样的道理:

$ npm install vue vue-cli -g

2、创建Vue项目及其简介

创建Vue项目使用CMD命令:

cd D:\VueProgram\

通过cd命令符进入你的工作空间。

vue init webpack vuetest

就会在该文件夹下面创建一个名称为vuetest的项目,其目录的结构如下:

然后运行:

$ npm install //安装项目所有的依赖文件
$ npm run build //编译项目所有的文件
$ npm run dev //启动服务器

打开浏览器在,地址栏输出https://localhost:8080就可以之间看到项目运行出来的。

各个文件夹的作用及其简介
build/ //编译用到的各种脚本
config/  //各种配置
dist/   //打包后的各种文件夹
node_modules/  //node的第三方包
src/    //源代码
static/    //静态文件
index.html      //最外层文件
package.json    //node项目配置文件
  • build :该文件夹中保留了各种打包脚本,是不可或缺的,不可以随意的更改。
  • config :与部署和配置有关。
  • dist: 打包之后的文件都在这里。
  • node_modules :node项目所用到的第三方的包特别的多,也特别的大。所有在package.json中定义的第三方包都会被下载到该文件夹内。
  • src :是核心源代码所在的目录。
    1. assets :文件夹用到的图片都可以放在这里。
    2. router/index.js :是路由文件,定义了各个页面对应的url。
    3. components :用到的视图和组件所在的文件夹(核心)。
    4. APP.vue :就是二级页面的模板。所有其他页面的VUE.js页面都应该作为该模板的一部分被渲染出来。
    5. main.js :没有实际的业务逻辑,但是为了支撑整个Vue.js框架,很有必要存在。

Webpack+Vue.js实战

1、创建页面

创建页面的步骤有两步:

  • 创建路由
  • 新建Vue页面
新建路由

默认路由页面是在src/router/index.js页面中,将其打开后,增加两行:

import Vue from 'vue'
import Router from 'vue-router'
import SayHi from '@/components/SayHi'

//增加这一行,作用是引入'@/component/HelloWorld'
//@表示当前目录
Vue.use(Router)

export default new Router({
  routes: [
      //增加一下几行,表示定义了  /#/helloword 这个 url
    {
      //对应一个url
      path: '/say_hi',
       //vue.js内部使用的名称
      name: 'SayHi',
        //对应的.vue页面的名字
      component: SayHi
    }
  ]
})

当用户浏览器访问https://localhost:8080/#/say_hi的时候,就会渲染.components/SayHi.vue文件

创建一个新的组件

src/components/创建SayHi.vue:

<template>
    <div>
        Hi Vue
   </div>
</template>
<script>
    export default{
        data (){
            return{

            }
        }
    }
</script>
<style>
</style>

此时输入http:\\localhost:8080/#/say_hi

每次创建一个的新的组件的记得使用import SayHi from '@components/SayHi'

为组件创建样式

修改SayHi.vue文件:

<template>
    <div class="hi">
        Hi Vue
   </div>
</template>
<script>
    export default{
        data (){
            return{

            }
        }
    }
</script>
<style>
    .hi{
        color:red;
    }
</style>

刷新浏览器就可以发现样式发生了改变。

由于webpack服务器的便捷操作,每次进行修改的时候都不用重启服务器,直接刷新浏览器就可以看到修改的内容

Vue.js中的ECMAScript

在以.vue为后缀的文件中,可以明显的看出来使用的不是JavaScript,而是ECMAScript,严格来说ECMAScript是JavaScript的规范,JavaScript是ECMAScript的实现。ECMAScript的简称是ES,其版本众多,很多时候用ES6来泛指。

1、ES6的简单入门

let、var

声明本地变量,使用var、let:

  1. var :有可能引起变量的提升,或者块级作用域的问题;
  2. let :就是为了解决上面两个问题而提出的;

多用let,少用var,遇到诡异变量的问题,就查一查是不是var的问题。

var title='标题' ;
let title='标题';
title='标题'   //此时会报错处理

在webpack下面的Vue.js中使用任何的变量,都要使用var和let来声明

常量和全局常量

常量使用const 标识符定义:

const title='标题';

全局常量需要在index.html中进行定义即可:

window.title="我的博客列表";
导入代码

import 用于导入外部的代码:

import Vue from 'vue'
import Router from 'vue-router'

目的是引入vue和vue-router(由于他们是在package.json中定义的,所以可以直接import ... from <包名> ,否则需要加上路径

import SayHi from '@components/SayHi'
  • 在from后面添加@符号,表示是在本地文件系统中引入文件。@代表源代码目录(一般是src)。
export default{}

在每个Vue的<script>标签中都会存在export default{}代码,作用是方便其他代码对这个代码进行引用。对于ES6之前,js没有统一的模块定义方式。

假设有lib/math.js文件:

export function sunm(x,y){
    return x+y;
}
export  var pi=3.1415926;

lib/math.js可以导出的有两个内容一个是函数sum(x,y),一个是变量pi

导出的方式也有多种:

import  *  as math from "lib/math"
alert("2π="+math.sum(math.pi,math.pi));
import {sum,pi} from "lib/math"
alert("2π="+sum(pi,pi))

export defult{}暴露的是一段没有名字的代码,而export function{}暴露的则是一段有名字的代码。

ES中的简写

<script>
    export default {
        data(){
            return {}
        }
    }
</script>

实际上等同于:

<script>
    export default{
        data:function(){
            return {}
        }
    }
</script>
箭头函数

ES可以通过箭头表示函数:

.then(response=>...);

等同于:

.then(function(response){});

这样写的好处在于,强制定义了作用域,使用=>可以避免很多的作用域的问题。

hash中同名的key/value简写
let title='tripe body'

return {
title:title
}

等同于:

let title='tripe body'

return {
    titile
}
分号可以省略
var a=1
var b=1;

解构赋值

let person={
    firstname:'seteve',
    lastname:'curry',
    age:29,
    sex:'man'
};

然后可以这样定义:

let {firstname,lastname}=person
//上面的代码等同于
// let firstname=person.firstname
//let lastname=perosn.lastname

Vue.js渲染页面的过程和原理

1、渲染过程1:js入口文件

./build/webpack.base.conf.js是webpack打包的配置文件。

'use strict'
const path = require('path')
const utils = require('./utils')
const config = require('../config')
const vueLoaderConfig = require('./vue-loader.conf')

function resolve (dir) {
  return path.join(__dirname, '..', dir)
}

const createLintingRule = () => ({
  test: /\.(js|vue)$/,
  loader: 'eslint-loader',
  enforce: 'pre',
  include: [resolve('src'), resolve('test')],
  options: {
    formatter: require('eslint-friendly-formatter'),
    emitWarning: !config.dev.showEslintErrorsInOverlay
  }
})

module.exports = {
  context: path.resolve(__dirname, '../'),
    //这里就定义了Vue.js 的入口文件
  entry: {
    app: './src/main.js'
  },
  output: {
    path: config.build.assetsRoot,
    filename: '[name].js',
    publicPath: process.env.NODE_ENV === 'production'
      ? config.build.assetsPublicPath
      : config.dev.assetsPublicPath
  },
  resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
      'vue$': 'vue/dist/vue.esm.js',
      '@': resolve('src'),
    }
  },
  module: {
    rules: [
      ...(config.dev.useEslint ? [createLintingRule()] : []),
      {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: vueLoaderConfig
      },
      {
        test: /\.js$/,
        loader: 'babel-loader',
        include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
      },
      {
        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: utils.assetsPath('img/[name].[hash:7].[ext]')
        }
      },
      {
        test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: utils.assetsPath('media/[name].[hash:7].[ext]')
        }
      },
      {
        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
        }
      }
    ]
  },
  node: {
    //防止Webpack注入无用的setImmediate polyfill,因为Vue源包含它(尽管仅在其本机时才使用它)。
    setImmediate: false,
    // 防止webpack将模拟注入到对客户端没有意义的Node本机模块
    dgram: 'empty',
    fs: 'empty',
    net: 'empty',
    tls: 'empty',
    child_process: 'empty'
  }
}
module.exports = {
  context: path.resolve(__dirname, '../'),
    //这里就定义了Vue.js 的入口文件
  entry: {
    app: './src/main.js'
  },
    ...
}

2、渲染过程2:静态的HTML页面(index.html)

每次打开服务器的时候显示的URL是http:localhost:8080/#/ ,实际上打开的文件是http://localhost:8080/#/index.html ,所以找到index.html的时候,就可以看其内容:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>vuetest</title>
  </head>
  <body>
    <div id="app"></div>

  </body>
</html>

这里的<div id="app"></div>就是将来会动态变化的内容。特别类似于Rails和layout(模板文件)。这个index.html文件是最外层的模板

3、渲染过程3:main.js中的Vue定义

import Vue from 'vue'
import App from './App'
import router from './router'

Vue.config.productionTip = false

new Vue({
    //app对应着'<div id="app"></div>''
  el: '#app',
  router,
  components: { App },
    //这里,APP就是.src/App.vue
  template: '<App/>'
})

熟悉jquery、css selector的读者可以看到,el:"#app"就是index.html就是<div id="#app"></div>

上面的App.vue会被main.js加载,App.vue的内容如下:

<template>
  <div id="app">
    <img src="./assets/logo.png">
    <router-view/>
  </div>
</template>

<script>
export default {
  name: 'App'
}
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

上面的代码就是<template />的第二层模板,可以认为该页面的内容就是在这个位置被渲染出来。

上面的代码中还有,<div id='app'></div>,该元素与index.html中的是用一个元素。

所有<router-view>中的内容都会被自动替换。<script>中代码则是脚本代码。

4、视图中的渲染

渲染某个变量
<script>
    export default{
        data(){
            return {
                my_value:'默认值'
            }
        }
    }
</script>

可以这样来显示它:

<template>
    <div>
        {{message}}
    </div>
</template>
方法的声明和调用
<script>
    export default{
        data(){
            return{
                my_value:'默认值'
            }
        },
        methods:{
            show_my_value:function(){
                alert('my_value'+this.message);
            }
        }
    }
</script>

调用上面的方法:

<template>
    <div>
        <input type='button' @click="show_my_value()" value="..." />
    </div>
</template>

事件处理:v-on

@click='show_message()'等同于v-on:click="show_message()"

5、视图中的Directive(指令)

Vue.js是一种javascript框架,所以只能与标签结合使用,叫做Directive(指令)。

在directive中使用表达式
  • 表达式:a>1(有效)
  • 普通语句:a=1;(这个是声明,不会生效)
  • 控制语句:returna;(不会生效)

在所有的Directive中,只能使用表达式

<div v-if="a>100"></div>
循环:v-for
<ul>
    <li v-for="tech in technologies">{{tech}}</li>
</ul>
var vm=new Vue({
    data:{
        technologies:['nvm','npm','node','webpack','ecma_script']
    }
})
判断:v-if
<div v-if="name==='Vue.js'">
    Vue.js
</div>
<div v-else-if="name==='angular'">
    Angular
</div>
<div v-else>
    React
</div>
var app=new Vue({
    el:"#app",
    data:{
        name:"Vue.js"
    }
})

v-if后面的引号中的是name==='Vue.js',===是ECMAScript的语言,表示严格判断。

v-if和v-for的优先级

当v-if与v-for一起使用的时候,v-for有与比v-if更高的优先级。也就是说,Vue.js会先执行v-for,再执行v-if。

v-bind

v-bind指令用于把某个属性绑定到对应的元素属性。

<p v-bind:style="'color:'+my_color">Vue.js 学起来好开心~ </p>
v-on
<input type="button" v-on:click="show_message()" value="点击点击" />
var app=new Vue({
    el:"#app",
    data:{
        message:"学习Vue使我快乐"
    },
    methods:{
        show_message:function(){
            this.message=this.message+"是的,你的工资还会涨的~"
        }
    }
})

v-on后面可以接HTML的标准事件:

  • click
  • dbclick
  • contextmenu(单击鼠标右键)
  • mouseover
  • mouseout
  • keydown
  • keyup
v-modal与双向绑定
<input type="text" v-modal="name" />
var app=new Vue({
    el:"#app",
    data:{
        name:"Vue.js(默认)"
    }
})

6、发送Http请求

Vue.js内置了对发送Http请求的支持,主要在对应的页面的script标签内加上对应的代码就可以了。但是Vue.js2.0要求使用第三方库—axios。

在使用第三方的库axios的时候,首先需要安装axios。利用命令行的工具,然后cd到项目所在的文件夹,使用:

npm install axios

然后在main.js文件中引入axios库:

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'


Vue.config.productionTip = false;
//将http的引用源头指向axios
Vue.prototype.$http = require('axios');
/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
})
<template>
    <div>
        <table>
            <tr v-for="blog in blogs" >
                <td></td>
            </tr>
        </table>
    </div>
</template>
<script>
    export default{
        data(){
            return {
                title:"我的博客",
                blogs:[]
            }
        },
  mounted() {
    this.$http.get("http://39.107.141.202:8086/query?u=yjf&p=123456",{
          params:{
             db: "sensor_statue",
             q: 'SELECT * FROM "sensor_statue"."autogen"."sensorid" order by time desc limit 298 ', 
         }
      },)
      .then(response => {
        let data=response.data.results[0].series[0].values;
        this.msg=data;
        console.log(response.data.results[0].series[0]);
      })
      .catch(reponse=>{
          console.log(reponse.body);
      })
  }
};
    }
</script>
<style>
    td{
        border-bottom:1px solid gray
    }
</style>
  • mouted 是Vue声明周期的中的钩子函数,表示的是:页面加载完毕之后应该干哪些事

  • this.$http.get(url,{params})表示的发送get请求。其中url的格式为字符串,params的格式为JSON字符串。

  • then(response=>{}) 表示的是请求成功的时候回调其中的函数;response代表的是返回的http协议中的请求体。

  • catch(response=>{})表示的请求失败的时候回调其中的函数;

设置Vue.js开发服务器中的代理

因为http协议的cookie中的限制,导致请求只能在同域中进行访问。正常来讲,JavaScript在浏览器中是无法发送跨域请求的。需要在Vue.js的“开发服务器”上作转发配置。

修改config/index.js文件,增加下列内容:

module.exports={
    dev:{
        proxyTable:{
             // 1.对所有以"/api"开头的url做处理
      '/api':{
        //3.将请求转发到http://siwei.me上面
        target:'http://siwei.me',
        changeOrigin:true,
        pathRewirte:{
          //2.将url中的"/api"替换成''
          '^/api' :''
        }
      }
        }
    }
}

此时请求的变成了:

发送post请求

与get类似,就是第二个参数是请求的body。

axios.post('/user', {
    firstName: 'Fred',        // 参数 firstName
    lastName: 'Flintstone'    // 参数 lastName
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

如果Web服务器无法处理编码为application/json的请求,你可以启用emulateJSON选项。

axios.post('/user', {
    firstName: 'Fred',        // 参数 firstName
    lastName: 'Flintstone'    // 参数 lastName
  },{emulateJSON:true})
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

7、不同页面间的参数传递

在普通的web项目开发中,参数的传递有以下的几种形式:

而在vue.js中,不会产生表单的提交(会引起页面的整体提交),有以下两种:

  • url同传统的语言,参数在url中
  • Vue.js内部的机制

8、路由

基本用法

每个vue页面都要对应一个路由的。添加路由的方式:src/router页面中添加路由信息,在src/components/book.vue添加页面

import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import SayHi from '@/components/SayHi'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/HelloWorld',
      name: 'HelloWorld',
      component: HelloWorld
    },
    {
      path: '/say_hi',
      name: 'SayHi',
      component: SayHi
    }
  ]
})
跳转到某个路由时带上参数

普通参数

routes:[{
    path:'/blog',
    name:'Blog'
}]

在视图中执行:

<router-link :to="{name:'Blog',query:{id:3}" >User</router-link>

<script>中:

this.$router.push({name:'Blog',query:{id:3}})

最后都会跳转到http:/localhost:8080/vuetest/#/blog?id=3

获取路由中的参数:

this.$router.query.id//获取普通的参数
this.$router.params.id//获取路由信息中定义好的参数
  • Post title:Webpack+Vue.js快速入门
  • Post author:Pawn
  • Create time:2020-04-23 12:18:32
  • Post link:https://panhao.work/2020/04/23/Webpack-Vue-js快速入门/
  • Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.