vue基础(一)补充1
vue实例对象#
-
以
$
开头的公有属性$el
-
以
_
开头的私有属性_data
打印vue实例对象发现,其中 el 被Vue 放入了公有属性中,而data 则被放入了 私有属性中
数据绑定#
单向数据绑定 data#
我们通过 vue 对象修改数据可以直接影响到 DOM 元素,但是,如果直接修改 DOM 元素,却不会影响到 vue 对象的数据;我们把这种现象称为 单向数据绑定 ;
双向数据绑定 v-model#
双向数据绑定的应用范围
-
文本框 & 文本域
-
绑定复选框
<div id="div"> 吃饭:<input type="checkbox" value="eat" v-model="checklist"><br> 睡觉:<input type="checkbox" value="sleep" v-model="checklist"><br> 打豆豆:<input type="checkbox" value="ddd" v-model="checklist"><br> {{ checklist }} </div> <script> var vm = new Vue({ el: '#div', data: { checklist: [] } }); </script>
-
绑定单选框
<div id="app"> 男<input type="radio" name="sex" value="男" v-model="sex"> 女<input type="radio" name="sex" value="女" v-model="sex"> <br> {{sex}} </div> <script> var vm = new Vue({ el: '#app', data: { sex: '' } }); </script>
修饰符#
.lazy
- 取代 input
监听 change
事件
.number
- 输入字符串转为有效的数字
.trim
- 输入首尾空格过滤
<div id="div">
<input type="text" v-model.lazy="input_val">
{{input_val}}
</div>
<script>
var app = new Vue({
el: '#div',
data: {
input_val: 'hello world '
}
})
</script>
指令#
v-if / v-else / v-else-if 条件判断
https://cn.vuejs.org/v2/api/#v-if
<div id="app">
<div v-if="type === 'A'">
A
</div>
<div v-else-if="type === 'B'">
B
</div>
<div v-else-if="type === 'C'">
C
</div>
<div v-else>
Not A/B/C
</div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
type: 'F'
},
})
</script>
v-cloak
https://cn.vuejs.org/v2/api/#v-cloak
和 CSS 规则如 [v-cloak] { display: none }
一起用时,这个指令可以隐藏未编译的 Mustache 标签直到实例准备完毕。
<div id="app">
<p>{{obj.id}}</p>
</div>
<script src="./vue.js"></script>
<script>
setTimeout(() => {
var vm = new Vue({
el: '#app',
data: {
arr: ['a', 'b', 'c'],
obj: { id: 1, name: '李四' }
},
})
}, 2000);
</script>
当我们的网络受阻时,或者页面加载完毕而没有初始化得到 vue 实例时,DOM中的 {{}}
则会展示出来;
为了防止现象,我们可以使用 CSS 配合 v-cloak 实现获取 VUE 实例前的隐藏;
<style>
[v-cloak] {
display: none;
}
</style>
<div id="app">
<p v-cloak>{{obj.id}}</p>
</div>
<script src="./vue.js"></script>
<script>
setTimeout(() => {
var vm = new Vue({
el: '#app',
data: {
obj: { id: 1, name: '李四' }
},
})
}, 2000);
</script>
v-once
https://cn.vuejs.org/v2/api/#v-once
只渲染元素和组件一次。随后的重新渲染,元素/组件及其所有的子节点将被视为静态内容并跳过
<div id="app">
<p v-once>{{msg}}</p>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
msg:'kkk'
},
})
</script>
计算属性与侦听器#
1. 计算属性
<div id="div">
<input type="text" v-model="xing">
<input type="text" v-model="ming">
{{xing + ming}}
</div>
<script>
var app = new Vue({
el: '#div',
data: {
xing:'',
ming:'',
}
})
</script>
模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护。因此我们可以使用方法,来进行运算并返回数据:
<div id="div">
<input type="text" v-model="xing">
<input type="text" v-model="ming">
{{ fullname() }}
<!-- 一百次调用,观察时间结果-->
{{ fullname() }}
</div>
<script>
var app = new Vue({
el: '#div',
data: {
xing:'',
ming:'',
},
methods:{
fullname(){
return this.xing+this.ming+Date.now();
}
}
})
</script>
注意,每次在模板中使用 {{ fullname() }}
fullname方法就会被调用执行一次;所以,对于任何复杂逻辑,你都应当使用计算属性 ,因为计算属性,会自动缓存数据:
<div id="div">
<input type="text" v-model="xing">
<input type="text" v-model="ming">
<br>
{{fulln}}
<!-- 一百次调用 -->
{{fulln}}
</div>
<script>
var app = new Vue({
el: '#div',
data: {
xing:'',
ming:'',
},
computed:{
fulln(){
return this.xing+this.ming+Date.now();
}
}
})
</script>
我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。然而,不同的是计算属性是基于它们的依赖进行缓存的。只在相关依赖发生改变时它们才会重新求值;多次调用,计算属性会立即返回之前的计算结果,而不必再次执行函数。
2. 使用侦听器
<div id="div">
<input type="text" v-model="xing">
<input type="text" v-model="ming">
{{ fullname }}
</div>
<script>
var app = new Vue({
el: '#div',
data: {
xing: '',
ming: '',
fullname:''
},
// 设置侦听器
watch: {
// 侦听器中的方法名和要侦听的数据属性名必须一致
// xing 发生变化,侦听器就会被执行,且将变化后的值和变化前的值传入
xing:function(newVal,old_val){
this.fullname = newVal+this.ming;
},
ming:function(newVal,oldVal){
this.fullname = this.xing+newVal;
}
}
})
</script>
通过上面的案例,我们基本掌握了侦听器的使用,但是我们也发现,与计算属性相比,侦听器并没有优势;也不见得好用,直观上反而比计算属性的使用更繁琐;
虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。这就是为什么 Vue 通过 watch
选项提供了一个更通用的方法,来响应数据的变化。当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。
<div id="div">
<input type="text" v-model="xing">
<input type="text" v-model="ming">
{{ fullname }}
</div>
<script src="./jq.js"></script>
<script>
var app = new Vue({
el: '#div',
data: {
xing: '',
ming: '',
fullname:''
},
// 设置侦听器
watch: {
// 侦听器中的方法名和要侦听的数据属性名必须一致
// xing 发生变化,侦听器就会被执行,且将变化后的值和变化前的值传入
xing:function(newVal,old_val){
// this.fullname = newVal+this.ming;
var t = this;
// 在侦听器中执行异步网络请求
$.get('./xx.php',(d)=>{
t.fullname = d;
})
},
}
})
</script>
过滤器的使用#
私有(局部)过滤器
1.定义过滤器
var app = new Vue({
el: '#app',
data:{msg:'UP'},
//定义过滤器
filters:{
// 过滤器的名称及方法
myFilters:function(val){
return val.toLowerCase();
}
}
})
过滤器的使用:
Vue.js 允许你自定义过滤器,可被用于一些常见的文本格式化转义等操作。过滤器可以用在两个地方:双花括号插值和 v-bind 表达式 (后者从 2.1.0+ 开始支持)。过滤器要被添加到操作值得后面,使用 管道符 |
分割;vue会自动将操作值,以实参的形式传入过滤器的方法中;
{{msg|myFilters}}
过滤敏感词汇
<div id="app">
<input type="text" v-model="msg"> <br>
{{msg|myFilters|get3}}
</div>
<script>
var app = new Vue({
el: '#app',
data:{
msg:''
},
//定义过滤器
filters:{
// 过滤器的名称及方法
myFilters:function(val){
return val.toLowerCase();
},
get3:function(val){
// 遇到数字替换为 0
// var reg = /\d/g;
// return val.replace(reg,0);
return val.replace('苍井空','***');
}
}
})
</script>
2.全局过滤器
Vue.filter(名称,处理器)
Vue.filter('myFilters', function (val) {
return val.toLowerCase();
})
自定义指令#
前面我们学过 v-on 、v-model、v-show
等指令,在操作 dom 时使用了 ref 属性,其实之前学过的指令也是操作dom 的一种方式,但有时,这些指令并不能满足我们的需求,因此 vue 允许我们自定义指令来操作 dom
全局自定义指令
<div id="app">
<p v-setcolor>自定义指令的使用</p>
</div>
<script>
// 注册一个全局自定义指令 `v-focus`
Vue.directive('setcolor', {
// 当被绑定的元素插入到 DOM 中时……
inserted: function (el) {
// 聚焦元素
el.style.color = 'red';
}
})
var app = new Vue({
el: '#app',
})
</script>
私有(局部)自定义指令
<div id="app">
<p v-setcolor>自定义指令的使用</p>
</div>
<script>
var app = new Vue({
el: '#app',
// 注册 局部(私有)指令
directives: {
// 定义指令名称
setcolor: {
// 当被绑定的元素插入到 DOM 中时……
inserted: function (el) {
// 聚焦元素
el.style.color = 'red';
}
}
}
})
</script>
为自定义指令传值
之前学习的指令中,有的指令可以传值,有的则没有,而我们自定的指令中是没有值的,如果想为自定义指令赋值,如下即可:
<div id="app">
<p v-setcolor='colors'>自定义指令的使用</p>
</div>
<script>
var app = new Vue({
el: '#app',
data:{
colors:'yellow'
},
// 注册 局部(私有)指令
directives: {
// 定义指令名称
setcolor: {
// 自定义指令可以接受第二个参数
inserted: function (el,val) {
// 第二个参数中包含了指令名称、挂载名称及数据键值
console.log(val);
// 聚焦元素
el.style.color = val.value;
}
}
}
})
</script>
组件#
组件系统是 Vue 的一个重要概念,因为它是一种抽象,允许我们使用小型、独立和通常可复用的组件构建大型应用
使用注意#
组件名如果是驼峰法命名,使用组件时要将大写字母改为小写,并且在前面加上 -
组件中的tamplate属性必须有一个唯一的根元素,否则会报错
组件中的数据及方法#
组件是带有名字的可复用的 Vue 实例 ,所以它们与 new Vue
实例对象接收相同的参数选项 data
、computed
、watch
、methods
, 但 el
例外;
虽然组件和实例对象可以接收相同的参数选项,但在具体使用中,vue实例对象的 data
与组件中的 data
还是有差异的, 在我们自己写的组件中,data 必须是一个函数
一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回的对象;
除 data
选项外,其他选项的使用都是一样的;
router-view#
<div id="app">
<ul>
<li><router-link to="/login">登录</router-link></li>
<li><router-link to="/register">注册</router-link></li>
<!-- <li><a href="#/login">登录</a></li>
<li><a href="#/register">注册</a></li> -->
<!-- router-link 会被解析为a标签 -->
<!--
不同的是,router-link在解析为a标签后,
会自动为点击的 a 标签添加class属性
-->
</ul>
<!-- 路由中设置的组件会替换router-view标签 -->
<router-view></router-view>
</div>
使用 router-link 的一大好处就是,每当我们点击时,在标签内就会自动帮我们添加 class 属性,而此时,我们就可以利用 class 属性,来定义样式:
<style>
.router-link-active {
color: red;
}
</style>
动态路由匹配#
假设有一个用户列表,想要删除某一个用户,需要获取用户的id传入组件内,如何实现呢?
此时可以通过路由传参来实现,具体步骤如下:
-
通过
传参,在路径上传入具体的值 <router-link to="/users/120">用户管理</router-link>
-
路由规则中增加参数,在path最后增加 :id
{ name: 'users', path: '/users/:id', component: Users },
-
在组件内部可以使用,this.$route 获取当前路由对象
var Users = { template: '<div>这是用户管理内容 {{ $route.params.id }}</div>', mounted() { console.log(this.$route.params.id); } };
语法检查#
注意 :如果我们在 构建项目时 选择了 Use ESLint to lint your code
那么我们在写代码时必须严格遵守 JavaScript Standard Style 代码风格的语法规则:
- 使用两个空格 – 进行缩进
- 字符串使用单引号 – 需要转义的地方除外
- 不再有冗余的变量 – 这是导致 大量 bug 的源头!
- 无分号 – 这没什么不好。不骗你!
- 行首不要以
(
,[
, or ``` 开头- 这是省略分号时唯一会造成问题的地方 – 工具里已加了自动检测!
- 详情
- 关键字后加空格
if (condition) { ... }
- 函数名后加空格
function name (arg) { ... }
- 坚持使用全等
===
摒弃==
一但在需要检查null || undefined
时可以使用obj == null
。 - 一定要处理 Node.js 中错误回调传递进来的
err
参数。 - 使用浏览器全局变量时加上
window
前缀 –document
和navigator
除外- 避免无意中使用到了这些命名看上去很普通的全局变量,
open
,length
,event
还有name
。
- 避免无意中使用到了这些命名看上去很普通的全局变量,
说了那么多,看看这个遵循了 Standard 规范的示例文件 中的代码吧。或者,这里还有一大波使用了此规范的项目 代码可供参考。
注意: 如果你不适应这些语法规则,可以在构建项目时不使用 ESLint 的语法检查
ES6模块化
http://es6.ruanyifeng.com/#docs/module
总结:
- CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用;
- CommonJS 模块是运行时加载,ES6 模块是编译时输出接口;
- ES6 的模块自动采用严格模式,不管你有没有在模块头部加上
"use strict";
; - ES6 模块之中,顶层的
this
指向undefined
;CommonJS 模块的顶层this
指向当前模块;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?