Mustache插值采用{{ }},用于解析标签体内容,将Vue实例中的数据插入DOM中
<h1>Hello {{name}}</h1>
指令用于解析标签,是vue为开发者提供的一套模板语法,辅助开发者渲染页面的基本结构。
(指令是vue开发中最基础、最常用、最简单的知识点)(支持绑定简单的数据值之外,还支持js表达式运算)
1、v-text=" " 会覆盖元素内默认的值、无法写HTML标签语句
2、{{ }} 插值表达式(Mustache) 不会覆盖元素中默认的内容
3、v-html 可以渲染包含HTML标签的字符串
v-html有安全性问题,在网站上动态渲染任意HTML是非常危险的,容易导致XSS攻击;永远不要再用户提交的内容上使用v-html。
v-bind: 为元素的属性动态绑定属性值
属性:placeholder、src等
简写::
<a v-bind:href="url">点击跳转</a>
<a :href="url">点击跳转</a>
v-on: 为DOM元素绑定事件监听
v-on:click=” “、v-on:input、v-on:keyup
事件处理函数,需要在methods节点中进行声明
简写:@、如果事件处理函数的代码足够简单,只有一行代码,则可以简写到行内
<body>
<div id="app">{{username}}</div>
<button @click="addcount($event,88)">
点击我
</button>
<script src="vue.js"></script>
<script>
const vm=new Vue({
el:'#app',
data:{
username:'zs',
count:0
},
methods:{
addcount(e,88){
const nowBgColor =e.target.style.backgroundColor
console.log(nowB gColor)
this.count+=1
}
}
})
</script>
</body>
绑定事件并传参,使用() 小括号,但会占用event的位置
$event是vue提供的特殊变量用于占位,用来表示原生事件参数对象event,使用e接受
vue提供事件修饰符,来辅助程序员更方便的对事件的触发进行控制
.stop阻止事件冒泡()里到外
.prevent 阻止默认行为()比如阻止跳转
.capture以捕获模式触发当前事件处理函数(外到里)
.self只有在event.target是当前元素自身时触发事件处理函数
.once绑定的事件只触发一次
.passive事件的默认行为立即执行,无需等待事件回调执行完毕
监听键盘事件时,我们经常需要判断详细的按键,此时可为键盘相关的事件添加按键修饰符
v-model 在不操作DOM的情况下,快速获取表单数据(只能配合表单元素一起使用)
<input type="text" v-model:value="username"/>
<input type="text" v-model="username"/>
方便用户对输入的内容进行处理
.number自动将用户输入值转化为数值.trim 自动过滤用户输入的首尾空白字符.lazy 在change时更新而非input时更新(不实时更新,文本框失去焦点更新)按需控制DOM的显示和隐藏
v-if =" " 动态创建或移除DOM元素,有更高的切换开销(重绘和回流)
v-else-if =" "、v-else =" "
v-show=" " 动态为元素添加或移除display样式,有更高的初始渲染开销。
v-for=" " 辅助开发者基于一个数组来循环渲染相似的UI结构
特殊语法:item in items
<body>
<div id="root">
<!-- 遍历数组 -->
<ul>
<li v-for="item in persons" :key="item.id">
{{item.id}}-{{item.name}}-{{item.age}}
</li>
</ul>
<!-- 遍历对象 -->
<ul>
<li v-for="(value,key) of cars" :key="key">
{{key}}-{{value}}
</li>
</ul>
<!-- 遍历字符串 -->
<ul>
<li v-for="(char,index) of str" :key="index">
{{index}}-{{char}}
</li>
</ul>
<!-- 遍历指定次数 -->
<ul>
<li v-for="(number,index) of 5" :key="index">
{{index}}-{{number}}
</li>
</ul>
</div>
<script type="text/javascript">
Vue.config.productionTip = false;
const vm=new Vue({
el:'#root',
data:{
persons:[
{id:'001',name:'张三',age:18},
{id:'002',name:'李四',age:17},
{id:'003',name:'王五',age:42},
],
cars:{
name:'Audi',
price:"70W",
color:"black"
},
str:"hello"
}
})
</script>
</body>
for in一般遍历对象,不建议遍历数组。遍历数组请使用for of或forEach。
(item,index) in items
注:v-for中的item项和index索引都是形参,任意命名
当列表的数据变化(添加、删除)时,vue会尽可能复用已存在的DOM元素,从而提升渲染的性能,但这种性能优化策略会导致有状态的列表无法被正确更新,key的使用将减少不必要的DOM操作,提高更新效率。
解释:
Vue根据初始数据生成初始虚拟DOM(Vnodes),将虚拟DOM转为真实DOM,用户添加新的数据,产生新虚拟DOM(Vnodes),此时将两份虚拟DOM根据key进行对比(diff 算法),如果对比一样的直接复用,将之前的真实DOM直接渲染;不一样的无法复用,将其生成真实DOM。
为了给vue一个提示,以便它能跟踪每个节点的身份,需要为每项提供一个唯一的key属性


