1、解构赋值
const data = {
name:'1',
teacher:'2',
}
const {name,teacher}=data;//解构赋值,需要key一一对应
const data1 = [1,2,3,4,5];
const [a,b,c] = data1;//1,2,3
const [a,...b]=data1;//b为【2,3,4,5】
const [a, , ,b]=data1;//a:1,b:4,中间跳过了几个数,选择性接受
//数组还可以用于交换
当有多个引用使用别名
const data = {
name:'1',
teacher:'2',
class:{
name:'er',
title:'duck'
}
}
const {name:teachername,
teacher,
class:{
name,title
}
}=data;
解构赋值一般用在传参,变量交换,取值的场景中
2、babel
babel几个命令:
npm install @babel/core
npm install @babel/cli
运行:babel src/index.js -o dist/index.js
文件夹执行:babel src -d dist
实时监听:即source文件的改变会实时同步到target文件
babel src -d -w dist
babel配置有两种形式一个是.babelrc文件一个是babel.config.json
presets: [//预设的语法
"@babel/preset-env",
["env",{
"targets": {
"chrome": 52,
"browsers": ["last 2 versions","safari 7"]
}
}]
],
plugins: [//插件
]
babel的作用其实就是将词法分析的AST树修改成我们需要的
ES6–>BABEL–>ES5–>BROSWER
code–>词法分析–>AST(抽象语法树)–>语法分析–>run
一行代码通过语法分析会生成一个令牌流token,一般包括关键字,标识符,操作符,值等,一般一行代码以分号结尾。抽象语法树就包含这些token,一般是一个数组多个token,因为多行代码。语法分析就是一个校验逻辑,比如变量提升。
比如let a==1;会报synax token 的错误,就是因为词法分析出错,关键字不匹配操作符
面试题:怎么将a=2转变为抽象语法树
首先写一个方法找到等号,然后把等号左边和右边的数据取出来保存
babel插件的写法
//插件主体index.js
model.export=()=>{
return {
visitor:{
Identifier(path){//可以对词法分析的ast树进行改造
const nodeName = path.node.name;//节点名称
const nodeType = path.node.type;//节点类型
}
}
}
}
使用babel插件
const {transformSync} = require('@babel/core');
const plugin = ruquire('./index.js');
const code ={}//业务代码
const option = {
plugin:plugin//一般这个写在babel配置文件里
}
const output = transformSync(code,option)
3、实战用class构造一个树组件
//构造实例插件ref.js
var ref={};
class tree{
constructor(opts,vm){
this.tree = vm;
this.refs = {};
ref[opts.name]=this;
}
get(cid){
return this.refs[cid]?this.refs[cid]:this.tree;
}
set(vm){
this.refs[vm.cid] = vm;
}
}
const init = funxtion(opts,vm){
if(ref[opts.name]){
return new tree(opts,vm);
}else{
ref[opts.name]
}
}
const get = function(name,cid){
return ref[name]&&ref[name].get(cid)
}
const set = function(name,vm){
ref[name].set(vm)
}
const destory = function(name){
delete ref[name]
}
export default {init,set,get,destory}
//主体树入口
<script>
import item from './item.vue';
import ref from './ref.js'
export default{
props:{
options:Array,
value:Array
}
data(){
return{
name:'tree1'
}
},
components:{item}
created(){
ref.init({name:this.name},this);
},
render(h){
return(
<div><ul>
{this.options.map((el,index)=>{
return(
<item
name={this.name}
key={`${this.name}`${item['value']}${index}}
option={el}
></item>
)
})
}
</ul></div>
)
}
}
</script>
子组件item.vue
<script>
import item from './item.vue';
import ref from './ref.js';
export default{
props:{
options:Object,
name:String,
}
count = 0 ;
let cid = 'item'+count++
data(){
cid:cid,
expand:false,
checked:false,
level:this.$parent.level||0+1,
indent:1,
}
mounted(){
ref.set(this.name,this);
this.setDefault();
}
methods:{
handleClickItem(){
this.checked = !this.checked;
},
handleClickExpand(){
this.expand = !this.expand;
},
setDefault(){
let tree = refs.get(this.name);//得到这颗树的实例
let _value = tree.value;//默认选中的值
if(_value.indexOf(this.option['value'])>-1){
this.checked = true;
}
}
}
computed(){
isFolder(){
return !!this.options.children
}
}
render(h){
return (
<li class={['tree_item',this.checked&&'ischecked']}>
<div class={['arrow',this.expand?'expand':'']} style={{display:this.isFolder?'block':'none'} onClick={handleClickExpand}>
<a class={['v-tree-title']} style={{paddingLeft:this.level!==0&&(`${this.level*this.indent}px`)}} onClick={handleClickItem}>{this.option['text']}</a>
{
this.isFolder&&<ul class="vue-tree__folder" style={{display:this.expand?'block':'none'}}>
{
this.option['children'].map((el,index)=>{
return (
<item
name={this.name}
key={`${this.name}`${item['value']}${index}}
option={el}
></item>
)
})
}
</ul>
}
</div>
</li>
)
}
}
</script>