首页 > 其他分享 >前端-Vue语法使用

前端-Vue语法使用

时间:2023-05-17 14:14:27浏览次数:50  
标签:Vue 定义 -- 前端 语法 resolve 组件 data 函数

ES6

做为动态语言,感觉底层开始-基本类型就全引用。
做为实例化的变量,也变得像指向指针的指针,可以随时切换指针,从而最终的数据类型也更着切换
总的来说概念上会比较别扭。以及灵活导致的不确定性。
底层都是对象,从对象的类型来搭建。

基本类型\ 

Primitive  value  
Undefined,Null,Boolean,Number,BigInt,String

Objecets
 

同样属于Object,typeof arrary 返回object,typeof function,返回 function

结构变量
变量--类型-不用申明的。
按照(名称:内容)这样的结构 --扁平化组织。
类,数组,单个变量,随意复合在一起

数据与函数也复合一起

集合变量

 数组 arr:[],可以放混合类型的值。
 集合 col:{p-a:v-a,p-b:vb,....}
 map var m = new Map([['Michael', 95], ['Bob', 75], ['Tracy', 85]]);
    写入  m.set('Adam', 67);
    只能有一个key,后面同一key的set会更行值。

数组,集合相互嵌套。
arr[
 col-a,col-b ,..
]
col{
arr_a,arr_b,...
}

这里的集合和json无缝互转。
其实是Axios自动会转换对象为Json而已。其它时候还是得用转换函数。

对象
这里实例和对象是不分得,有个prototype的内置属性,有个原型链。
对象/函数
这里模糊不清的。感觉对象是有两种含义。
一种是除了基本类型,其它都属于对象A,包括函数。
一种是对象类型B。也是属于对象A?

对象里可以定义属性,方法。
函数里可以定义属性,方法。
继承了对象,加了一些东西,然后机制上也有不同。

对象的定义

var  objA={
pa:va,
funa:function(){}
}
    

function Student(props) {
    this.name = props.name || '匿名'; // 默认值为'匿名'
    this.grade = props.grade || 1; // 默认值为1
}

Student.prototype.hello = function () {
    alert('Hello, ' + this.name + '!');
};

function createStudent(props) {
    return new Student(props || {})
}

一些写法
json的key是加引号的。
集合的key可加可不加。
但不规范的名称- "111name","key-2" , 这种需要加引号,
虽然自己一般不会这么取,但axios返回的数据里,header里面很多属性都是有横杠的。

属性的获取一般是obj.propA,不规范的名称要用obj['propA']

属性的维护
add
就直接赋值。
xiaoming.age = 18;
del
delete xiaoming.age;

两个集合合并
Object.assign()

一个集合作为另一个集合的属性

ccol={ca:va}
scol={ccol,sa:va}

scol:{
    ccol:{ca:va},
    sa:va
}

这里加入的属性名称,就是函数的名称。

变量赋值
var=xxx;
col{} 可随时增加项目。

作用域
var
可全局定义,也可局部定义。
同一个变量名,在已经有全局定义的情况下,
局部定义使用时,并不会干扰到全局变量,没啥冲突。

有个自动上升机制。
一个函数内先使用全局变量,再定义局部变量也是行不通的。
默认把下面的定义提前。

let ,const 局部定义。
const如果是指针类型,那里面对象值还是能变得
代码里const主要用在类的创建,axios的返回对象。

两者的使用区别。
感觉大部分时候并没啥区别。
就只有函数内部的’{}‘块状代码内。

var  xx;
{
    var xx
}
xx

这样编译会报错。
文档上说这样定义后,操作的是同一个xx。不存在块级作用域。

let xx=1;
{
 let xx=2;
}

这样可以编译,有块级作用域。

初始值
var --undefined
let --undefined ,建议是初始化一个值。
const 必须初始化

然后会有混用的情况,自己写肯定不会去找这种麻烦。
先定义了var,后面再定义let,那么使用的就是let
先定义let,再定义var,不允许

文档上说var容易定义混乱。
感觉就函数内代码比较多时,会搞不清楚。
但编译器已经禁止这样定义。

函数内调用其它函数感觉也不涉及这些作用域了。

操作符号
!--取反某个变量,不为空的是true。空的null、undefined和空字符串是false
取反后,就倒过来。
!!--两次取反,相当于不为空的才成立。

