- 👋 Hi, I’m @jiaozitang
- 👀 I’m interested in ...
- 🌱 I’m currently learning ...
- 💞️ I’m looking to collaborate on ...
- 📫 How to reach me ...
note's Introduction
note's People
note's Issues
react入门
声明式,组件化开发
####1.安装环境
- 安装node
- 下载安装vs code
- 安装create-react-app
- npm install prop-types --save(类型检查)
import PropTypes from 'prop-types
模块化开发使用export ,export default/import from
sudo建立的文件夹需要修改权限才能保存
sudo chown -R $USER <directory_project>
jsx注意:只能有一个根节点
###2.组件化开发
新建单文件组件
import React,{Component} from 'react'
class Button extends Component{
constructor(){
super()
}
render(){
return(
<button>来自button.js的组件</button>
)
}
}
export default Button
引入单文件组件:
import Button from './Button'
组件的三个属性:
state:状态
跨组件传值,state的设置和修改都提升到父级组件操作
状态提升:
方法提升:
//函数方式创建组件
const Nav = function(props){
return(
<nav style={{height:'100px',backgroundColor:'black',color:'#fff'}}>
hello world1
{props.children}
{props.title}
</nav>
)
}
//类方式 创建组件
class Button extends Component{
constructor(){
super()
}
render(){
return(
<button>{this.props.name}</button>
)
}
}
传递参数
<Nav title="title">
<h1>h1</h1>
</Nav>
<Button name="helloworld"></Button>
import React,{Component} from 'react';
import logo from './logo.svg';
import './App.css';
import PropTypes from 'prop-types'
import Button from './Button'
class Title extends Component{
static contextTypes = {
title:PropTypes.string
}
constructor(){
super();
}
render(){
return(
<nav>
<h1>{this.context.title}</h1>
</nav>
)
}
}
class App extends Component{
static childContextTypes = {
themeColor: PropTypes.string,
title:PropTypes.string,
handleChangeThemeColor:PropTypes.func
}
getChildContext(){
return{
themeColor:this.state.themeColor,
title:this.state.title,
handleChangeThemeColor:(color)=>this.handleChangeThemeColor(color)
}
}
constructor(){
super();
this.state = {
themeColor:'red',
title:'这是标题'
}
}
handleChangeThemeColor(color){
this.setState({
themeColor:color
})
}
render(){
return (
<div>
<Button></Button>
<Title></Title>
</div>
)
}
}
export default App;
import React, { Component} from 'react'
import PropTypes from 'prop-types'
export default class Button extends Component{
static contextTypes = {
themeColor: PropTypes.string,
handleChangeThemeColor:PropTypes.func
}
constructor(){
super()
}
render(){
return(
<div>
<button style={{color:this.context.themeColor}}
onClick={()=>this.context.handleChangeThemeColor('green')}>绿色</button>
<button style={{color:this.context.themeColor}}
onClick={()=>this.context.handleChangeThemeColor('red')}>红色</button>
</div>
)
}
}
###3.事件
调用事件使用箭头函数的方法调用是因为this执行的问题
4.生命周期函数
will生命周期函数在react17版本之后修改为 static getDerivedStateFromProps()
组件定时器demo
import React,{Component} from 'react';
import logo from './logo.svg';
import './App.css';
import Test from './test'
class App extends Component{
constructor(){
super();
this.state = {
isRenderTest:true
}
}
render(){
return (
<div>
{this.state.isRenderTest?<Test></Test>:'不需要渲染test'}
<button onClick={()=>{
this.setState({isRenderTest:!this.state.isRenderTest})
}}>
切换渲染Test,测试卸载组件的生命周期函数</button>
<button onClick={()=>this.setState({})}>app setState更新</button>
App
</div>
)
}
}
export default App;
import React, { Component} from 'react'
export default class Test extends Component{
constructor(props){
super(props)
this.state = {
time: new Date()
}
console.log('constructor');
}
tick(){
this.setState({
time:new Date()
})
}
//加载
componentWillMount(){
this.timeId = setInterval(()=>this.tick(),1000)
this.tick();
console.log('组件将要加载')
}
componentDidMount(){
console.log('组件已经加载')
}
//更新
componentWillReceiveProps(){
console.log('组件将要接收参数')
}
shouldComponentUpdate(){
console.log('是否要更新组件');
return true;
}
componentWillUpdate(){
console.log('组件将要更新')
}
// getSnapshotBeforeUpdate(){
// console.log('在更新前获取截图')
// }
componentDidUpdate(){
console.log('组件已经更新')
}
//卸载
componentWillUnmount(){
console.log('组件将要卸载')
clearInterval(this.timeId)
}
render(){
console.log('render')
return(
<div>
<div>Test</div>
<p>{this.state.time.getSeconds()}</p>
<button onClick={()=>this.setState({})}>test setState更新</button>
</div>
)
}
}
taro入门
web安全
web安全
xss 跨站脚本攻击
--用户填写的信息是可运行的js代码,操作用户界面
攻击源头:
-反射型,从Url读取内容展示
-存储型,从后台读取内容展示
防范手段:
-富文本,白名单过滤,就是把安全的标签保留下来,不不安全的标签过滤,XSS-filter,js,xss过滤的库
-纯文本,html encode,js encode
ex1 反射型
<div id="test"></div>
<script>
//#<img src="404.html" onerror="alert('xss')">
var $test = document.querySelector('#test');
$test.innerHTML = decodeURIComponent(window.location.hash)
</script>
怎么关闭或者隐藏iframe
注意要用window.top而不是直接document;
document.getElementById('ui_ptlogin')拿到的是null
let ui_ptlogin = window.top.document.getElementById('ui_ptlogin');//iframe 获取父级的节点
ui_ptlogin.style.display = "none";
上传文件、下载文件
vue 下载文件:
1.后台提交了接口怎么下载文件
将a标签的href值,定为后台的接口路径拼接参数的url;
<a :href="get_modified_auth_users(historys.record_id)" class="btn-downRoll">下载名单</a>
get_modified_auth_users(record_id){
let url = 'https://courtreport.gamesafe.qq.com/cgi-bin/report_judge/qq/get_modified_auth_users?';
let params ={
game_id: 0,//游戏id, 取0表示全量游戏
src_type: 0,
op_type: 0,//只查询自己的操作记录,1查询全量的查询记录
record_id: record_id,//记录id,query_modify_auth_history接口中获取
};
for (var [k, v] of Object.entries(params)) {
url+= k + "=" + v + "&";
};
return url;
},
2.只需要下载一个静态文件,需要把路径写成网络路径
<a download="https://courtreport.gamesafe.qq.com/static/report_judge/admin/static/user_template.txt"
href="https://courtreport.gamesafe.qq.com/static/report_judge/admin/static/user_template.txt">
管理平台授权模板
</a>
上面这么写有个问题是下载到本地的文件名称太长,于是修改download的属性就可以了
没有修改的时候文件名:https---courtreport.gamesafe.qq.com-static-report_judge-admin-static-user_template (2).txt
修改后文件名:user_template (2).txt
<div>名单文件模板下载:
<a download="user_template.txt"
href="https://courtreport.gamesafe.qq.com/static/report_judge/admin/static/user_template.txt">
管理平台授权模板
</a>
</div>
约好面试时间9:30-10:00
9:25签到、笔试题和个人资料、入职申请表
笔试题:
1.css3实现自适应的3行,左右行固定宽带,中间自适应,要求优先渲染中间部分
博客地址:https://www.jianshu.com/p/6ac97f8573dd
2.事件委托的原理和优缺点
博客地址:https://www.jianshu.com/p/d5e8dfbe1c41
3.vuex的原理,有哪些属性
vuex用来管理vue组件之间相互依赖的状态
属性:state.getters.mutation.action.module
4.vue生命周期
每个实例在被创建时都要经过一系列的初始化过程。需要设置数据监听、编译模板、将实例挂载到DOM并在数据变化时更新DOM,同时在这个过程也会运行一些叫做生命周期的函数,这给了用户在不同阶段添加自己的代码的机会。
beforeCreate 组件实例化之前执行的函数
created 组件实例化之后,但是页面还未显示
beforeMount 组件挂载前,但页面还没显示
mounted 组件挂载后,这个函数执行后页面显示
beforeUpdate 组件更新前,页面还未更新
updated 组件更新,这个函数执行后页面更新
beforeDestroy 组件销毁前
destroyed 组件销毁后
5.call,apply
修改this指向,
apply(上下文对象,参数数组);
call(上下文对象,参数1,参数2);
6.var let const的不同
1.暂时性死区
2.块级作用域
3.是否可重复声明
7.position的属性
abosolute:绝对定位,相对于最近的非static定位的祖先元素
fixed:绝对定位。相对与屏幕视口
static:默认值
relative:相对定位
sticky
8.性能优化
博客地址:https://www.jianshu.com/p/8eef9dd0de72
11:00一面技术面
1.自我介绍
2.垂直居中的方法(列举多种)
3.自适应3行的方法(列举多种)
4.vue data 的特殊性
5.http缓存
6.vue 父子组件间传值
7.vue v-model的实现
8.vue怎么操作dom
9.性能优化的方法
10.跨域解决
11.怎么调试
12.常用的es6新功能
博客地址:https://www.jianshu.com/p/9a7e1352e2ad
13.export defoult 和export区别的
--结束后告知业务面合格
11:50hr面
1.自我介绍
2.为什么从上家公司离职
--次日会有通知, 而后谈论薪资
vue 2.0 入门笔记
搭建一个框架的完整步骤
- vue init webpack test-project
- npm install axios --save-dev
- npm install vuex --save-dev
- npm install mockjs --save-dev
- npm install vue-cookies --save
npm install axios vuex mockjs vue-cookies --save-dev
https://www.jianshu.com/p/535b53989b39
1.computed and methods区别
我们想去时刻监控数据的变化,在视图上显示不同的结果,当然这两中方法都可以实现这种效果,这个时候用computed就比较合理了,因为computed是可缓存的,只要数据层值不改变,computed就不会去改变,而且可缓存,如果数据层的值变了,computed就会实时更新到视图层上,所以说computed是响应式的
2.模板
Vue.component('my-component-name', {
template:"<div>
<p></p>
<button></button>
</div>",
data:function(){
return{
name:'tangjiao';
}
}
})
注意:template里要有一个根标签
data在function里面返回数据对象
使用时需要:
1.安装NodeJs,版本要求node-v在6.0以上,npm在3.0以上
2.用npm安装vue-cli,时间有点久,耗时1小时以上,
推荐使用国内镜像来安装,所以我们先设置 cnpm:
npm install -g cnpm --registry=https://registry.npm.taobao.org
-
vue init webpack test-project
-进入项目目录(cd Vue-Project),启动项目npm run dev
-
遇到的问题:npm install和npmrun dev都报错,提示504,解决方式,设置ngn版代理,npm config set proxy=http://web-proxy.tencent.com:8080
-
npmrun dev报错,提示cant font module 'webpack-server',解决方式,npm install成功后再执行npm run dev
4.打包上线
自己的项目文件都需要放到 src 文件夹下
项目开发完成之后,可以输入 npm run build 来进行打包工作
npm run build
打包完成后,会生成 dist 文件夹,如果已经修改了文件路径,可以直接打开本地文件查看
项目上线时,只需要将 dist 文件夹放到服务器就行了。
打包后css/img等静态资源404时,解决方法:
1.config/index.js 中修改build对象的 assetsPublicPath 为 正确的资源路径
如服务器域名下的路径为http://gamecredit.qq.com/static/games/index.htm
代码路径为/static/games
设置‘'/static/games/'’ 绝对路径
2.build/utils.js 中的 ExtractTextPlugin.extract 传入参数 publicPath: '../../' 无效
4.组件
组件嵌套
a.定义全局变量,在页面中用到组件
ex:main.js中定义变量:
import Users from './components/Users';
Vue.component('Users',Users);//全局变量
app.vue 引用这个组件:
<users></users>
b.定义局部变量
app.vue定义局部变量, 引用这个组件
import Users from "./components/Users";
import Users from "./components/Users";
components: {Users},
5.组件css作用域
vue文件下的<style></style>加上属性scoped,所编写的样式只改变当前组件的样式,不加scoped则影响整个页面的样式
6.组件传值(父组件传值给子组件)
不可在子组件中修改父组件的值,可以通过深拷贝。在子组件中拷贝一份数据
app.vue:
<users v-bind:list="users_list"></users>
//users_list为data中要传递的数据
users.vue:
props: ["list"],
//拿到传递过来的值,list就是传过来的数据,可以直接使用
还有一种写法:
props:{ list:{ type:Array, required:true }
7.组件事件传值(子组件传值给父组件)
- a.在子组件中创建一个按钮,给按钮绑定一个点击事件
- b.在响应该点击事件的函数中使用$emit来触发一个自定义事件,并传递一个参数
- c.在父组件中的子标签中监听该自定义事件并添加一个响应该事件的处理方法
子组件中需要以某种方式例如点击事件的方法来触发一个自定义事件
将需要传的值作为$emit的第二个参数,该值将作为实参传给响应自定义事件的方法
在父组件中注册子组件并在子组件标签上绑定对自定义事件的监听
在通信中,无论是子组件向父组件传值还是父组件向子组件传值,他们都有一个共同点就是有中间介质,子向父的介质是自定义事件,父向子的介质是props中的属性。抓准这两点对于父子通信就好理解了
页面加载时就要引入的方法,一般放在mounted()里。如果报错,则更换其他的钩子函数
9.vue 路由
路由点击跳转不会页面刷新,可以保留数据
localhost:8080/#/需要定义为localhost:8080/:mode:'history'
-
vue-cli,npm run build后,dist目录下文件放在服务器中,页面是空白的问题。
是因为配置了mode:history,需要后台配置了环境才能用这个功能
10.vue http请求
用到vue-resource
- 安装vue-resource:npm install vue-resource --save-dev
安装后要重新npm run dev,才生效 - 在main.js中引用
import VueResource from 'vue-resource'
Vue.use(VueResource)
- 在http://jsonplaceholder.typicode.com/中调用线上可用的接口
在xx.vue中引用
11.Vue2.x-实现跨域请求(fetch/axios/proxytable)
跨域问题,修改proxyTable,然后重启npm run dev
proxyTable: {
'/api': {
target: "http://test.wx.gamesafe.qq.com",
changeOrigin: true
},
},
axios请求接口
1.安装 cnpm install axios
2.使用 cdn:
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
在main.js中引入axios,并命名全局变量
请求接口:
`
created(){
this.$axios.post('http://jsonplaceholder.typicode.com/users')
.then(data =>{
console.log(data)
})
}`
main.js中设置全局变量和全局方法,this指向引入改全局方法的vue组件对象
在父组件已经更新的值,子组件没有更新
{{}}在页面中打印是更新了。mounted()钩子函数中查看没有更新的问题
一定注意v-if
子组件引入npm 下载下来的插件
var loadWrap = {
data: function () {
return {
}
},
template: '<div id="loading"></div>'
};
Vue.component('load_wrap', {
data: function () {
return {
}
},
template: '<div id="loading"></div>'
})
v-bind:src
<li v-if="Boolean(favorite_games)" v-for="favorite_game in favorite_games" :key="favorite_game">
<img :src="require('../assets/images/games/gm_'+favorite_game+'.jpg')" alt="" />
<p>{{favorite_game}}</p>
</li>
引入外部js文件
ex:showDialog.min.js
1.尝试npm install showDialog
2.安装不了,只能下载下来
3.在main.js引入
import showDialog from './assets/js/showDialog.min'
需要导出showDialog数据,首先要在js文件中输出
5.在main.js导入这个js后,console.log(showDialog),发现需要引用showDialog.showDialog才能调用它的show方法
Vue.prototype.popShow = function(e){
showDialog.showDialog.show({
id:e, //需要弹出的id,如果是弹出页面上的div,则该选项为必选
bgcolor:"#000",//弹出“遮罩”的颜色,格式为"#FF6600",可选,默认为"#fff"
opacity:60 //弹出“遮罩”的透明度,格式为{10-100},可选
})
}
axios post 请求 ‘'application/x-www-form-urlencoded'’
要下载qs插件,npm install qs --save-dev,不然参数会有问题
params = Qs.stringify(params);处理参数
let url='/cgi-bin/login_protect';
var params = {
//user_id: self.uin,
//user_type: 'user_type',//str, required
game_id: game_id,//int, required
protect: protect,//int, required, 0|1, 0为解除,1为设定
code: code,//str, optional, 解除校验key,用户输入md5
};
params = Qs.stringify(params);
self.$axios.post(url,params,{
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
.then(function (response) {
console.log(response.data.ret)
if(response.data.ret === 0){
if(self.loginProtectData[index].protected === 1){
self.dialogShow('webLoginClose');
self.loginProtectData[index].protected = 0;
}else{
self.dialogShow('webLoginOpen');
self.loginProtectData[index].protected = 1;
}
}else if(response.data.ret === 1315){
//错误的校验码
self.dialogShow('commErr');
}else{
self.dialogShow('commErr');
}
})
.catch(function (error) {
})
vue2.0不兼容安卓4.4,出现白屏
1.npm安装
npm install babel-polyfill
npm install es6-promise
package.json中会出现
"babel-polyfill": "^6.26.0",
"es6-promise": "^4.1.1",
2.main.js引入
import 'babel-polyfill'
import Vue from 'vue'
import Es6Promise from 'es6-promise'
require('es6-promise').polyfill()
Es6Promise.polyfill()
3.webpack.base.conf.js
module.exports = {
entry: {
"babel-polyfill":"babel-polyfill",
app: './src/main.js'
},
vue-router query传参
this.$router和this.$route
this.$router.push({ path: '/static/proxy/accountSafe/securityCode', query:
{
index: index,
game_id: game_id,
protect: protect,
gameName: this.gameName[gameList.game_id]
}
})
data(){
return{
err_remove:"",
code: null,
gameName: this.$route.query.gameName
}
},
vue2 webpack2 为less/css自动添加前缀autoprefixer
为了兼容不同的浏览器,很多时候要写前缀,不然存在很多兼容性问题,如果用webpack的话,很容易实现自动添加前缀,我现在用的项目是基于vue2 webpakc2的,查阅了很久没有发现便捷的解决方案:
- 安装 postcss-loader
npm install postcss-loader --save-dev
2.配置webpack.conf.js
rules: [{
test: /.vue$/,
loader: 'vue-loader',
options: {
// vue-loader options go here
postcss: [require('autoprefixer')({ browsers: ['last 10 Chrome versions', 'last 5 Firefox versions', 'Safari >= 6', 'ie > 8'] })]
}
},
{
test: /.less$/,
loader: 'style-loader!css-loader!postcss-loader!less-loader'
}]
新电脑环境配置
1.安装nvm
- xcode-select --install
- curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh | bash
安装nvm的坑:https://www.cnblogs.com/giggle/p/7075548.html
如果,你本地运行nvm还是出现command not found,那么请检查安装目录下/Users/tangjiao11/.nvm是否含有.bash_profile文件,如下:
ls -a | grep .bash_profile
defaults write com.apple.finder AppleShowAllFiles Yes && killall Finder //显示隐藏文件
defaults write com.apple.finder AppleShowAllFiles No && killall Finder //不显示隐藏文件
先让隐藏的文件显示,然后如果没有.bash_profile文件,新建.bash_profile文件,在.bash-profile中添加:
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm
然后执行source .bash_profile
配置环境变量
nvm --version
查看版本号
- 安装Node nvm install 12.3.0
2.安装brew
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
brew -v
如果提示上面的错误,则运行sudo xcodebuild -license
,运行后根据提示按enter/space,或者输入agree.
3.安装yarn
brew install yarn
项目的问题
vue-cli3
比cli2运行和打包都快
npm install -g @vue/cli
vue create hello-world
npm run serve
npm run build
配置打包目录:
module.exports = {
publicPath: '/static/proxy/query_punish/',
outputDir: 'D:/software-place/wamp/www/wechat_tornado_20180820/static/proxy/query_punish/'
}
git
1.关联ssh,新建ssh
a. 检查SSH公钥
看看存不存在.ssh,如果存在的话,直接跳过到下一步;不存在的话请看下一步,按照操作进行
b.生成SSH公钥
-
$ssh-keygen -t rsa -C "[email protected]"
在接下来提示输入密码的时候输入你的github密码
Enter passphrase (empty for no passphrase): [Type your github passphrase]
Enter same passphrase again:[Type your github passphrase again]
这个时候输入你在github上设置的密码。
-
然后在.ssh中可以看到,id_rsa,id_rsa.pub文件了
-
添加SSH公钥到github
打开github,找到账户里面添加SSH,把id_rsa.pub用记事本或者notpad++打开,将内容复制到key里面。
c.测试是否生效
使用下面的命令测试
ssh -T [email protected]
当你看到这些内容放入时候,直接输入yes
Are you sure you want to continue connecting (yes/no)?
看到这个内容放入时候,说明就成功了。
Hi username!
You've successfully authenticated, but GitHub does not provide shell access.
参考链接
https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/001374385852170d9c7adf13c30429b9660d0eb689dd43a000
2.如果push要输入帐号密码,设置git remote url 从https到ssh:
git remote -v
使用remote set-url 命令切换url.
git remote set-url origin [email protected]:USERNAME/REPOSITORY2.git
使用remote set-url 命令切换url.
git remote set-url origin https://github.com/USERNAME/REPOSITORY_2.git
参考博客
https://www.sheng00.com/2057.html
3.安装好ssh后如果提示22端口链接不成功。原因是公司内网需要设置代理,尝试设置代理失败,最后设置git remote url 从ssh到https。就可以提交成功了
https下提示需要输入用户名、密码
2.提交修改
3.克隆博客
git clone [email protected]:michaelliao/gitskills.git
如果上面的语句提示
ssh: connect to host github.com port 22: Connection timed out
则改成git clone https://github.com/tang119/javascript-note.git
sass入门
最新的sass文件以 .scss 作为拓展名。
1.安装
//安装如下(如mac安装遇到权限问题需加 sudo gem install sass)
gem install sass
gem install compass
2.使用变量
将使用很多次的css属性值定义为变量,使用$符号来标志变量。
变量声明$highlight-color: #F90;
变量引用background-color:$highlight-color
3.嵌套css规则
#content {
article {
h1 { color: #333 }
p { margin-bottom: 1.4em }
}
aside { background-color: #EEE }
}
父选择器&:有些情况下不希望sass使用后代选择器的方式生成连接,可以加上&符号,表示这条规则只应用到自身.
article a {
color: blue;
&:hover { color: red } ->article a:hover { color: red } 选择父级选择器
}
子组合选择器>选择一个元素的直接子元素
同层相邻组合选择器+选择a元素后紧跟的b元素
同层全体组合选择器~,选择所有跟在a元素后的同层b元素
article {
~ article { border-top: 1px dashed #ccc }选择所有跟在article元素后的同层article元素
> section { background: #eee }选择article元素的直接子元素section
dl > {
dt { color: #333 }选择dl元素的直接子元素dd
dd { color: #555 }
}
nav + & { margin-top: 0 } ->nav + article { margin-top: 0 }选择nav元素后紧跟的article元素
}
嵌套属性
nav {
border: {
style: solid;
width: 1px;
color: #ccc;
}
}
nav {
border-style: solid;
border-width: 1px;
border-color: #ccc;
}
3.导入sass文件
sass局部文件,只用来引入,不需要生成独立的css文件。sass局部文件的文件名以下划线开头,_night-sky.scss。
默认变量值!default,如果这个变量被声明赋值了,那就用它声明的值,否则就用这个默认值。
$fancybox-width: 400px !default;
.fancybox {
width: $fancybox-width;
}
嵌套导入
sass允许@import命令写在css规则内。这种导入方式下,生成对应的css文件时,局部文件会被直接插入到css规则内导入它的地方。
原生的CSS导入
可以把原始的css文件改名为.scss后缀,即可直接导入
4.静默注释
该注释不会出现在生成的css文件中。
body {
color: #333; // 这种注释内容不会出现在生成的css文件中
padding: 0; /* 这种注释内容会出现在生成的css文件中 */
}
5. 混合器
混合器使用@mixin标识符定义。看上去很像其他的CSS @标识符,比如说@media或者@font-face。这个标识符给一大段样式赋予一个名字,这样你就可以轻易地通过引用这个名字重用这段样式。
何时使用混合器?
如果你能找到一个很好的短名字来描述这些属性修饰的样式,比如rounded-cornersfancy-font或者no-bullets,那么往往能够构造一个合适的混合器。如果你找不到,这时候构造一个混合器可能并不合适。
混合器中的CSS规则
给混合器传参
@mixin link-colors($normal, $hover, $visited) {
color: $normal;
&:hover { color: $hover; }
&:visited { color: $visited; }
}
6.使用选择器继承来精简CSS
通过@extend语法实现
//通过选择器继承继承样式
.error {
border: 1px solid red;
background-color: #fdd;
}
.seriousError {
@extend .error;
border-width: 3px;
}
何时使用继承
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.