注:
key只能是字符串或数字类型
key的值必须具有唯一性
建议把数据项id属性的值作为key的值,将index的值作为key的值没有任何意义(https://blog.csdn.net/z591102/article/details/106682298/)
建议使用v-for时一定要指定key的值(提升性能,防止列表状态紊乱)
但不存在对数据的操作,仅是渲染列表用于展示,使用index作为key没有问题

v-cloak没有值,配合CSS,解决网速慢、服务器响应慢时未经解析的模板渲染到页面上,Vue实例创建并接管容器后,会删掉该属性。
[v-cloak]:{
display:none;
}
v-once没有值,记录初始值,在初次动态渲染后,就视为静态内容,以后数据的改变不会引起v-once所在结构的更新,可以用于性能优化。
v-pre没有值,跳过其所在节点的编译过程,可以用它跳过:没有使用指令语法、插值语法的节点,会加快编译。
本质:将原生操作DOM进行二次封装。
<body>
<div id="root">
<!-- v-big放大10倍 -->
<h2>当前的n值是:<span v-text="n"></span></h2>
<h2>放大10倍后的n值是:<span v-big="n"></span></h2>
<button @click="n++">点位n++</button>
<hr>
<!-- v-fbind在v-bind基础上,自动获得焦点 -->
<input type="text" v-fbind:value="n">
</div>
<script type="text/javascript">
Vue.config.productionTip = false;
const vm=new Vue({
el:'#root',
data:{
n:0,
},
directives:{
//函数式
//何时会被调用:1、指令和元素成功绑定;2、指令所在的模板被重新解析时
big(element,binding){
element.innerText=binding.value*10
},
//错误写法:
fbind(element,binding){
element.value=binding.value
element.focus()//.focus()调用时机不对,此时input还未被插入页面
},
//对象式
fbind:{
//指令与元素成功绑定时调用
bind(element,binding){
element.value=binding.value
},
//指令所在元素被插入页面时调用
inserted(element,binding){
element.focus()
},
//指令所在模板被重新解析时调用
update (element,binding) {
element.value=binding.value
},
}
},
})
</script>
</body>
注意:
-分隔;this的指向是window;Vue.directive;计算属性本质上就是一个function函数,它可以实时监听data中数据的变化,并return一个计算后的新值,供组件渲染DOM时使用。
开发者需要以function函数的形式声明到组件的computed节点中
<template>
<div>
<input type="text" name="" id="" v-model.number="count">
<p>{{count}} 乘以2的值为:{{plus}}</p>//必须当做普通属性使用
</div>
</template>
<script>
export default {
name:'MyCount',
data(){
return{
count:1,
}
},
//必须定义在computed节点
computed:{
//必须是一个function函数
plus(){
//必须具有返回值
return this.count*2
}
//相当于
plus:{
//当读取plus,get会被调用,且返回值作为plus的值
//get何时被调用?1、初次调用plus;2、所依赖的数据发生变化
get(){
return this.count*2
}
}
}
}
</script>
侧重于得到一个计算的结果,必须有return返回值
计算属性(computed)vs方法(methods):
相对于方法,计算属性会缓存计算结果,只有计算属性的依赖项发生变化时,才会重新进行运算,因此计算属性的性能会更好。
watch侦听器允许开发者监视数据的变化,从而针对数据的变化做特定的操作
开发者需要在watch节点之下,定义自己的侦听器
<script>
export default {
name:'MyCount',
data(){
return{
username:'',
}
},
watch:{
//当username发生改变时,调用 handler
username:{
handler(newVal,oldVal){
console.log(newVal,oldVal)
}
}
//简写
username(newVal,oldVal){
console.log(newVal,oldVal)
}
}
}
</script>
<body>
<div id="app">{{username}}</div>
#导入脚本文件
<script src="vue.js"></script>
<script>
const vm=new Vue({
data(){
return{
username:'zs'
}
}
})
vm.$mount=('#app')//挂载
vm.$wtach('username',{ //第二种写法
handler(newVal,oldVal){
console.log(newVal,oldVal)
}
})
//简写
vm.$wtach('username',function(newVal,oldVal){
console.log(newVal,oldVal)
}
})
</script>
</body>
使用watch检测用户名是否可用,监听username值得变化,并使用axios发起ajax请求,检测当前输入的用户名是否可用
<script>
import axios from 'axios'
export default {
name:'MyCount',
data(){
return{
username:'',
}
},
watch:{
async username(newVal,oldVal){
console.log(newVal,oldVal)
const {data:res}=await axios.get('https://www.escook.cn/api/finduser'+newVal)
//await简化promise实例对象为数据
console.log(res)
}
}
}
</script>
默认组件在初次加载完毕后不会调用watch侦听器,如果想让watch侦听器立即被调用,则需要使用immediate选项
<script>
import axios from 'axios'
export default {
name:'MyCount',
data(){
return{
username:'',
}
},
watch:{
//不能直接定义成方法,要让监听的数据指向一个配置对象
username:{
async handler(newVal,oldVal){
const {data:res}=await axios.get('https://www.escook.cn/api/finduser'+newVal)
//await简化promise实例对象为数据
console.log(res)
},
//立即触发watch侦听器
immediate:true,
}
}
}
</script>
当watch侦听的是一个对象,如果对象中的属性值发生了变化,则无法被监听到,需要使用deep选项侦听所有属性的变化。
<script>
import axios from 'axios'
export default {
name:'MyCount',
data(){
return{
username:'',
}
},
watch:{
//不能直接定义成方法,要让监听的数据指向一个配置对象
username:{
async handler(newVal,oldVal){
const {data:res}=await axios.get('https://www.escook.cn/api/finduser'+newVal)
//await简化promise实例对象为数据
console.log(res)
},
deep:true,//监视多级结构(对象)中所有属性的变化
}
}
}
</script>
<script>
import axios from 'axios'
export default {
name:'MyCount',
data(){
return{
info:{username:'zs',password:'123456'}
}
},
watch:{
//不能直接定义成方法,要让监听的数据指向一个配置对象
'info.username':{//只想监听info.username的属性变化
async handler(newVal,oldVal){
const {data:res}=await axios.get('https://www.escook.cn/api/finduser'+newVal)
//await简化promise实例对象为数据
console.log(res)
},
deep:true,
}
}
}
</script>
前者侧重监听多个值的变化,最终计算返回一个新值
后者侧重于单个数据的变化,最终执行特定的业务处理,不需要任何返回值
两个原则:
<!--字符串写法,适用于样式的类名不确定,需要动态指定-->
<h1 class="basic" :class:"className">Hello World!</h1>
<!--数组写法,适用于样式的个数和类名都不确定-->
<h1 class="basic" :class:"classArr">Hello World!</h1>
<!--对象写法,适用于样式的个数和类名都确定,但要动态觉得用不用-->
<h1 class="basic" :class:"classObj">Hello World!</h1>
<!--动态指定-->
<h1 class="basic" :style="{fontSize: fsize+'px';}">Hello World!</h1>
<h1 class="basic" :style="styleObj">Hello World!</h1>
<h1 class="basic" :style="[styleObj1,styleObj2]">Hello World!</h1>
(Vue3.x废弃,用计算属性、方法代替)
过滤器(Filters)常用于文本的格式化,本质是一个函数
过滤器应该被添加到js表达式的尾部,由“管道符”进行调用
在创建vue实例期间,可以在filters节点中定义过 滤器
私有过滤器:只能在被vm实例控制的区域下控制
如果想在多个vue实例之间共享过滤器,则可以按照如下格式声明全局过滤器:
<script>
vue.filter('capitalize',(str)=>{
return str.charAt(0).toUpperCase() + str.slice(1)+'--'
})
new Vue...
</script>
注:如果二者冲突以私有过滤器为准,就近原则
过滤器可以串联的地调用
{{message | capitalize | maxlength}
过滤器本质是js函数,第一个参数永远是管道符前面的值,第二个参数开始才是arg1、arg2...
{{message | filterA(agr1,arg2)}
vue.filter('filterA',(msg,arg1,aarg2)=>{})
在vue3.x版本中已经剔除了过滤器相关功能,可以使用计算方法或属性来代替
我脑子里浮现出一些关于一种新编程语言的想法,所以我想我会尝试实现它。一位friend建议我尝试使用Treetop(Rubygem)来创建一个解析器。Treetop的文档很少,我以前从未做过这种事情。我的解析器表现得好像有一个无限循环,但没有堆栈跟踪;事实证明很难追踪到。有人可以指出入门级解析/AST指南的方向吗?我真的需要一些列出规则、常见用法等的东西来使用像Treetop这样的工具。我的语法分析器在GitHub上,以防有人希望帮助我改进它。class{initialize=lambda(name){receiver.name=name}greet=lambda{IO.puts("He
所以我在关注Railscast,我注意到在html.erb文件中,ruby代码有一个微弱的背景高亮效果,以区别于其他代码HTML文档。我知道Ryan使用TextMate。我正在使用SublimeText3。我怎样才能达到同样的效果?谢谢! 最佳答案 为SublimeText安装ERB包。假设您安装了SublimeText包管理器*,只需点击cmd+shift+P即可获得命令菜单,然后键入installpackage并选择PackageControl:InstallPackage获取包管理器菜单。在该菜单中,键入ERB并在看到包时选择
在Ruby类中,我重写了三个方法,并且在每个方法中,我基本上做同样的事情:classExampleClassdefconfirmation_required?is_allowed&&superenddefpostpone_email_change?is_allowed&&superenddefreconfirmation_required?is_allowed&&superendend有更简洁的语法吗?如何缩短代码? 最佳答案 如何使用别名?classExampleClassdefconfirmation_required?is_a
可能已经问过了,但我找不到它。这里有2个常见的情况(对我来说,在编程Rails时......)用ruby编写是令人沮丧的:"astring".match(/abc(.+)abc/)[1]在这种情况下,我得到一个错误,因为字符串不匹配,因此在nil上调用[]运算符。我想找到的是比以下内容更好的替代方法:temp="astring".match(/abc(.+)abc/);temp.nil??nil:temp[1]简而言之,如果不匹配,则简单地返回nil而不会出错第二种情况是这样的:var=something.very.long.and.tedious.to.writevar=some
我正在学习Ruby的基础知识(刚刚开始),我遇到了Hash.[]method.它被引入a=["foo",1,"bar",2]=>["foo",1,"bar",2]Hash[*a]=>{"foo"=>1,"bar"=>2}稍加思索,我发现Hash[*a]等同于Hash.[](*a)或Hash.[]*一个。我的问题是为什么会这样。是什么让您将*a放在方括号内,是否有某种规则可以在何时何地使用“it”?编辑:我的措辞似乎造成了一些困惑。我不是在问数组扩展。我明白了。我的问题基本上是:如果[]是方法名称,为什么可以将参数放在括号内?这看起来几乎——但不完全是——就像说如果你有一个方法Foo.d
项目介绍随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱小学生兴趣延时班预约小程序的设计与开发被用户普遍使用,为方便用户能够可以随时进行小学生兴趣延时班预约小程序的设计与开发的数据信息管理,特开发了小程序的设计与开发的管理系统。小学生兴趣延时班预约小程序的设计与开发的开发利用现有的成熟技术参考,以源代码为模板,分析功能调整与小学生兴趣延时班预约小程序的设计与开发的实际需求相结合,讨论了小学生兴趣延时班预约小程序的设计与开发的使用。开发环境开发说明:前端使用微信微信小程序开发工具:后端使用ssm:VU
我正在尝试使用ruby编写一个双线程客户端,一个线程从套接字读取数据并将其打印出来,另一个线程读取本地数据并将其发送到远程服务器。我发现的问题是Ruby似乎无法捕获线程内的错误,这是一个示例:#!/usr/bin/rubyThread.new{loop{$stdout.puts"hi"abc.putsefsleep1}}loop{sleep1}显然,如果我在线程外键入abc.putsef,代码将永远不会运行,因为Ruby将报告“undefinedvariableabc”。但是,如果它在一个线程内,则没有错误报告。我的问题是,如何让Ruby捕获这样的错误?或者至少,报告线程中的错误?
这个问题在这里已经有了答案:WhatisRuby'sdouble-colon`::`?(12个答案)关闭8年前。什么是::?@song||=::TwelveDaysSong.new
在添加一些空格以使代码更具可读性时(与上面的代码对齐),我遇到了这个:classCdefx42endendm=C.new现在这将给出“错误数量的参数”:m.x*m.x这将给出“语法错误,意外的tSTAR,期待$end”:2/m.x*m.x这里的解析器到底发生了什么?我使用Ruby1.9.2和2.1.5进行了测试。 最佳答案 *用于运算符(42*42)和参数解包(myfun*[42,42])。当你这样做时:m.x*m.x2/m.x*m.xRuby将此解释为参数解包,而不是*运算符(即乘法)。如果您不熟悉它,参数解包(有时也称为“spl
我使用Jekyll运行博客,并认为我会解决RedcarpetMarkdown解释器,因为它是developedandusedbyGitHub.好吧,我只是碰巧遇到了一个错误,去检查问题,然后foundthis.Maintainersays,"Asyouprobablyhavenoticed(harharharhar)Idon'thavetimetomaintainRedcarpetanymore.It'snotapriorityforme(IfindMarkdownthoroughlyboring)andit'snotapriorityforGitHub,becausewenolong