针对java程序员的前端开发学习说明
Nodejs
Nodejs是什么
Nodejs是javascript的执行引擎,提供的js文件作为运行入口。作为生产使用,尽量选择LTS版本。前端开发过程中大量使用到了html、css和javascript的代码,为了方便开发过程中对这些资源、文件的处理,需要定义一些处理过程,而前端开发人员使用最多的是js,而nodejs是一个js引擎,nodejs的作用和java中的jvm的作用是一致的。
在java开发中,需要对业务的工具进行类的设计,实现对文件的归类,前端组件的设计,资源的维护等。因此有很多前端的工具和框架。全栈工程师则是加上js来编写后端的业务处理过程,就是一套技术就把前后端统一了,因此叫全栈工程师。
Javascript开发常用工具和框架
NPM是什么
在javascript项目的开发中,有大量需要引用的模块,为了管理模块之间的依赖关系,引入了npm。npm安装后就可以使用,第三方模块通过npm命令安装。常用命令如下:
- npm init:初始化项目信息。
- npm install -g -save xxxx: 安装指定模块,-g是全局安装,安装完成后可以直接使用模块提供的命令,-save是将此模块添加到当前项目的依赖中。install可以使用i代替。
- npm list / npm ls:列出项目依赖的所有模块。
- npm uninstall xxx:卸载模块
- npm update xxx:更新模块
NPM仅仅是对模块依赖的管理(当然也集成了其他测试运行等功能)。项目是具体用来做什么的npm不负责管理,对于常见的webserver,资源管理等,npm有常用的模块处理,下面是常见模块的说明。
Webpack
一个web项目常见的内容包括html文件,css文件,js文件以及其他图片等等,利用webpack,可以将这些文件合并,输出为一个更优化的web应用文件。
首先是安装webpack的命令行工具:
npm i -g webpack-cli
然后是在package.json中添加webpack处理的script,下面是样例
{
"name": "empty-project-",
"version": "1.0.0",
"description": "",
"main": "index.js",
"keywords": [],
"author": "",
"license": "ISC",
"scripts": {
"clean": "rm dist/bundle.js",
"build-dev": "webpack -d --mode development",
"build-prod": "webpack -p --mode production"
},
"dependencies": {},
"devDependencies": {
"webpack": "^4.26.0",
"webpack-cli": "^3.1.2"
}
}
执行以下命令即可打包并运行项目
npm install
npm run build-prod
npm run build-dev
node dist/bundle.js
处理的流程是npm调用script,script调用webpack-cli,webpack-cli调用js,利用webpack.config.js中的配置,自动生成最终的成品。
有一些UI工具帮助生成配置文件:https://webpack.jakoblind.no/ 或 https://generatewebpackconfig.netlify.com/
webpack配置说明
下面是使用一个样例说明配置文件的使用
const webpack = require('webpack');
const path = require('path');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const LodashModuleReplacementPlugin = require('lodash-webpack-plugin');
const config = {
// 程序的入口
entry: './src/index.js',
// 程序的输出
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.vue$/, //文件匹配规则,如果匹配,则使用loader中指定的loader
loader: 'vue-loader'
},
{
test: /\.js$/,
loader: 'babel-loader'
},
{
test: /\.css$/,
use: [
'vue-style-loader',
'css-loader'
]
},
{
test: /\.png$/,
use: [
{
loader: 'url-loader',
options: {
mimetype: 'image/png'
}
}
]
}
]
},
resolve: {
extensions: [
'.js',
'.vue'
]
},
plugins: [
new VueLoaderPlugin(),
new LodashModuleReplacementPlugin
]
}
module.exports = config;
从上面可以看出webpack严重依赖于loader,而且loader处理的规则需要参考具体loader的设计。
在webpack中使用css模块
Css模块在使用npm安装后,可以直接使用import命令导入。如安装了weui的包,在使用css类的地方可以直接使用js命令导入:
import from "weui"
Vue
Vue是表现层的框架,使用的方法是引入vue,定义Vue实例,剩下的就是在实例中定义data数据,而在html中使用标签显示要展示的数据。显示层的变量格式是{{ variableName }}。
Vue的生命周期
Vue LifecycleVue的模板语法
Vue的模板信息是添加到html的元素中的(单纯的值是Mustache语法),下面是汇总:
- {{ varName }} : 单纯获取值,varName可以使用单个js语句。
- v-html:当成原始HTML输出。<span v-html="rawHtml"></span>
- <span v-if="seen">现在你看到我了</span>
- <a v-bind:href="url">...</a>可以使用<a :href="url">..</a>代替(:是v-bind的缩写)
- <a v-on:click="doSomething">...</a>可以使用<a @click="doSomething">...</a>代替(@是v-on的缩写)
- v-model用于定义表单的输入对应的变量。
Vue的值除了静态的以外,可以通过计算和方法获取,计算属性在Vue实例的computed属性中定义,里面定义的是function
var vm = new Vue({
el: '#example',
data: {
message: 'Hello'
},
computed: {
// 计算属性的 getter
reversedMessage: function () {
// `this` 指向 vm 实例
return this.message.split('').reverse().join('')
}
}
})
Vue组件
Vue的组件与Vue的主实例类似,接收的选项也相同,下面是一个示例:
Vue.component('button-counter', {
data: function () {
return {
count: 0
}
},
props: ['title'],
template: '<h3>{{ title }}</h3><button v-on:click="count++">You clicked me {{ count }} times.</button>'
})
可以通过下面的html进行使用
<div id="components-demo">
<button-counter title="Button1"></button-counter>
</div>
注意:组件中的data是一个function,而不是普通的属性,是为了保证每个组件实例的变量独立。
组件通过props属性传递参数,建议在props中传递Object,而非单个属性。对于大量数据的传递,推荐使用slot进行。组件的元素必须是单根的,如下面的组件定义就是非法的:
<h3>{{ post.title }}</h3>
<div v-html="post.content"></div>
<div>{{ hugeContent }}</div>
需要通过单根元素包含:
<div class="blog-post">
<h3>{{ post.title }}</h3>
<div v-html="post.content"></div>
<div><slot></slot></div>
</div>
组件可以通过$emit向父级组件触发事件。
Vue可以动态切换组件,类似于java中reflection中的方式,内容比较多,参照https://cn.vuejs.org/v2/guide/components.html#动态组件
定义组件时,名称务必保证字母全小写且必须包含一个连字符,这会帮助你避免和当前以及未来的 HTML 元素相冲突。
Vue.component注册的组件是全局的,可以局部注册组件,但有较多限制。全局注册的行为必须在根 Vue 实例 (通过 new Vue) 创建之前发生
props属性传递参数可以设定参数的具体类型。
props: {
title: String,
likes: Number,
isPublished: Boolean,
commentIds: Array,
author: Object
}
在一个JS文件中编写不同的组件是很难维护的,因此提出了单文件组件的概念,此文件包含html、JS和样式内容,如下所示:
Vue文件组件
Vue文件组件和普通的js组件类似,包含template,script,style的内容。Vue文件组件在使用其他组件时有2中方式,一种是在全局(main.js)导入后使用,另外一种是在文件内部导入后使用,这是一种局部的导入方式。全局导入的方式适合在最终的项目中使用,局部导入的方式适合在组件开发时使用。
Vue工具
为了管理多文件组件,以及和其他构建工具集成,Vue提供了cli,方便大家创建vue项目。最新版的cli版本是3。Vue的cli工具有自己独立的设计,自身使用插件的方式处理资源,原来webpack的处理逻辑被cli工具中的vue-cli-service包装,可以认为vue的cli产生的项目使用常规方式比较难配置。新项目添加步骤如下
- 使用vue create创建基础项目
- cd到项目目录,执行npm run serve可以发布项目做测试
后缀为vue的文件是vue的组件文件,在执行vue-cli-service serve或vue-cli-service build时,cli插件自动将vue文件编译成js代码。
Vue-router
Vue-router是路由管理插件,目的是可以在一个页面中可以自由的切换系统当前的组件。一个未使用router的项目中,web请求的处理流程如下:
image.png
在这个处理过程中可以认为是Vue实例的独立渲染,为了方便管理多个视图,vue-router有自己独立的管理方式。
image.png
为了在vue中使用router,需要定义router,设定
import Router from 'vue-router'
import Dashboard from './views/Dashboard.vue'
Vue.use(Router)
export default new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{
path: '/',
name: 'Dashboard',
component: Dashboard
}
]
})
router中定义的路由需要使用<router-link to="xxx">的方式使用,<router-view></router-view>是路由渲染的位置。
JS语法(针对Java程序员)
基础语法
变量:var xxx,未定义的变量值是undefined,变量可以删除delete xxx
当您声明新变量时,可以使用关键词 "new" 来声明其类型:如var carname=new String;
一条语句,多个变量使用逗号,分开
内置类型:Number,String,Array,Object(Key+Value),function。使用typeof来获取变量类型
分号用于分隔 JavaScript 语句,行最后的分号可以不加分号。JavaScript 对大小写是敏感的。反斜杠对代码行进行换行
使用算术运算符计算值,使用=赋值。+-*
注释使用//或/* */格式
对象属性访问:person.lastName; person["lastName"];
函数样例:function functionname(arg1,arg2) { code; return 0; }
函数可以被赋予为变量,可以调用变量
可以通过(){xxxx; return function(){}}()的方式闭包。xxx中定义的变量只能在此方法内使用
JavaScript 函数有个内置的对象 arguments 对象,包含了函数调用的参数数组。
支持的语句:
- if(condition){}else{}
- switch
- for, for in的语法中,变量的值是属性或数组的索引
- while, do {} while()
- break & continue
- throw、try 和 catch。throw "xxxx"可以抛出异常。
"use strict"; 启用严格模式下你不能使用未声明的变量。
Javascript中没有类的概念,如果需要定义新的类型,直接指定或者使用funtion定义。
保留字:
abstract | else | instanceof | super |
---|---|---|---|
boolean | enum | int | switch |
break | export | interface | synchronized |
byte | extends | let | this |
case | false | long | throw |
catch | final | native | throws |
char | finally | new | transient |
class | float | null | true |
const | for | package | try |
continue | function | private | typeof |
debugger | goto | protected | var |
default | if | public | void |
delete | implements | return | volatile |
do | import | short | while |
double | in | static | with |
ES6
ES6中定义了class,尽量使用class定义
Module 语法是 JavaScript 模块的标准写法
import { func1, func2 } from 'moduleA';
使用const和let定义变量
ES6 新增了箭头函数。(参数1, 参数2, …, 参数N) => { 函数声明 }。箭头函数都没有自己的 this
ES6 函数可以自带参数,参数可以设定为指定值