Vue.js初学笔记
1、vue.js简介
vue.js是一个web端的渐进式框架。MVVM模式(Model-View-ViewModel)MVC的改进版,分离视图UI与业务逻辑。核心:是一个允许采用简洁的模板语法来声明式的将数据渲染进DOM的系统。
2、开始使用vue.js 并 创建第一个vue实例
- 使用script标签引入vue.js文件。浏览器控制台看到vue警告表引入成功!
- 当引入vue.js时,会声明一个名为Vue的全局变量。
- 可通过new Vue();的方式可以得到一个Vue对象。在new Vue();的时候需要传递两个属性
el
:(element)即元素。后填写视图中id的值。类似于id选择器。
data
:(数据,即变量。)可以在data中注册视图中的变量,并对其进行初始化赋值。
<!-- 视图:{{}}:是vue常见的文本插值方式 -->
<div id="app">
{{ message }} {{name}}
</div>
<script src="vue.js" type="text/javascript" charset="utf-8"></script>
<!-- 脚本 -->
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!',
name : "Vue"
}
});
</script>
3、vue的数据与方法
- Vue应用时通过Vue函数创建一个新的Vue实例开始的。
即:var vm = new({}); - 当一个Vue实例被创建时,它将data对象中的所有的属性加入到Vue的响应系统中。当这些属性的值发生改变时,视图将会进行响应更新。使用watch方法可以观察到新值与旧值。
<div id="app">
{{a}}
</div>
<script type="text/javascript">
var data = { a : 1 };
var vm = new Vue({
el : "#app",
data : data //属性 : 变量
});
//以下方法可以更改a的属性值
vm.a = "hello";
data.a = vm.a;
//亦可使用$data来与用户定义的data区分
vm.$data.a = "test...."
//watch方法,可以观察一个值的变化
vm.$watch('a', function(newVal, oldVal){
console.log(newVal, oldVal);
})
</script>
- vue中若要使用变量,需要提前对该变量进行声明才可以使用
<div id="app1">
{{b}}
</div>
<script type="text/javascript">
var vm = new Vue({
el : "#app1",
});
//若注释掉这一句,上边的{{b}}并没有显示,表明若要使用该变量,需要提前进行声明才可以使用
//data.b = "ccc";
//vm.$data.b = 'bbb';
/*但如果像下边这样写,没有声明也是可以对b进行赋值修改,但控制台会报错:说b未声明。这里不要这样写*/
vm.b = "aaa";
</script>
- 若要阻止响应更新:Object.freeze()。这会阻止修改现有的属性,也意味着响应系统无法再追踪变化。
<div id="app3">
{{a}}
</div>
<script type="text/javascript">
var data = {a : 123}
var app3 = new Vue({
el : "#app3",
data : data
})
Object.freeze(app3);
//这时,app3的属性值不可以再修改,如果修改控制台报错
frz.a = '456';
</script>
4、vue的生命周期
Vue 实例在被创建时都要经过初始化。在这个过程中会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。
生命周期钩子,需要写在new Vue()时的对象内。以属性的方式进行声明。这时在vue的生命周期的各个阶段会调用对应的方法。生命周期函数不可使用箭头函数。
<div id="app">
{{msg}}
</div>
<script type="text/javascript">
var vm = new Vue({
el : "#app",
data : {
msg : "hi vue",
},
//在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。
beforeCreate:function(){
console.log('beforeCreate');
},
/* 在实例创建完成后被立即调用。
在这一步,实例已完成以下的配置:数据观测 (data observer),属性和方法的运算,watch/event 事件回调。
然而,挂载阶段还没开始,$el 属性目前不可见。 */
created :function(){
console.log('created');
},
//在挂载开始之前被调用:相关的渲染函数首次被调用
beforeMount : function(){
console.log('beforeMount');
},
//el 被新创建的 vm.$el 替换, 挂在成功
mounted : function(){
console.log('mounted');
},
//数据更新时调用
beforeUpdate : function(){
console.log('beforeUpdate');
},
//组件 DOM 已经更新, 组件更新完毕
updated : function(){
console.log('updated');
}
});
//延时3秒执行,与jq类似
setTimeout(function(){
vm.msg = "change ......";
}, 3000);
</script>
5、Vue模板语法
Vue.js 使用了基于 HTML 的模板语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据。所有 Vue.js 的模板都是合法的 HTML,所以能被遵循规范的浏览器和 HTML 解析器解析。
Vue 底层将模板编译成虚拟 DOM 渲染函数。结合响应系统,Vue 可智能计算出最少需要重新渲染多少组件,并把 DOM 操作次数减到最少。
5.1 文本插值:{{}}
v-once指令:一次性地插值,当数据改变时,插值处的内容不会更新。
<div id="app"> {{a}} </div>
<script>
var vm = new Vue({
el : "#app",
data : {
a : "hello"
}
});
//这时的修改是无效的。
vm.a = "hi";
</script>
{{}}会将所有内容解析为文本。并不会解析为HTML代码。
5.2 JavaScript表达式
<div id="app">
<!-- 算数运算 -->
<p>{{ num+1 }}</p>
<!-- 三元运算 -->
<p>{{ ok ? 'YES' : 'NO' }}—{{ !ok ? 'YES' : 'NO' }}</p>
<!-- 函数运算,分割字符串,反序排列,加入空格 -->
<p>{{msg.split('').reverse().join(' ')}}</p>
</div>
<script>
//对比jq:$("#id").attr("class","red")
var vm = new Vue({
el : "#app",
data:{
num : 10,
ok : true,
msg : 'HUATHY'
}
});
</script>
5.3 原始HTML:使用v-html指令
<body>
<div id="app">
<!-- 这里输出的是文本值 -->
<p>Using mustaches: {{ mHtml }}</p>
<!-- 这里将会被解析替换为下边声名html代码 -->
<p v-html="mHtml"></p>
</div>
</body>
<script>
var vm = new Vue({
el : "#app",
data:{
mHtml : "<font color='red' size='5'>SHOULD BE RED</font>"
}
})
</script>
5.4 Attribute属性绑定:使用指令,格式v-bind:属性=“变量值”
详见:7、vue指令 -> 7.1 v-bind指令
6、vue指令:格式 v-xxx
指令 (Directives) 是带有 v- 前缀的特殊属性(attribute)。
指令 attribute 的值:是单个的 JavaScript 表达式 (v-for 例外)。
指令的作用:当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM。
6.1 v-bind指令,格式:v-bind:属性=“变量”
6.1.1 href绑定:
<div id="app">
<a v-bind:href="href">百度</a>
</div>
<script>
var vm = new Vue({
el:"#app",
data:{
href : "https://www.baidu.com"
}
})
</script>
6.1.2 class绑定:
我们可以传给 v-bind:class 一个对象,以动态地切换 class。并可以在对象中传入更多属性来动态切换多个 class。此外,v-bind:class 指令也可以与普通的 class 属性共存。
<style>
.red{
color: #FF0000;
}
.blue{
color: #0000FF;
}
.aqua{
background-color: aqua;
}
.green{
color: #00aa00;
}
.text{
font-size: 30px;
}
.yellow{
background-color: yellow;
}
</style>
<div id="app">
<p v-bind:class="color">TEST...</p>
<div class="text" v-bind:class="{aqua:isaqua,green:isgreen}" style="width: 200px;text-align: center;"> 哈哈哈 </div>
<!-- 另外下边这些写法也是支持的,可见class属性值为yellow green -->
<div v-bind:class="['yellow','green']"> 嘻嘻嘻 </div>
<!-- 三元运算也是可以的 -->
<div v-bind:class="[isgreen ? 'aqua':'green',!isaqua ? 'aqua' : '']"> 呵呵呵 </div>
</div>
<script>
var vm = new Vue({
el: "#app",
data:{
color : "red", //这里可以看到p标签的class属性值为red
isaqua:true,
isgreen:false
}
})
//对比jq:$("#id").attr("class","red")
vm.color = "blue yellow"; //这里可以看到p标签的class属性值为blue yellow
</script>
6.1.3 style绑定:
v-bind:style 的对象语法非常像 CSS,但其实是一个 JavaScript 对象。CSS 属性名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用引号括起来) 来命名。
<div id="app">
<div :style="{color:color,fontSize:size,background : isYel ? 'yellow' : ''}">STYLE的绑定</div>
</div>
<script>
var vm = new Vue({
el: "#app",
data:{
color : "red",
size : "50px",
isYel : true
}
})
</script>
6.2 条件渲染:
6.2.1 v-if,v-else,v-else-if
- v-if 是“真正”的条件渲染,因为在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
- v-if 也是惰性的,如果初始渲染时条件为假,则什么也不做,直到条件第一次变为真时,才会开始渲染条件块。
<div id="app">
<!-- 这里逻辑判断为true才会进行渲染,否则不会进行渲染 -->
<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 : "A"
}
})
</script>
6.2.2 v-show
带有 v-show 的元素始终会被渲染并保留在 DOM 中。v-show 只是简单地切换元素的 CSS 属性 display。
<div id="app">
<div v-show="flag">{{flag}}</div>
<!-- false:相当于display:none; -->
<div v-show="!flag">{{flag}}</div>
</div>
<script>
var vm = new Vue({
el: "#app",
data:{
flag : true
}
})
</script>
对比:v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。
6.3 列表渲染:v-for
- 用 v-for 指令基于一个数组来渲染一个列表。v-for 指令需要使用 item in items 形式的特殊语法,其中 items 是源数据数组,而 item 则是被迭代的数组元素的别名。
Vue 正在更新使用 v-for 渲染的元素列表时,它默认使用“就地更新”的策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序,而是就地更新每个元素。为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key 属性。
- 意思是如果需要for循环的元素排序,则就要给定一个key属性。
<div id="app">
<ul>
<!-- 遍历数组 -->
<li v-for="item in items">
{{item.msg}}
</li> <hr />
<!-- 这样写可以获取到数组元素,与索引 -->
<li v-for="item,index in items">
{{index}}-{{item.msg}}
</li> <hr />
<!-- 如果需要元素排序则需要给定key属性 -->
<li v-for="item,index in items" v-bind:key="index">
{{index}}-{{item.msg}}
</li> <hr />
<!-- 遍历属性: key可以获取该对象的键 -->
<li v-for="val,key in obj" :key="key">
{{key}} : {{val}}
</li>
</ul>
</div>
<script>
var vm = new Vue({
el: "#app",
data:{
items:[
{msg:'msg01'},
{msg:'msg02'}
],
obj:{
title : 'TITLE',
author : 'HUATHY'
}
},
})
</script>
7.4 事件处理,绑定事件监听器,语法: v-on:xxx=""
v-on指令可以绑定html元素所有事件。事件类型由参数指定。表达式可以是一个方法的名字或一个内联语句,如果没有修饰符也可以省略。
<div id="app">
<!-- 内联语句 -->
<button v-on:click="num++" v-on:dblclick="show">数值:{{num}}</button>
<!-- 缩写 -->
<p @click="doClick(this,$event)">Click...</p>
<p><input @keyup.13="onEnter($event)"></p>
</div>
<script>
var vm = new Vue({
el: "#app",
data:{
num : 0
},
methods:{ //使用键值对方式声明。函数名:函数体
show : function(){ //双击显示
console.log(this); //这里输出vue对象
console.log(this.num);
},
doClick(obj,e){
console.log(obj); //这里输出window对象
console.log(e); //输出event
},
onEnter : function(e){
console.log(e.keyCode);
},
}
})
</script>
事件常用修饰符:.stop .prevent .capture .self .once .passive
按键修饰符:.keyCode。按键码:.enter .tab .delete (捕获“删除”和“退格”键) .esc .space .up .down .left .right。 系统修饰键: .ctrl .alt .shift .meta
鼠标按钮修饰符: .left .right .middle。
6.5指令修饰符
修饰符 (modifier) 是“.” 指明的特殊后缀,用于指出一个指令应该以特殊方式绑定。
<div id="app">
<div @click="click1">
<!-- 这里如果没有添加修饰符stop,则click1,click2都会执行 -->
<div @click.stop="click2"> click me </div>
</div>
</div>
<script>
var vm = new Vue({
el:"#app",
methods:{
click1(){
console.info("click1...")
},
click2(){
console.info("click2...");
}
}
})
</script>
6.6 表单输入绑定:v-model
- 用 v-model 指令可以在表单 、 及 元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。
- v-model 在内部为不同的输入元素使用不同的属性并抛出不同的事件:
*text 和 textarea 元素使用 value 属性和 input 事件;
*checkbox 和 radio 使用 checked 属性和 change 事件;
*select 字段将 value 作为 prop 并将 change 作为事件。
<div id="app">
<!-- 双向绑定:在上边更改,下边的值也会变动。 -->
<input v-model="msg" placeholder="在这里输入下边的值会同步变" />
<div id="eg1">MSG:{{msg}}</div>
<textarea v-model="msg2" placeholder="请输入:"></textarea>
<p style="white-space: pre-line;">{{msg2}}</p>
<div>
<label><input type="radio" value="A" v-model="picked"/>A</label>
<label><input type="radio" value="B" v-model="picked"/>B</label>
<p><span>单选选项:{{picked}}</span></p>
</div>
<div>
<label><input type="checkbox" value="A" v-model="check1"/>A</label>
<label><input type="checkbox" value="B" v-model="check1"/>B</label>
<label><input type="checkbox" value="C" v-model="check1"/>C</label>
<p><span>单选选项:{{check1}}</span></p>
</div>
<button type="button" @click="submit">提交</button>
</div>
<script>
<!-- 在初始化的时候赋值,上边的的文本框中也会赋值。选项,也会默认选中。这也体现了v-model的双向绑定 -->
var vm = new Vue({
el: "#app",
data:{
msg : '哈哈',
msg2 : '嘻嘻',
picked : 'A',
check1 : ['A','C']
},
methods:{ //使用键值对方式声明。函数名:函数体
submit(){
console.log(this.msg);
var subObj = {
msg : this.msg,
msg2 : this.msg2,
packed : this.packed,
check1 : this.chck1
}
console.log(subObj);
}
}
})
</script>
7、vue组件
7.1 组件基础
在开发时,可以将常用的功能封装为组件,以便开发。组件是可复用的vue实例,与 new Vue() 接收相同的选项。语法:
Vue.component('组件名称',{
//参数2:以对象的形式,描述组件
data:function(){ //描述组件的数据
},
template:'' //描述组件的模板
},)
组件可以重复调用,每个组件的数据封闭在组件内部,相互独立,互不影响 。创建组件时需要注意,一个组件需要具备一个根节点。在最外层加上div标签可以达到在一个组件内使用多个html标签的效果。
<div id="app">
<!-- 调用组件 ,并对title属性进行赋值-->
<button-counter title="btn1:"></button-counter>
<!-- 组件可以重复调用,每个组件的数据封闭在组件内部,相互独立,互不影响 -->
<button-counter title="btn2:"></button-counter>
</div>
<script>
//注意:组件的名称必须是已有的“标签名-xxx”,且这里组件要卸载Vue对象的前面
Vue.component('button-counter',{ //创建一个button-counter组件
props:['title'],
data:function(){
return{
num : 0
}
}, //{{title}}对属性进行调用渲染
template:'<div><h3>{{title}}</h3><button @click="num++">{{title}}clicked {{num}} 次</button></div>'
/*创建组件时需要注意,一个组件需要具备一个根节点。在最外层加上div标签可以达到在一个组件内使用多个html标签的效果。
无法渲染的错误写法示例:<h1>hi..</h1><button @click="num++">{{title}}clicked {{num}} 次</button>。
可以渲染的正确写法示例:<div><h3>{{title}}</h3><button @click="num++">{{title}}clicked {{num}} 次</button></div>。
*/
},)
var vm = new Vue({
el: "#app",
data:{
}
})
</script>
7.2 组件的事件监听 及 插槽<slot></slot>
- 通过this对象的$emit(‘事件名’,‘参数’)方法触发一个事件。在组件的父级可以通过事件绑定的方式来接收emit函数所触发的事件。
- 在模板内可以通过 <slot></slot> 标签来声明组件的插槽,通过插槽,可以插入任意的html内容及标签
<div id="app"> <!-- @clicknow="clicknow"绑定clicknow方法 -->
<button-counter title="btn1:" @clicknow="clicknow"></button-counter>
<button-counter title="btn2:">
<h1>haha</h1> <!-- 需要通过<slot></slot>标签声明的插槽来插入 -->
</button-counter>
</div>
<script>
Vue.component('button-counter',{
props:['title'],
data:function(){
return{
num : 0
}
}, //在模板内可以通过<slot></slot>标签来声明组件的插槽,通过插槽,可以插入任意的html内容及标签
template:'<div><h3>{{title}}</h3><button @click="doClick()">{{title}}clicked {{num}} 次</button><slot></slot></div>',
methods:{
doClick(){
this.num++;
//通过this对象的$emit('事件名','参数')方法触发一个事件。在组件的父级可以通过事件绑定的方式来接收emit函数所触发的事件。
this.$emit("clicknow",this.num);
}
}
},)
var vm = new Vue({
el: "#app",
data:{
},
methods:{
clicknow : function(num){ //声明clicknow方法
console.log(num);
}
}
})
</script>
7.3 组件的注册
- 组件命名规范:kebab-case(横杠分割),PascalCase(驼峰命名)
7.3.1 全局注册
通过 Vue.component 创建的组件都是全局注册的。在注册后可以用在任何新创建的 Vue 根实例 (new Vue) 的模板中。
Vue.component定义的全局组件要求每个component 命名不得重复。 字符串模板缺乏语法高亮。不支持CSS。 没有构建步骤。
7.3.2 局部注册
全局注册往往是不够理想的。 全局注册所有的组件即便不再使用,仍会包含在最终的构建结果中。这造成了用户下载的 JavaScript 的无谓增加。
组件局部注册:在Vue对象初始化,即创建Vue对象时。在Vue函数的一个对象形式的参数,即在该对象内声明一个components属性。在该components内部进行局部注册。
<div id="app">
<!-- 通过<test></test>标签调用test组件 -->
<test></test>
</div>
<script>
var vm = new Vue({
el: "#app",
data:{
},
methods:{
clicknow : function(num){ //声明clicknow方法
console.log(num);
}
},
//组件局部注册:在Vue对象初始化,即创建Vue对象时。在Vue函数的一个对象形式的参数,即在该对象内声明一个components属性。在该components内部进行局部注册
components:{
test : {
template: '<h2>hahaha</h2>'
}
}
})
</script>
局部注册的组件在其子组件中不可用。
7.4 单文件组件
定义全局组件,缺点:命名不得重复。字符串模板缺乏语法高亮。不支持CSS。 没有构建步骤。
7.4.1 vue单文件组件环境配置:安装node.js
、npm
、cnpm
、vue-cli
、webpack
https://blog.csdn.net/qq_40366738/article/details/105212244
- 安装
node.js
- 安装
cnpm
npm install -g cnpm --registry=https://registry.npm.taobao.org
- 安装
vue-cli
cnpm install -g @vue/cli
- 安装
webpack
cnpm install -g webpack
7.4.2 开始编写一个单文件组件
- 通过
vue ui
命令启动vue图形化管理界面 - 通过创建主页的创建,来创建一个新项目,选择npm作为包管理器
- 在刚刚填写的路径里可以看到创建的test文件夹。使用HBuilder打开。
目录结构:public(打包发布后用于部署到生产环境下的目录)。src(开发环境目录)包含assets,components(组件目录)app.vue作为整个项目的入口文件,完成对组件的引入工作。 - 在components下新建一个 test.vue 文件
<!-- 模板视图块-->
<template>
<div class="hello"> <!-- 声明一些元素 -->
<h2 class="red">test...{{msg}}</h2>
</div>
</template>
<!-- 脚本块 -->
<script>
//声明该组件的名称,属性,方法,数据
export default{
name:'test',
props:{
msg:{
type : String, //类型
default : 'test msg' //默认值
}
},
methods:{ //注册方法
},
data(){ //声明数据
return{
}
}
}
</script>
<!-- 风格样式块 -->
<style>
.red{ //声明样式
color: red;
}
</style>
- 在App.vue中调用该组件
<template>
<div id="app">
<test></test> <!-- 使用test组件 -->
</div>
</template>
<script>
import test from './components/test.vue' //引入test组件
export default {
name: 'App',
components: {
test //局部注册test组件
}
}
</script>
终、附
- 本文为个人学习笔记,仅对vue基础内容做简单阐述
- 详细内容见官方API文档:https://cn.vuejs.org/v2/api/
本文来自博客园,作者:Huathy,遵循 CC 4.0 BY-NC-SA 版权协议。转载请注明原文链接:https://www.cnblogs.com/huathy/p/17253890.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理