那为啥不直接 if (变量)--估计是要!一下才变为boolean类型。

数据操作
遍历
这些都是不能改变数组里的原值,但如果是引用类型,可以改变被引用的值。类似const这种吧。。

for

for (let i = 0; i < books.length; i++) {
  totalPrice1 += books[i].count * books[i].price
}
简洁版
for(let i in this.books),i是下标
for(let item of  books)

回调版
forEach
arr.forEach(callback[, thisArg])

一般不用thisArg,callback有三个参数 Value,index,array。
只要指定用到参数就行,有了=》函数申明。看起来也很简洁。

arr.forEach(item => do something with item).  

map
格式和forEach类似。
多了返回一个新的数组。
推荐里不返回数组的用foreach。但lamp代码中很多不返回的也用map。
返回数据,完全看return的内容,保持原来的数组长度?
const map1 = array1.map(x => x * 2);
也有不用写return的?

.../三个点。
把数组展开

var number = [1,2,3,4,5,6]
console.log(...number) //1 2 3 4 5 6

错误异常处理
try catch --看着用的很少

 

VUE操作

模板<template>

表达式 --模板里写脚本
属性绑定

v-bind:-->:   v-on:-->@、v-slot-->#   简写
v-bind:动态地绑定一个或多个 attribute,或一个组件 prop 到表达式
v-on:绑定事件监听器
数据需要用“”括起来。

{{}}:引用vue中定义的数据
<p>{{ message }}</p>

大概显示内容的html就用{{}},属性设置里不能用,要用bind。

嵌入的表达式只能是单个表达式。不能是多个语句的js
不能访问用户定义的全局变量。

渲染
条件渲染
v-if 只有满足的才会创建出来。
v-show 这个dom是创建出来了,设置display来控制
列表渲染
v-for

过滤器(filter)
{{ message | capitalize }}
这里 | 表示管道。

可以在组件内定义filters:{}
可以全局定义Vue.filter();

这边用来格式化输出内容。

组件之间有父子关系,模板定义与实例关系?

数据绑定

单项绑定
element<--data .   <input v-bind:value="something">
element-->data     <input  -on:input="something = $event.target.value" />
双向绑定
<input v-model="something" />  相当于单项绑定的结合

props:父子组件之间传递数据
父到子
这个传递类似于一个引用,父组件中修改值后,子组件会相应更新

father---:data="device"  
child-props: { 
                   data: Object
            },
使用 this.data.xxx

子到父,有一套机制,事件绑定。

 

 

v-model--语法糖
对控件值的双向绑定

<currency-input v-model="price"></currency-input>相当于下面的简写:
<currency-input :value="price" @input="price = arguments[0]"></currency-input>

prop的更新。
prop本来是父元素传子元素。子元素不建议直接修改。
父组件调用子组件时,申明监听事件v-on:update:title
子组件可以触发这个事件,同时附加上数据。
父组件在这个事件中更新数据。
看着子组件还是不能操作这个prop的,要曲线绕回父组件来操作。

父组件-- <text-document  v-bind:title="doc.title"  v-on:update:title="doc.title = $event" ></text-document> 申明一个update监听事件。
子组件--  this.$emit('update:title', newTitle)  触发update事件

这里sync是语法糖。简化了父组件的申明。

MediaSelector.vue

 A:<media-selector :media.sync="hcMedia" >
 B: props: {  media: Object}
     this.$emit('update:media', this.mediaSel)

这里BoxSelector.vue搞不懂

 props: {        select: Object    },
 this.select.boxImei = value.deviceName || ''

直接对props参数赋值,放到其他项目里,编译就报错了。

这个机制可以调用到父组件的方法。相当于彼此互通。

<el-dialog title="任务信息" :visible.sync="dialogFormVisible">    

去掉sync后
直接 设置 dialogFormVisible 是没有问题,
点右上角的x标记,没有反应,等于没有侦听,对子组件的update调用无视了,导致无法关闭?

说是v-model针对的input类型输入。
看TaskRS中,el-radio,el-select,el-switch都是用vmodel

index.vue
<sunrn-media-selector :media.sync="srmedia" v-if="selectedProduct == 'SUNRN'"></sunrn-media-selector>

