songhlc / blog Goto Github PK
View Code? Open in Web Editor NEW写博客呀来来来
写博客呀来来来
常见的搜索输入框,输入一个字符之后会调用后台的服务传入关键字进行查询。
以往实现,监听输入框的keydown/change事件,当输入参数改变的时候触发keydown事件,获取当前输入的参数然后调用后端服务。
该事件类似于 onchange 事件。不同之处在于 oninput 事件在元素值发生变化是立即触发, onchange 在元素失去焦点时触发。
浏览器兼容性:现代浏览器, IE9+(ie9以下需要用onpropertychange来代替)
<input type="text"
v-model="inputtext"
@input="input"
placeholder="请试试中文输入法和英文输入法">
input: function (val) {
if (this.inputtext != this.inputvalue) {
console.log("doquery:" + this.inputtext)
this.inputvalue = this.inputtext
//使用inputvalue进行查询
}
}
//vue 2.1.4
//line 5433
el.addEventListener('compositionstart', onCompositionStart);
el.addEventListener('compositionend', onCompositionEnd);
line 5511
function onCompositionEnd (e) {
e.target.composing = false;
trigger(e.target, 'input');
}
原来在compositionend之后手动触发了input方法
vue 1.0.26
line 4721
this.on('compositionend', function () {
composing = false;
// in IE11 the "compositionend" event fires AFTER
// the "input" event, so the input handler is blocked
// at the end... have to call it here.
//
// #1327: in lazy mode this is unecessary.
if (!lazy) {
self.listener();
}
});
似乎好像明白了什么
input + compositionend 来联合解决这个问题
<input type="text"
v-model="compositiontext"
@input="compositioninput"
@compositionend="compositionend" placeholder="请试试中文输入法和英文输入法">
compositioninput: function (val) {
if(this.compositionvalue != this.compositiontext) {
console.log("do query:" + this.compositiontext)
this.compositionvalue = this.compositiontext
}
},
compositionend: function(val) {
console.log("do query:" + this.compositiontext)
this.compositionvalue = this.compositiontext
}
复合事件(composition event)是DOM3级事件中新添加的一类事件,用于处理IME的输入序列。IME(Input Method Editor,输入法编辑器)可以让用户输入在物理键盘上找不到的字符。复合事件就是针对检测和处理这种输入而设计的。
compositionstart:在IME的文本复合系统打开时触发,表示要开始输入了。
compositionupdate:在向输入字段中插入新字符时触发。
compositionend:在IME的文本复合系统关闭时触发,表示返回正常键盘的输入状态。
结语: 遇到问题 + 解决问题 = 提升。其实不仅仅是vue,本身input+compositionevent都是解决不同IME输入的统一解决办法
这里其实我有一点混乱,到底是因为我使用组件的问题还是其他问题,后续来更正
vue1.0中用于属性转换,可以看到在vue-strap里有了大量的使用,主要通过计算属性来解决了
其实不管是以往在使用vux还是其他第三方组件的时候,使用了大量的.sync来双向绑定,官方的解释是只保留了单向数据流的绑定,如果子组件需要影响父组件则需要通过事件派发的机制,降低了子组件和父组件的耦合
本质上 render function和写一个模版是等价的,但是具体为什么要新增render,等我深入了解后再来解答吧。
用全局事件或vuex代替
这里有一个帮助从vue1.x升级到vue2.0的开源项目,号称是能够覆盖80%需要升级的内容,对于老项目来说是一个很不错的选择哦
PS:关于vue2.0 UI框架的选择:
个人目前决定pc端UI框架从vue-strap转移到element UI上,毕竟基于vue2.0开发,而且vue-strap的文档我一直觉得不够友好。另外如果有其他好的项目,也希望大家推荐给我。
最近看的几篇文章列一下,开始实践之后再回头来看看
1.你是如何构建 Web 前端 Mock Server 的?
2.web开发模式的演变-玉伯
3.前后端分离思考与实践
使用es6+简单的vue componet
点我看效果
1.创建工程,引入依赖npm init //引入vue npm install vue --save-dev //引入 vue router npm install vue-router --save-dev
2.创建如下目录结构
assert
build
dist
src
|--pages
|----index
|------index.vue
|----setting
|------setting.vue
|--main.js
test
index.html
package.json
3.index.html结构
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=0">
<title>vue-router</title>
</head>
<body>
<div id="app">
<h1>header</h1>
<hr>
<!-- 路由外链 -->
<router-view></router-view>
<hr>
<h2>footer</h2>
</div>
<script src="dist/build.js"></script>
</body>
</html>
4.main.js
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
// 创建一个路由器实例
// 创建实例时可以传入配置参数进行定制,为保持简单,这里使用了一个记住滚动条位置的配置 随意忽略吧
var router = new VueRouter({
saveScrollPosition: true
})
//定义页面路由,这里url路由切换到/index 会加载index.vue
//然后将组件内容替换html中的<router-view></router-view>
router.map({
'/index':{
component:require("./pages/index/index.vue")
},
'/setting':{
component:require("./pages/setting/setting.vue")
}
})
var App = Vue.extend({})
router.start(App, '#app')
window.router = router
5.index.vue/setting.vue
//index.vue
<script>
export default {}
</script>
<template>
<div class="content">
<p>i am page index</p>
<a v-link="{path:'/setting'}">跳转到setting</a>
</div>
</template>
<style scoped>
p{color:red;}
</style>
//setting.vue
<script>
export default {}
</script>
<template>
<div class="content">
<p>i am page setting2</p>
<a v-link="{path:'/index'}">index</a>
</div>
</template>
<style scoped>
p{color:black;}
</style>
以上,所有的代码就编写完了
6.然后开始配置webpack相关的东西咯,这里不去详解把我package.json的配置直接贴出来了。
基本就是引入babel解析es6 引入vue-loader解析.vue文件,引入vue-hot-reload-api方便开发时候调试。
//依赖配置
"devDependencies": {
"babel-core": "^6.10.4",
"babel-loader": "^6.2.4",
"babel-plugin-transform-runtime": "^6.9.0",
"babel-preset-es2015": "^6.9.0",
"babel-preset-stage-0": "^6.1.2",
"babel-runtime": "^6.0.0",
"css-loader": "^0.23.1",
"style-loader": "^0.13.1",
"vue-hot-reload-api": "^1.2.0",
"vue-html-loader": "^1.2.3",
"vue-loader": "^8.5.3",
"vue-style-loader": "^1.0.0",
"webpack": "^1.13.1",
"webpack-dev-server": "^1.14.1"
}
//运行配置
"scripts": {
"dev": "webpack-dev-server --inline --hot --config build/webpack.dev.config.js",
"build": "webpack --progress --hide-modules --config build/webpack.prod.config.js"
}
这里要注意一下vue-hot-reload-api的版本,别引入2.x的版本,2.x的版本是专门给vue2.0用的 这点要注意。
7.运行看一看
npm install
npm run build
npm run dev
然后访问http://localhost:8080/index
点击切换看一看咯,就是如此简单
引:flexbox布局的出现解决了以往float布局以及inline-block布局遗留的问题,本文先针对inline-block布局出现的元素间空白的问题做出描述
文章原文:https://css-tricks.com/video-screencasts/
问题现象:当你对一系列的内联元素进行普通的格式化时,这些内联元素之间就出现了空白。
比如:
HTML
<nav>
<a href="#">One</a>
<a href="#">Two</a>
<a href="#">Three</a>
</nav>
CSS
nav a {
display: inline-block;
padding: 5px;
background: red;
}
结果
我们通常希望这些元素紧密的连接在一起,在使用到导航时不会出现中间不可点击的空白区域。
这其实并不是一个bug(至少作者认为),这只是设置这些元素在同一行显示的一种方式。我们通常也希望在文字和文字之间存在空格以方便阅读。这并不意味着这些文字之间的空格不应该存在,但我相当肯定,如果休整了它就能够解决一系列的问题。
产生以上现象的原因,因为你的这些元素之间存在着空格,可能是换行符,也可能是tab产生的空格。压缩html代码可以解决这个问题,或者像下面这样的小戏法
HTML
<ul>
<li>
one</li><li>
two</li><li>
three</li>
</ul>
或者
HTML
<ul>
<li>one</li
><li>two</li
><li>three</li>
</ul>
或者使用注释
<ul>
<li>one</li><!--
--><li>two</li><!--
--><li>three</li>
</ul>
你可以给元素设置一个-4px的margin。
nav a {
display: inline-block;
margin-right: -4px;
}
当然,这会让你感觉怪怪的。
<ul>
<li>one
<li>two
<li>three
</ul>
nav {
font-size: 0;
}
nav a {
font-size: 16px;
}
ps:Android端不起作用
或许并不需要把元素设置成inline-block,设置成浮动就好了。你同样可以设置宽度高度padding和其他一些特性,只不过不能使用text-align:center;内敛元素的父元素。你可以这么做,就是还是优点奇怪。
当 浏览器支持 的情况下
参考demo
编者注:每个东西出现总有其必然性,了解背后的原因能帮你更好的了解它
学习前端大全的文章,顺带了解一下自己并不懂的时间冒泡,需要好好把js的基础知识恶补一下了。
事件流包含三个部分:事件捕获,处于目标,事件冒泡
新插入的子元素没有绑定点击事件(具体怎么解决,用事件委托,委托给他的父级容器)
如果目标有子元素,怎么办?
event.target可能变成了他的子元素,这里有一个css的解决方式,假定li.item 是要绑定的元素;
li.item > *{
pointer-events:none;
}
实际上以上常见的坑在jquery已经都帮我们处理掉了,就安心的直接使用delegate或者
$("ul").on("click","li.item",function(events){
//do your things
})
就可以了
前后端分离之本地mock-server
前后端分离之后,前端不依赖于后端服务的进度,在前后端定义好json接口之后,就可以开始开发了。
基于json-server我们可以很方便的定义好本地调用的restful服务,然后在前端通过proxy,修改服务调用即可。
$ npm install -g json-server
{
"posts": [
{ "id": 1, "title": "json-server", "author": "typicode" }
],
"comments": [
{ "id": 1, "body": "some comment", "postId": 1 }
],
"profile": { "name": "typicode" }
}
$ json-server --watch db.json
默认json-server会启动本地3000端口。
通过访问http://localhost:3000/posts/1, 会返回以下数据
{ "id": 1, "title": "json-server", "author": "typicode" }
以当前项目例子,实际后台服务访问路径为
http://localhost/yuncai/qutate/loaddata
然后json-server 初步使用发现json-server好像不支持超过三层路径的访问
{
"qutate/getdata": [
{ "id": 1, "title": "json-server", "author": "typicode" }
],
"yuncai/qutate/loaddata": [
{ "id": 1, "body": "some comment", "postId": 1 }
],
"profile": { "name": "typicode" }
}
通过以上定义的db.json
通过下面的url,可以正常返回数据。
http://localhost:3000/qutate/getdata
但通过下面的url则返回结果为{}
http://localhost:3000/yuncai/qutate/loaddata
还没有深入研究详细原因,目前暂时通过配置routes.json的方式来解决。
1. 在本地创建routes.json
2. 启动参数改成 json-server db.json --watch --routes routes.json
3. 访问http://localhost:3000/yuncai/qutate/loaddata 成功返回数据
http://localhost:3000/qutate/getdata/1 //返回id 为1 的数据
http://localhost:3000/qutate/getdata?title=json-server //返回title字段等于json-server的数据
以上就能用最简单的方式搭建起本地的mock-server 进行前后端分离的调试啦。
本地可以使用proxy或者nginx都可以进行跳转啦,详细的会在下一篇文章进行介绍
一入vue 终身脑残粉
持续关注vue 2.0(github vue-next 分支下的内容)
于是关注到 readme 中的 Pull Request Guidelines中关于代码风格的描述,原文如下:
翻译如下:
// good way
var variable1 = "Hello World!";
var variable2 = "Testing...";
var variable3 = 42;
// not recommend way
var variable1 = "Hello World!",
variable2 = "Testing...",
variable3 = 42;
var a = superLongConditionalStatement
? 'yep'
: 'nope'
总结启示再使用eslint的时候以上的代码风格都是需要遵循的,所以这里看完后并没有太多严格的地方,最严格的在最后一句,读源代码,参考它原有的方式
为什么选择vue,因为实在太轻量,太好学了。里面组件化开发的**再加上指令和过滤器,以及自带的一些动画效果,上手起来比react学习成本低很多,在已有hybrid app的经验下结合移动的场景非常适合,并且和第三方框架集成的也很好。后续会逐步结合正在做的云采超市app 点我看演示demo04/a111111 ,从一个更简化的思路去学习vue。PS:官方文档写的很棒,大家可以进行参考。
<div id="app">
{{ message }}
</div>
new Vue({
el: '#app',
data: {
message: 'Hello Vue.js!'
}
})
最终效果
<div id="app">
<ul>
<li v-for="todo in todos">
{{ todo.text }}
</li>
</ul>
</div>
new Vue({
el: '#app',
data: {
todos: [
{ text: 'Learn JavaScript' },
{ text: 'Learn Vue.js' },
{ text: 'Build Something Awesome' }
]
}
})
<div id="app">
<input v-model="newTodo" v-on:keyup.enter="addTodo">
</div>
new Vue({
el: '#app',
data: {
newTodo: '',
todos: [
{ text: 'Add some todos' }
]
},
methods: {
addTodo: function () {
var text = this.newTodo.trim()
if (text) {
this.todos.push({ text: text })
this.newTodo = ''
}
}
}
})
以上就是一个最简单的vue的数据绑定的简单实例,利用这些就可以完成最简单的双向数据绑定的例子了。
ps:关于重复绑定,在构造vue实例 new Vue()的时候会指定需要绑定到的元素el:"#app" ,之前在使用knockout的时候存在限制,相同的元素或自元素不允许存在重复绑定。但对于vue来说,目前暂时好像没有遇到此类限制,不过后续用到组件化开发的过程还是会通过不同组件的作用域来处理此类问题的。
《js函数式编程》
书在这,先拿去自己看。
书里面提到 了一些简要的概念,乘热打铁。
1.纯函数。
所为纯函数就是同样的输入永远产生同样的输出,不会受到任何输入值的影响,这样的函数就是纯函数。纯函数的好处,当然就是上下文简单,可测试,可预测。
举个例子
function add(a,b){
return a+b
}
再来看一个不纯的函数
var count = 0
function addwithCount(a,b){
count++
return a + b + count
}
很明显第一次调用addwithCount(0,1)和第二次调用addWithCount(0,1)明显产生的结果是不一样的。
这里不纯的函数就会产生副作用,至于具体的副作用那就看代码有多不纯了。
哦啦 一次学的东西不要太多,我们后续会慢慢展开讨论。
当然 第一次看这书的时候我对于书里的习题是一列懵逼不会写的。所以还是要多实践。
下一节见
在做混合式App/web app 通常一般开发时会通过chrome或者android/ios模拟器进行调试。
但实际上有些问题在chrome和模拟器上跑的好好的,放到真机上就见了鬼了。所以怎么在真机上调试就真是一件很头疼的事,以下结合自己在做移动应用时的实践经验简单分享一下。
以上,不论是直接用chrome访问,还是打开app使用app里内嵌的webview 都是可以做到真机调试的。
如果有遇到问题欢迎反馈。
希望对大家有用。
推荐一款目前团队在用的一个在线敏捷看板
leangoo
目前来说基本能满足我的需求:
场景、故事、工作量、团队成员、检查项(需求验证条目)、截止时间、标签、燃尽图
毕竟有一个敏捷看板对于当前项目所处状态的把握还是很好的。
关于敏捷开发是否重要,当然不是我本文需要讨论的内容,毕竟敏捷开发对于快速迭代的好处毋庸置疑。如何更好的使用工具去辅助我门的开发事一件必然的事情。
不断学习进步中
=====
不愿意的加班的前端不是好前端,好前端是会找办法让团队尽量少的加班的。
=====
CommonsChunkPlugin用于将一个传统的js应用拆分成不同的模块,并在重用公共依赖的模块
它非常适合用于开发一个由很多页面组成的应用(无论是传统的页面或者是页面路由)
1.单入口文件
在使用webpack时,通常会把所有的代码都打包到一个入口文件entry.js 之中。当项目规模比较小的时候并没有什么,但如果项目规模比较大里之后,这就意味着在不同页面会有一堆无用的代码被引用。
//不存在代码分割
entry.js
- app
- page1
- page2
- jquery
- underscore
- moment
进行代码分隔之后在entry.js之中只需要引入启动工程所必须的代码,对于每一个页面则只引入页面需要的代码。
entry.js
- app
- jquery
- underscore
page1.js
- page1
- jquery
- moment
page2.js
- page2
- underscore
问题:jquery和underscore引用重复了
CommonsChunkPlugin的出现就是为了更高效的解决这些外部的依赖关系
3.优化后的结构
entry.js
- app
- jquery
- underscore
page1.js
- page1
- moment
page2.js
- page2
在这个示例中,juqery和underscore因为众多页面都有对它的依赖,所以移入了入口文件entry.js之中。
在webpack中,通过给plugin添加一个webpack.optimize.CommonsChunkPlugin实例来实现,如下:
// webpack configuration
const webpack = require("webpack");
module.exports = {
entry: {
entry: './app.js'
},
output: {
...
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
// name of the entry chunk to scan for common (shared) dependencies
// the common dependencies will be moved into this entry chunk
name: 'entry',
// indicate that we want to scan for common dependencies in
// child (code split) chunks of the named entry chunk
children: true,
// minimum number of different chunks (entry or split) which a dependency
// must be used by to deem it a common dependency
minChunks: 2
})
]
};
关于其他更多的CommonsChunkPlugin的配置请看
http://webpack.github.io/docs/list-of-plugins.html#commonschunkplugin
ps:后续会更新vue-cli 创建的webpack模板的例子解析
vue组件在这里是可扩展的html自定义元素,封装可复用的代码。比如
<div id="example">
<my-component></my-component>
</div>
var MyComponent = Vue.extend({
// 选项...
})
// 全局注册组件,tag 为 my-component
Vue.component('my-component', MyComponent)
var Child = Vue.extend({ /* ... */ })
var Parent = Vue.extend({
template: '...',
components: {
// <my-component> 只能用在父组件模板内
'my-component': Child
}
})
组件实例的作用域是孤立的。这意味着不能并且不应该在子组件的模板内直接引用父组件的数据。可以使用 props 把数据传给子组件。
Vue.component('child', {
// 声明 props
props: ['msg'],
// prop 可以用在模板内
// 可以用 `this.msg` 设置
template: '<span>{{ msg }}</span>'
})
<child msg="hello!"></child>
<child v-bind:my-message="parentMsg"></child>
例子:
<app>
<app-header></app-header>
<app-footer></app-footer>
</app>
疑问:如果app下也有自己的模板,怎么处理。
<my-component>
<p>This is some original content</p>
<p>This is some more original content</p>
</my-component>
<div>
<h1>This is my component!</h1>
<slot>
如果没有分发内容则显示我。
</slot>
</div>
<div>
<h1>This is my component!</h1>
<p>This is some original content</p>
<p>This is some more original content</p>
</div>
<div>
<h1>This is my component!</h1>
</div>
====
以上就是个人觉得初识vue需要了解到的vue 组件相关的一些细节,其实还有很多详细的内容,都欢迎到官网进行查看吧。
下一篇计划是介绍一下vue-router并结合vue-router来做一个spa webapp,敬请期待咯
上篇主要简单介绍了vue简单数据绑定的一些基础,本篇对vue的事件监听、指令和过滤器做一些简单的介绍。
<div id="example">
<button v-on:click="greet">Greet</button>
</div>
同时在js里定义这个方法
var vm = new Vue({
el: '#example',
data: {
name: 'Vue.js'
},
// 在 `methods` 对象中定义方法
methods: {
greet: function (event) {
// 方法内 `this` 指向 vm
alert('Hello ' + this.name + '!')
// `event` 是原生 DOM 事件
alert(event.target.tagName)
}
}
})
ps:你也可以在js里这么调greet方法
vm.greet();
Vue.filter('reverse', function (value) {
return value.split('').reverse().join('')
})
<!-- 'abc' => 'cba' -->
<span v-text="message | reverse"></span>
综合以上例子,过滤器可常用于,显示格式的转换,比如价格显示精度处理,格式转化等等通用场景都可以使用过滤器的方式来处理
Vue.filter('currencyDisplay', {
// model -> view
// 在更新 `<input>` 元素之前格式化值
read: function(val) {
return '$'+val.toFixed(2)
},
// view -> model
// 在写回数据之前格式化值
write: function(val, oldVal) {
var number = +val.replace(/[^\d.]/g, '')
return isNaN(number) ? 0 : parseFloat(number.toFixed(2))
}
})
另外过滤器还支持动态参数。具体详细查看 动态参数
===============下章节计划介绍component的内容===============
《提问的智慧》
如何提问,如何描述一个问题,如何降低沟通成本。
有时候开发老反馈,测试提的问题描述看不懂。
我做过一年的测试,对这方面也感触颇深,降低沟通成本,让对方更容易懂你,绝对是对双方都有好处的。推荐看一看上面这本《提问的智慧》,会让你收获颇多。
前端面试过程中经常都会问一个问题:一个元素如何实现水平垂直居中?
这里我们抛开技术层面的实现,直接从实际业务角度,通过不同的场景来回答这个问题,毕竟任何技术都是为了业务服务的,有了具体业务,也方便我们更好的去实践。
直接看代码,所有demo地址
<article>
<p class="title"><span>我是title</span></p>
<p class="content">我是文章的内容,我通常来说会有多段去显示</p>
</article>
<style>
.demo1 .title{
text-align: center;
}
</style>
<table>
<thead>
<th>姓名</th>
<th>年龄</th>
<th>性别</th>
<th>个人描述</th>
</thead>
<tbody>
<tr>
<td>张三</td>
<td>18</td>
<td>男</td>
<td>我通常来说会超过一行所能显示的内容</td>
</tr>
<tr>
<td>张三</td>
<td>18</td>
<td>男</td>
<td>我通常来</td>
</tr>
</tbody>
</table>
<style>
table td{
border:solid 1px #eee;
vertical-align: middle;
text-align: center;
}
</style>
当然多数浏览器下table默认是会垂直居中的,这里只是为了引入下面对table-cell的使用
<div class="demo-cell">
<div class="table-like">
<div class="table-cell-like">
姓名
</div>
<div class="table-cell-like">
年龄
</div>
<div class="table-cell-like">
性别
</div>
<div class="table-cell-like">
描述
</div>
</div>
<div class="table-like">
<div class="table-cell-like">
张三
</div>
<div class="table-cell-like">
18
</div>
<div class="table-cell-like">
男
</div>
<div class="table-cell-like">
我要超过两行了哦我要超过两行了哦我要超过两行了哦
</div>
</div>
</div>
<style>
.table-like{
display: table;
width: 400px;
}
.table-cell-like{
display: table-cell;
text-align: center;
vertical-align: middle;
}
</style>
利用display:table 就能像表格一样使用vertical-align来实现垂直居中了
ps:table-cell只是可以用来做这个,但并不是最适合用做垂直居中的
弹出的模态框一般来说都是通过绝对定位来做,即:postion:absolute/fixed,所以基本可以用下面的方法实现。
<div class="demo3">
<div class="modal-ab">
假设我是一个弹出的模态框 <br>如果当弹出框高度和宽度是固定值的时候,<br>可以使用 <br>margin-left:-弹框width%;<br>
margin-top:-弹框height%; <br>来支持ie8.
</div>
</div>
<style>
.demo3{
position: relative;
width: 500px;
height: 300px;
border:solid 1px #eee;
}
.demo3 .modal-ab{
position: absolute;
top:50%;
left:50%;
width: 200px;
height: 120px;
border:solid 1px #000000;
text-align: left;
padding:10px;
-webkit-transform: translateX(-50%) translateY(-50%);
-moz-transform: translateX(-50%) translateY(-50%);
-ms-transform: translateX(-50%) translateY(-50%);
transform: translateX(-50%) translateY(-50%);
}
</style>
这种方式启示算是一种通用方式,利用定位来做垂直水平居中(IE9+),当然,在IE8中如果已知元素高宽是可以用margin负值的方式去实现的,如下:
.demo3 .modal-ab{
position: absolute;
top:50%;
left:50%;
width: 200px;
height: 120px;
margin-left: -100px;
margin-top:-60px;
}
图标和文字对齐(不使用position:relative)
<h2>图标大 文字小</h2>
<div class="demo4">
<span class="fa fa-edit big" ></span><span class="small">我是文字</span>
</div>
<h2>图标小 文字大</h2>
<div class="demo4">
<span class="fa fa-edit small"></span><span class="big">我是文字</span>
</div>
<style>
.demo4 .big{
vertical-align: middle;
}
</style>
场景4中,因为inline-block默认的vertical-align是baseline,所以会产生底部和文字底部对齐的现象,所以需要设置成middle来保证垂直居中。启示以前我都是一直用postion:relative的方式来处理这个问题。
最近手头上正在开发的app需要用到扫码功能,于是上用上了这一个cordova的插件目前来说适配ios以及安卓的效果还不错。推荐下大家尝试使用。
cordova.plugins.barcodeScanner.scan(
function (result) {
alert("We got a barcode\n" +
"Result: " + result.text + "\n" +
"Format: " + result.format + "\n" +
"Cancelled: " + result.cancelled);
},
function (error) {
alert("Scanning failed: " + error);
},
{
"preferFrontCamera" : true, // iOS and Android
"showFlipCameraButton" : true, // iOS and Android
"prompt" : "Place a barcode inside the scan area", // supported on Android only
"formats" : "QR_CODE,PDF_417", // default: all but PDF_417 and RSS_EXPANDED
"orientation" : "landscape" // Android only (portrait|landscape), default unset so it rotates with the device
}
);
4. 注意事项:scan方法需要在deviceReady之后调用
document.addEventlisterner('deviceready',onDeviceReady,false);
function onDeviceReady(){
//here bind event to click to use camera to scan barcode
}
html中需要通过script引入cordova.js(执行cordova build android之后在asserts目录下就能找到对应的文件)
location /mall-cli-portal{
proxy_pass http://songhlc:9001/mall-cli-portal;
proxy_set_header Host localhost;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
add_header From localhost;
proxy_set_header Cokkie $http_cookie;
proxy_redirect default ;
}
location /mobile{
proxy_pass http://localhost:63342/mobile/web/src/main/webapp/static;
proxy_redirect default
}
如上,开发环境就可以通过简单本地nginx的配置解决这个问题啦,然后线上环境就不用管了,本来就在同一个域下嘛。done,愉快的进行前后端分离了。
团队从最终一个人到现在初具规模,一开始大家都是全栈,前端代码,写到dubbo服务,写到mybatis脚本,到代码自动构建、线上版本,开发版本、测试版本的初步稳定,走了很多坑。但毕竟我还是要专注到前端上来,所以借此来好好总结一下。
思路并不清晰,只希望在前端的路上越来越快的成长
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.