slot--插槽

可以把父组件定义好的html模板传给子组件,显示在子组件的特定位置--插槽。

<el-table-column prop="enable" label="启用" align="center">
<template slot-scope="scope">
<el-tag size="medium"> {{  scope.row.enable ? "启用" : "禁用" }} </el-tag>
</template>
</el-table-column>

这里子组件是el-table-column?
slot-scope="scope" -- "scope" 这个可以随意取名字,用来接受子组件的数据、
scope.row.enable子组件的数据。
这里就是自定义表格列的显示内容。

类似于回调函数,组件申明插槽,调用者放入内容。
然后怎么标记,怎么传递。
组件插槽处起一个名称?
调用者传入名称,内容

差不多是这样,这里可以有个默认插槽,不用具名。多个插槽点就起名。

child

<slot name="up"></slot>

father
<child>
<div class="tmpl" slot="up">
<child/>

然后插入的内容,这里可以全部由调用这提供。
还有一种调用者只提供样式。数据是自己维护,叫作用域插槽,语法标签都不一样

child
 <slot  :data="data"></slot>
 export default {
    data: function(){}
 }
 
 <child>
      <template slot-scope="user">
        <div class="tmpl">
          <span v-for="item in user.data">{{item}}</span>
        </div>
      </template>
</child>

自定义事件
要素,定义事件,监听事件,触发事件,处理事件。
一般都是控件已有事件,如点击,输入。都是系统触发。
在哪里定义,在引用组件的时候?加上事件属性 event=eventA proc=procA
组件里面定义处理函数procA
在哪里触发,引用组件这里,vue的触发函数 emit(eventA,data);

定义事件/监听事件
用$on->('eventname',proc)给组件绑定事件。
这里绑定有两个途径

  • 在组件定义的时候,mouted(){..}这里写。
  • 在组件引用的时候,v-on:eventA=procA

触发事件
感觉哪里都能去触发。
父子之间,平级的组件之间。

上面的逻辑不对劲,认为事件是属于绑定的组件。事件看起来并不需要先定义。
应该有个系统的事件调度,要做的是
一方是监听者,只要申明监听某个事件名称。
一方是提交者,只要触发这个事件名称。

这里监听要争对某个对象/组件,在引用组件的时候写 v-on。
触发也是被监听的组件来触发。

有例子是组件内的事件。。监听对象就是自己?

methods: {
      isClick() {
        this.$emit('isLeft', '点击事件!');
      }
    },
 mounted() {
      this.$on('isLeft', (val) => {
        console.log(val);
      });
    }

有例子是通过"eventBus"

 mounted() {
      eventBus.$on('isLeft', (info) => {
        this.name = info ;
      });
    }

这样不针对某个对象/组件,纯监听事件名的。

事件先还有修饰符。.stop /.preven这些

 

模板字符串
反引号(`),直接在``中嵌入变量。

 `Hello ${name}, how are you ${time}?`
 

类似于format字符串

机制

响应式更新
数据和Dom之间是异步更新的。
有一个执行循环。

//改变数据
vm.message = 'changed'

//想要立即使用更新后的DOM。这样不行,因为设置message后DOM还没有更新
console.log(vm.$el.textContent) // 并不会得到'changed'

//这样可以,nextTick里面的代码会在DOM更新后执行
Vue.nextTick(function(){
    console.log(vm.$el.textContent) //可以得到'changed'
})

数据的变动情况很多,会导致这种同步关系失效。

  • 对象后续加了属性
    this.$set(this.someObject,'b',2)
  • 数组的变动
    ** 内容的变动
    vm.$set(vm.items, indexOfItem, newValue)
    ** 长度的变动
    vm.items.splice(newLength)

watch

直接触发事件
watch:{
   name:function () {
            this.loadData()
        }
}
详细参数
watch:{
    name:{
       handler(newName,oldName){ //执行代码 }
     },
     //页面首次加载是不会执行的。只有值发生改变才会执行。
     immediate:true 
     
     //监听的是对象类型,当修改对象的某个属性时,是不会触发的。
     deep:true 
     
     //监听整个对象开销大,可以指定属性。
     'obj.a':{  
         deep:true
     }
         
     }
 }

与服务器通讯

异步机制--
这里分多个线程和单个线程。
多个线程天然就是异步了。
JS是单线程,要异步,感觉本质就是轮询+任务池。
放在一个任务池里,(轮询)事件循环(Event Loop),在任务池看是否有需要执行的事件。
再放入一个任务队列(Task Queue)。

这里就关注单线程的异步。

执行步骤
代码的顺序只是顺序执行的顺序。
但执行后步骤是跳跃的,可以进入等待任务池,再弹出执行。
这样后续的顺序是没法保证的。
业务上后面的步骤要在前面步骤完成之后执行。保持序列性。
感觉这里的异步一方面是说流程的挂起,等待,弹出。一方面是说后续流程的衔接。

等待任务

  • 花费事件长
    • 计算量大的,这种貌似只能慢。
    • IO,涉及硬件操作,尤其是网络,涉及外部主体。
  • 定时

JS事件任务

  • DOM Binding--onclick
  • network
  • timer--setTimeout
    就通过JS提供的api放进去吧。

后续流程的衔接。

  • 等异步任务完成,相当于变回同步
    如ajax:async设为false
    怎么阻塞步骤,弄一个while循环?这里没查到具体的实现。
  • 异步任务提供回调挂载点,后续任务挂载上去。
    https://wangdoc.com/javascript/async/general.html
    这里回调的方式挺多种。思路就是直接传入回调函数太耦合。可以事件驱动之类

IO网络对象
A--一个请求调用方
B--一个服务处理方
B这边往往是一个中转B1+后面的群体Bx.
这里可能需要多个链路。来完成收发。

业务上的异步流程
会有长周期的操作。
开辟另一条更松散的通知链路。

  • A提供接收接口/B通知
    xixun屏幕操作
    上传文件,接收进度
  • B提供查询接口/A查询

行为上--

  • 餐馆叫号:先等待服务空闲(拿号,监听),再同步服务

mqtt里的异步
有个标签来标记同一事务。

这里客户端的机制。
JS长时间运行,页面会无响应么?
滚动条能拖拉,但输入框这些都无响应了。

XMLHttpRequest
jquery
axios --基于Promise封装
Fetch-这个是新的原生api

promise机制

把异步函数改造成同步,
多层的回调嵌套--》同层的链式调用。

想想弄个队列,把异步函数放进去。然后顺序执行,等执行完成一个在继续下一个。
怎么算执行完成呢?要在异步函数后面加点啥吧。

这里内容挺丰富的,涉及到挺多不懂的概念。

通过 setTimeout 机制,将 resolve 中执行回调的逻辑放置到JS任务队列末尾,以保证在 resolve 执行时,then方法的 onFulfilled 已经注册完成
js有个消息队列,setTimeout(xx,0).跳过当次循环,让后面的执行。

实现原理大致是内部有个队列维护回调函数。一个个注册进去,然后再弹出来。

//极简的实现
class Promise {
    callbacks = [];
    constructor(fn) {
        fn(this._resolve.bind(this));
    }
    then(onFulfilled) {
        this.callbacks.push(onFulfilled);
    }
    _resolve(value) {
        this.callbacks.forEach(fn => fn(value));
    }
}
//Promise应用
let p = new Promise(resolve => {
    setTimeout(() => {
        console.log('done');
        resolve('5秒');
    }, 5000);
}).then((tip) => {
    console.log(tip);
})

这些的创建有点绕。传入一个函数A,这个函数又要能接收一个传入方法。相当于要在这个传入函数后面加入一段代码。

这里把回调函数挂载到了fn后面。但callbacks里只是遍历执行,如果callbacks里的也是异步函数。感觉也还是会乱呀。

后面是说then这里会继续创建Promise对象。。

箭头函数

resolve=>{}  。这种应该是匿名函数,有一个参数resolve,这里的参数就是(this._resolve.bind(this))

(tip) => {console.log(tip)},这个括号,在参数只有一个时可以省略。  
elements.map(element => element.length);只有一个 `return` 语句时,可以省略 `return` 关键字和方法体的花括号  

function Person(){
  this.age = 0;
  setInterval(() => {
    this.age++; // |this| 正确地指向 p 实例
  }, 1000);
}

不会创建自己的this,它只会从自己的作用域链的上一层继承this。

this._resolve.bind(this)。
这里就是用来传递this,

promise使用

const promise = new Promise(function(resolve, reject) {
  // ... some code
  if (/* 异步操作成功 */){
    resolve(value);
  } else {
    reject(error);
  }
});

promise.then(function(value) {
  // success
}, function(error) {
  // failure
});

看着也是原来的函数,给加上回调,只是这个回调是传入的,resolve()或者reject()。
这里new的时候里面的代码就会运行。

async、await
给函数前加async,声明后面是一个返回Promise对象的函数,本来不是的也会被包装成Promise对象 。
调用就编程 AFun().then(..);

--await.
把promisexx.then中传入的值返回。。
let data=await promisexx;
这里Promise返回后,原先是要用Promise.then(xx),来继续处理返回值。
用了await后,就直接接收返回值。流程看着更加简化。
Lamp中实际用的也都是这种模式。
就和以前ajax,设成同步,流程差不多。

promise中的catch错误呢?

const [err, data] = await fetchData().then(data => [null, data] ).catch(err => [err, null])

promise可以await then一起用。
就是固定返回[err,data]的格式,当success时候error就是null,fail的时候data就是null
返回值可以是一个数组格式?

结合axios。axios的方法就是promise类型。结合上面这些获取数据就和普通函数调用一样。

这里处理失败的消息,如重试;以及对返回结果进行处理,如只取其中一段。
再包装一层promise-PA,原来的axios Promise 传入的时候就会执行,返回的promise对象-PB,再拿来处理。
PB正常,PB.then的处理做为PA的resolve。
PB的错误,再分析处理。

function promiseWrapper(promise) {
    return new Promise(resolve => {
        if (!!promise && typeof promise.then === 'function') {
            promise.then(res => {
                resolve(res)
            }).catch((error) => {
                if (error.response.status == 500) {
                    resolve({
                        status: 200,
                        data: error.response.data
                    })
                }
            })
        }
    })
}
目前还搞不太清楚这块
卡莱特这边。
错误status是400
会到catch(error)这里
不处理,那就没有返回。
resolve(error)直接返回错误
记录到的返回值
Error: Request failed with status code 400
    at createError (createError.js?2d83:16:1)
    at settle (settle.js?467f:17:1)
    at XMLHttpRequest.handleLoad (xhr.js?b50d:61:1)

携带cookie
这里比较麻烦,
跨域登录后服务器返回Set-Cookie,但新版的chrome有个SameSite策略,会显示一个感叹号标记。
压根就不写入cookie。
网上说的浏览器设置也都不再适用。

axio这里再怎么设置也是无源之水。

然后axio设置后,访问本站地址是会带cookie,访问跨域是不带的,
不知道是限制不让带,还是说没找到跨域网站的cookie。
application中只能手动添加已有cookie的网站。

要么降级浏览器,要么两个网站都用nginx代理。

header
设置默认
instance.defaults.headers.post['Content-Type'] = 'multipart/form-data"';
单独设置
instance.post('/wp-json/wp/v2/programs', widget, { headers: { "Content-Type": "application/json" } })
下次调用其它的api还是会用defaults。

几个方面

  • 交互的body格式
  • 返回的往往都关注到response值,这里返回的数据是很全的。header,general-status

交互参数

post<T = any, R = AxiosResponse<T>>(url: string, data?: any, config?: AxiosRequestConfig): Promise<R>;
可以直接把提交数据写在第二个参数。
AxiosRequestConfig这里也可以设置详尽的参数
{
 headers:{
    'Content-Type': 'application/x-www-form-urlencoded'
  },    
  data: new URLSearchParams({
      'userName': '[email protected]',
      'password': 'Password!',
  }?
}
get--要在AxiosRequestConfig中填params参数。一般就{params}这样

url栏参数
序列化
URLSearchParams
qs.stringify
两种看着基本的都有,[数组,对象]->查询字符串。
看着qs这个对于数组的序列化更精细。有好几种arrayFormat。格式会不同
'a[0]=b&a[1]=c','a[]=b&a[]=c','a=b&a=c'

body

  • form-data
    实际数据
------WebKitFormBoundaryW5lVt9jWzIweckdo
Content-Disposition: form-data; name="log"
user3
------WebKitFormBoundaryW5lVt9jWzIweckdo
Content-Disposition: form-data; name="pwd"
Hcxny321

用 new FormData()来封装

  • x-www-form-urlencoded
    实际数据 key=value&key=value,和url栏参数格式一样的。
    对象参数需要遍历重新组织。
    一般URLSearchParams(object)转换
  • raw
    • json
      有JSON.stringify()方法可以转换对象到json
      axios内置了转换过程,一般就直接传对象。
      这里的json参数,
  • binary

这里会有组合如x-www-form里的数据是value为json格式。
先 obj.properyA=JSON.stringify(objA)
再 URLSearchParams(obj).

 
 

标签:Vue,定义,--,前端,语法,resolve,组件,data,函数
From: https://www.cnblogs.com/halfwake/p/17408561.html

相关文章

  • vue设置全局scss,报错
    sass-loader版本问题引发的错误:optionshasanunknownproperty'prependData'.Thesepropertiesarevalid当前版本如下:"sass":"^1.32.7","sass-loader":"^12.0.0",原来的写法:css:{loaderOptions:{sass:{......
  • 如何搭建一个vue项目
    一、nvm安装与使用1.1、nvm简介nvm全名node.jsversionmanagement,顾名思义是一个nodejs的版本管理工具。通过它可以安装和切换不同版本的nodejs1.2、nvm下载①github下载https://github.com/coreybutler/nvm-windows/releases②百度网盘下载链接:https://pan.baidu.com/s/1......
  • Vue ElementUI中 table单元格使用多个Popover解决多行溢出隐藏鼠标悬浮提示问题
    Popover的简单介绍trigger属性用于设置何时触发Popover,支持四种触发方式:hover,click,focus和manual。对于触发Popover的元素,有两种写法:使用slot=“reference”的具名插槽,或使用自定义指令v-popover指向Popover的索引ref。placement弹框的出现位置value/v-model状态......
  • 最近遇到的一个问题 后端写好的接口,前端怎么获取数据
    这是我后端的接口:GET接口这是我前端运行的项目地址:简单使用:咱门前端使用颇受好评的axios来发起请求这是它的官网:https://www.axios-http.cn/不过要在vue中使用它,就需要先安装打开终端输入一下命令 npminstallaxios然后在需要使用的页面<script>中标签引入a......
  • Nginx 常用的基础配置(web前端相关方面)
    基础配置userroot;worker_processes1;events{worker_connections10240;}http{log_format'$remote_addr-$remote_user[$time_local]''"$request"$st......
  • 前端-VUE
    工程化这里要从node.js开始。node.js要弄一个基于事件驱动、非阻塞I/O的的web服务,发现V8引擎+JavaScript很合适。这样Js就能直接写后端应用。然后发展成作为本地的运行容器(类似jdk),将js导入到了本地运行领域。以此位基础,发展出了生态环境,里面关系挺绕的,各种轮子,互相占位。......
  • vue自定义组件——search-box
    github地址:https://github.com/lxmghct/my-vue-components组件介绍props:value/v-model:检索框的值,default:''boxStyle:检索框的样式,default:'position:fixed;top:0px;right:100px;'highlightColor:高亮颜色,default:'rgb(246,186,130)'......
  • 企业级项目模板的配置与集成(Vite + Vue3 + TypeScript)
    企业级项目模板的配置与集成(Vite+Vue3+TypeScript)1、项目介绍项目使用:eslint+stylelint+prettier来对我们代码质量做检测和修复。需要使用husky来做commit拦截需要使用commitlint来统一提交规范需要使用preinstall来统一包管理工具。2、环境准备nodev16.14.2pnp......
  • Vue的生命周期
    varvm=newVue({el:"#app",//在基础初始化完成之后,数据和事件配置之前调用beforeCreate(){console.log("beforeCreate")},//初始化全部完成,实例创建完成后立即调用created(){console.log("created")},//挂载之......
  • VUE前端随笔计2
    又是小白记录问题的一次,老规矩,还是抄别人的代码来改。 在表标签中找到了一个点击事件定位代码,对比别人的,发现自己的删多了,把这个补充回去就行了,具体意思不太明白,大概是给这个模型里面填充这行数据。 ......