赞
踩
目录
vue是用于构建用户界面的javascript框架。
vue是一个渐进式 自底层向上增量开发的MVVM框架。
即先完成项目的基本功能,再使用各种高级的vue插件来完成复杂的功能。
渐进式,就是vue是会做 自己管理的功能 不会影响其他没有管理的范围 所以vue可以很好的和第三方插件结合。
vue的核心就是数据驱动与组件化。
M model 模型 存放数据 data
V view 视图 就是用户可以看见的界面
VM viewModel 视图模型 就是关联视图与模型之间的桥梁 用来再数据层和视图层中间进行数据传递(双向绑定)
1.npm 下载 vue依赖库 或者可以用cnpm
注意: 如果你要用cnpm 淘宝镜像 需要先安装:
npm install -g cnpm --registry=https://registry.npm.taobao.org
打开cmd,window+r
初始化:
npm init -y
下载 vue包
2.x
npm install --save vue@2
3.x
npm install --save vue@3
或npm install --save vue
注:查看下载的是哪个版本的包
1.package.json里dependencies下的vue
2.node_modules下的vue下的dist文件夹下的vue.js下的vue的注释中(vue2)
引用vue库文件
vue2
- <script src="./node_modules/vue/dist/vue.js"></script>
- // 或
- <script src="./node_modules/vue/dist/vue.min.js"></script>
vue3
<script src="./node_modules/vue/dist/vue.global.js"></script>
在vue3中使用createApp()方法来进行创建
注:
切包:package.json里dependencies下的vue中更改2或3,右键在集成终端中打开,输入cnpm install.
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Document</title>
- <!-- 1.引用vue库文件 -->
- <script src="./node_modules/vue/dist/vue.js"></script>
- </head>
- <body>
- <!-- 1.创建视图层 -->
- <div id="demo">
- <h1>{{text}}</h1>
- <h1>{{obj.name}}</h1>
- </div>
- <h1>外面{{text}}</h1>
-
- <!-- 2.创建vm层 vue实例 -->
- <script>
- new Vue({
- // 关联视图
- // el:"#demo",
-
- // 3.创建模型数据
- data:{
- text:"初一",
- age:18,
- arr:[111,222,333,444,555],
- obj:{
- name:"飘飘",
- sex:"女"
- }
- }
- }).$mount("#demo")
- </script>
- </body>
- </html>

- <body>
- <!-- 在vue3中使用createApp()方法来进行创建 -->
- <!-- 1.创建视图层 -->
- <div id="demoDiv">{{text}}</div>
- <script>
- // 创建vue实例
- Vue.createApp({
- // 创建模型数据
- // data函数返回一个对象
- data(){
- return{
- text:"hello"
- }
- }
- }).mount("#demoDiv")
- // 关联视图
- </script>
- </body>

1.对象式(2.x正常用 )
2.函数式(推荐 2.x与3.x都正常用 )
- <body>
- <div id="demo">
- <h1>{{text}}</h1>
- </div>
- <script>
- let v = new Vue({
- // data: {
- // text: "我是对象式写法里的变量"
- // }
-
- // 函数式data写法
- data() {
- return {
- text: "我是函数式变量写法里的变量"
- }
- }
- })
- v.$mount("#demo");
- </script>
- </body>

1.el 正常的属性挂载
2.mount 手动挂载(推荐)因为vue是渐进式的,不单单会使用vue的基本内容,还会使用vue的高级插件,但是这些插件需要等待vue加载完才能使用,所以必须要使用mount 延时挂载来解决
把表达式(通过计算返回结果的公式)放到页面中进行展示
- <body>
- <div id="demo">
- <h2>{{text}}</h2>
- <em>{{num+1}}</em>
- <p>{{demo.toUpperCase()}}</p>
- <h3>{{bool?"啊偶":"切"}}</h3>
- </div>
- <script>
- Vue.createApp({
- data() {
- return {
- text: "hello",
- num:1234,
- demo: "qqwertyuiop",
- bool: false
- }
- }
- }).mount("#demo")
- </script>
- </body>

html的属性是用来扩展html标签的功能,它写在html的开标签中,属性="属性值"
指令是在vue中使用v-前缀的html特殊属性,用来在vue中扩展标签的功能
语法: 写在开标签中,v-指令=“指令值”
在表单元素中进行数据的双向绑定
可以用于不同的表单元素
eg: input文本类型,绑定当前元素的value属性,并自动监听input事件。
复选框,自动监听change事件,并设置true或false。
下拉列表,自动监听change事件,并得到对应value值。
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Document</title>
- <!-- <script src="./node_modules/vue/dist/vue.js"></script> -->
- <script src="./node_modules/vue/dist/vue.global.js"></script>
- </head>
- <body>
- <div id="demo">
- <!-- 给表单元素完成数据的双向绑定 -->
- <input type="text" v-model="inputval" />
- <h1>{{inputval}}</h1>
- <h1>{{inputval}}</h1>
-
- <!-- 给复选框绑定任何数据,再勾选时,就会修改成布尔值 -->
- <input type="checkbox" v-model="hhh">
- <h1>{{hhh}}</h1>
- <!-- 飘飘 勾选为true,反之false -->
- </div>
- <script>
- Vue.createApp({
- data(){
- return{
- inputval:"",
- hhh:"飘飘"
- }
- }
- }).mount("#demo")
- </script>
- </body>
- </html>

视图变模型变:Dom监听(DOM Listener)即view页面改变 ---- dom监听-----通知模型改变
模型变视图变:数据绑定 即data数据改变 ---- 数据绑定触发-----页面视图改变
在vue中双向绑定是数据劫持/数据代理配合发布者订阅者模式完成的。
数据劫持/数据代理:
在Vue2中,vue的data在初始化时,便通过Object.defineProperty()来监听,当视图或者模型改变,会通知另外一方进行改变。
在Vue3中使用Proxy 来完成
发布者订阅者模式
一对多 的关系
使用css方式控制元素的显示和隐藏,true为显示,false为隐藏
- <body>
- <div id="demo">
- <h1 v-show="bool">登录</h1>
- <h1 v-show="boolone">登录成功</h1>
- <hr>
- <input type="checkbox" v-model="booltwo">{{booltwo?"显示":"隐藏"}}
- <h1 v-show="booltwo">哈哈</h1>
- </div>
- <script>
- Vue.createApp({
- data() {
- return {
- bool: false,
- boolone: true,
- booltwo: true
- }
- }
- }).mount("#demo")
- </script>
- </body>

在vue中进行dom事件绑定
语法:
1.传统写法 v-on:事件名不加on 例如:onclick----> v-on:click="函数"
2.简写 @事件名不加on 例如: onclick----> @click="函数"
事件处理
1.调用函数方式
2.内联事件方式 eg: @click="v.edit=!v.edit"
另外,函数写在与data同级的methods里,在函数中使用data数据需要this.变量名。
- <body>
- <div id="demo">
- <button v-on:click="fun()">点击</button>
- </div>
- <script>
- Vue.createApp({
- data() {
- return {
- text: "哈哈"
- }
- },
- // 函数写在与data同级的methods里
- // 在函数中使用data数据需要this.变量名
- methods: {
- fun() {
- console.log("qwdfg", this.text)
- }
- }
- }).mount("#demo")
- </script>
- </body>

输入框中改变原始值,h1中值随之改变,点击h1,输入框消失,再次点击输入框出现,里面是原始值
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Document</title>
- <script src="./node_modules/vue/dist/vue.global.js"></script>
- </head>
- <body>
- <!-- 输入框中改变原始值,h1中值随之改变,点击h1,输入框消失,再次点击输入框出现,里面是原始值 -->
- <div id="demo">
- <h1 @click="fun()">{{text}}</h1>
- <input type="text" v-model="text" v-show="bool">
- </div>
- <script>
- Vue.createApp({
- data(){
- return{
- text:"hahaha",
- bool:true
- }
- },
- methods:{
- fun(){
- this.text="hahaha";
- this.bool=!this.bool;
- }
- }
- }).mount("#demo")
- </script>
- </body>
- </html>

遍历展示data数据
语法: v-for="(遍历的值 遍历的下标) in 要遍历的数据"
- <body>
- <div id="demo">
- <ul>
- <li v-for="(v,i) in arr">{{v}}</li>
- </ul>
- <hr>
- <table border="1">
- <tr v-for="(v,i) in arrobj">
- <td>{{v.name}}</td>
- <td>{{v.age}}</td>
- </tr>
- </table>
- </div>
- <script>
- Vue.createApp({
- data() {
- return {
- arr: ["ab", "cd", "ef", "gh"],
- arrobj:[
- {name:"xiaoming1",age:11},
- {name:"xiaoming2",age:12},
- {name:"xiaoming3",age:13},
- {name:"xiaoming4",age:14}
- ]
- }
- }
- }).mount("#demo")
- </script>
- </body>

给html属性插入变量
语法: 传统写法:v-bind:属性="属性值"
简写::属性="属性值"
- <!DOCTYPE html>
- <html lang="en">
-
- <head>
- <meta charset="UTF-8">
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Document</title>
- <script src="./node_modules/vue/dist/vue.global.js"></script>
- </head>
-
- <body>
- <div id="demo">
- <!-- 传统写法 -->
- <a v-bind:href="ahref">{{text}}</a><hr>
- <!-- 简写 -->
- <a :href="ahref">{{text}}</a>
- </div>
- <script>
- Vue.createApp({
- data() {
- return {
- text: "点击去百度",
- ahref: "http://www.baidu.com"
- }
- }
- }).mount("#demo")
- </script>
- </body>
-
- </html>

点击变色,价格计算
- <!DOCTYPE html>
- <html lang="en">
-
- <head>
- <meta charset="UTF-8">
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Document</title>
- <script src="./node_modules/vue/dist/vue.global.js"></script>
- <style>
- .cs{background-color: red;}
- </style>
- </head>
-
- <body>
- <!-- 展示数据--点击变色-- -->
- <div id="demo">
- <h1>计算价格</h1>
- <table border="1">
- <tr v-for="(v,i) in arr" @click="fun(i)" :class="v.style?'cs':''">
- <td>{{v.title}}--{{v.price}}</td>
- </tr>
- </table>
- <p>总价格:{{num}}</p>
- </div>
- <script>
- Vue.createApp({
- data() {
- return {
- num:0,
- arr:[
- {title:"苹果",price:3,style:false},
- {title:"西瓜",price:4,style:false},
- {title:"葡萄",price:5,style:false},
- {title:"梨",price:2,style:false}
- ]
- }
- },
- methods:{
- fun(i){
- console.log(i);
- this.arr[i].style=!this.arr[i].style;
- // 判断当前style是否为true,为true做加法,false做减法
- if(this.arr[i].style){
- this.num+=this.arr[i].price;
- }else{
- this.num-=this.arr[i].price;
- }
- }
- }
- }).mount("#demo")
- </script>
- </body>
-
- </html>

对页面的dom元素进行添加和移除,true为添加,false为移除。
v-else和v-else-if都必须紧跟在v-if的后面使用(v-else-if可以跟在v-else-if后面)。
页面效果和v-show基本一致,但底层操作不一样。
1.代码不同
2.v-show是通过css的方式进行显示和隐藏的,v-if是对dom进行添加和移除
3.v-show在初始化时更消耗性能,v-if则好点,v-show在频繁切换时性能更好,v-if性能浪费更高
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Document</title>
- <script src="./node_modules/vue/dist/vue.global.js"></script>
- </head>
- <body>
- <div id="demo">
- <input type="checkbox" v-model="ck">
- <h1 v-show="ck">v-show效果</h1>
- <h1 v-if="ck">v-if效果</h1>
- </div>
- <script>
- Vue.createApp({
- data(){
- return{
- ck:true
- }
- }
- }).mount("#demo")
- </script>
- </body>
- </html>

- <body>
- <div id="demo">
- <input type="checkbox" v-model="ck">
- <!-- <h1 v-show="ck">v-show效果</h1> -->
- <h1 v-if="ck">v-if效果</h1>
- <h1 v-else>v-else效果</h1>
- </div>
- <script>
- Vue.createApp({
- data(){
- return{
- ck:true
- }
- },
- methods:{}
- }).mount("#demo")
- </script>
- </body>

- <body>
- <div id="demo">
- <select v-model="selectval">
- <!-- <option value="发给后台的">给用户看的展示在页面上</option> -->
- <option value="苹果">苹果</option>
- <option value="西瓜">西瓜</option>
- <option value="桃子">桃子</option>
- <option value="栗子">栗子</option>
- </select>
- <h1 v-if="selectval=='苹果'">苹果</h1>
- <h1 v-else-if="selectval=='西瓜'">西瓜</h1>
- <h1 v-else-if="selectval=='桃子'">桃子</h1>
- <h1 v-else-if="selectval=='栗子'">栗子</h1>
- <h1 v-else>什么都没有选</h1>
- </div>
- <script>
- Vue.createApp({
- data() {
- return {
- selectval: ""
- }
- }
- }).mount("#demo")
- </script>
- </body>

把字符串标签进行页面渲染
- <body>
- <div id="demo">
- <div v-html="text" ></div>
- </div>
- <script>
- Vue.createApp({
- data() {
- return {
- text: "<h2>qwertyuiop</h2>"
- }
- },
- methods: {}
- }).mount("#demo")
- </script>
- </body>
向页面插入变量 作用和{{}}一样
- <body>
- <div id="demo">
- <h1>{{text}}</h1>
- <h1 v-text="text"></h1>
- </div>
- <script>
- Vue.createApp({
- data(){
- return {
- text:"我是初始值"
- }
- }
- }).mount("#demo")
- </script>
- </body>
当用户网络较慢,或是被较卡时,可能会出现vue的库文件还没有加载完,但是页面渲染完成。
解决方案1:
就是全部使用v-text替代{{}} 不好用
解决方案2:
使用v-cloak指令(该指令就是防止页面加载时出现vue变量名没有渲染而产生的 )配合css来完成
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Document</title>
- <script src="./node_modules/vue/dist/vue.global.js"></script>
- <style>
- [v-cloak]{
- display: none;
- }
- </style>
- </head>
- <body>
- <div id="demo" v-cloak>
- <h1>{{text}}</h1>
- </div>
- <script>
- Vue.createApp({
- data(){
- return {
- text:"我是初始值"
- }
- }
- }).mount("#demo")
- </script>
- </body>
- </html>

一次性插值
- <body>
- <div id="demo">
- <input type="text" v-model="text">
- <h1>{{text}}</h1>
- <h1>{{text}}</h1>
- <h1 v-once>{{text}}</h1>
- <h1>{{text}}</h1>
- <h1>{{text}}</h1>
- </div>
- <script>
- Vue.createApp({
- data() {
- return {
- text: "初始值"
- }
- }
- }).mount("#demo")
- </script>
- </body>

如图
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Document</title>
- <script src="./node_modules/vue/dist/vue.global.js"></script>
- <style>
- li{list-style-type:none;}
- .aaa{background-color: red;}
- .del{cursor: pointer;}
- </style>
- </head>
- <body>
- <div id="demo">
- <h1>任务列表</h1>
- <p>任务总数:{{arr.length}};还有:{{sheng()}}未完成; <span class="del" v-on:click="del">【完成】</span></p>
- <ul v-if="arr.length!=0">
- <li v-for="(v,i) in arr">
- <!-- 选中后变色 -->
- <input type="checkbox" v-model="v.style">
-
- <!-- <input type="text" v-model="v.title" v-if="v.edit" @blur="v.edit=!v.edit">
- <span v-bind:class="v.style?'aaa':''" v-else @click="v.edit=!v.edit">{{v.title}}---{{v.style}}</span> -->
- <!-- 使用edit(i)函数 @blur 元素失去焦点触发-->
- <input type="text" v-model="v.title" v-if="v.edit" @blur="editOne(i)">
- <span v-bind:class="v.style?'aaa':''" v-else @click="edit(i)">{{v.title}}</span>
- </li>
- </ul>
- <h3 v-else>暂无任务</h3>
- <input type="text" v-model.trim="inputval"><button @click="add()" :disabled="bool">添加</button>
- </div>
- <script>
- Vue.createApp({
- data(){
- return{
- inputval:"",
- arr:[
- {title:"AAAAA",style:false,edit:false},
- {title:"BBBBB",style:false,edit:false},
- {title:"CCCCC",style:false,edit:false},
- {title:"DDDDD",style:false,edit:false}
- ],
- bool:true
- }
- },
- methods:{
- add(){
- // console.log(this.inputval);
- //拿到输入框中添加的值,添加至arr数组末尾,添加完成后,输入框中为空
- this.arr.push({title:this.inputval,style:false,edit:false});
- this.inputval="";
- },
- sheng(){
- let k=0;
- // forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数。该方法是对数组的每个元素执行一次给定的函数;他的返回值是 undefined;注意: forEach() 对于空数组是不会执行回调函数的。
- this.arr.forEach(v => {
- // 判断遍历出的v.style是否恒等于false,是则k++
- if(v.style==false){
- k++;
- }
- });
- return k
- },
- del(){
- // 1.先创建一个空变量用于临时保存数据
- let newarr=[];
- // 2.把原数据赋值给这个临时变量
- newarr=this.arr;
- // 3.把原始数据清空
- this.arr=[];
- // 4.循环这个临时数据,判断每个值里的style是否等于false,等于false,则把它放在原始数据中
- for(var i=0;i<newarr.length;i++){
- if(newarr[i].style==false){
- this.arr.push(newarr[i]);
- }
- }
- },
- edit(i){
- // 避免多个输入框出现
- this.arr.forEach((item,index)=>{
- item.edit=false
- });
- this.arr[i].edit=!this.arr[i].edit;
- },
- editOne(i){
- // 在输入框失去焦点后,该条数据恢复原始状态(输入框消失)
- this.arr[i].edit=false;
- }
- },
- computed:{},
- watch:{
- // 当输入框中值的长度为0,不可添加
- inputval(newval,oldval){
- if(this.inputval.length==0){
- this.bool=true;
- }else{
- this.bool=false;
- }
- }
- }
- }).mount("#demo")
- </script>
- </body>
- </html>

谁触发这个事件,事件对象就指向谁,事件对象中包含触发这个事件元素相关信息
- <!DOCTYPE html>
- <html lang="en">
-
- <head>
- <meta charset="UTF-8">
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Document</title>
- <script src="./node_modules/vue/dist/vue.global.js"></script>
- </head>
-
- <body>
- <div id="demo">
- <input type="text" @keydown="fun($event)">
- </div>
- <script>
- Vue.createApp({
- data() {
- return {
- }
- },
- methods:{
- fun(e){
- if(e.keyCode==13){
- console.log("按下了回车");
- }
- }
- }
- }).mount("#demo")
- </script>
- </body>
-
- </html>

通过vue提供的修饰符可以处理dom时间的一些细节性的内容(对事件的细节进行约束)
v-on:事件.修饰符="函数()"
.up .down .left .right .ctrl .enter .delete .space .esc .....
优化对于键盘事件的相关处理
- <!DOCTYPE html>
- <html lang="en">
-
- <head>
- <meta charset="UTF-8">
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Document</title>
- <script src="./node_modules/vue/dist/vue.global.js"></script>
- </head>
-
- <body>
- <div id="demo">
- <input type="text" @keydown.space="fun()">
- </div>
- <script>
- Vue.createApp({
- data() {
- return {}
- },
- methods: {
- fun(e) {
- console.log("aaaaaa");
- }
- }
- }).mount("#demo")
- </script>
- </body>
-
- </html>

.stop 阻止事件冒泡
.prevent 阻止事件默认行为
.captrue 设置捕获
.self 只触发自己范围的事件 不包含子元素
.once 只触发当前事件一次
- <!DOCTYPE html>
- <html lang="en">
-
- <head>
- <meta charset="UTF-8">
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Document</title>
- <script src="./node_modules/vue/dist/vue.global.js"></script>
- <style>
- .fu{width: 300px;height: 300px;background-color: yellowgreen;}
- .zi{width: 100px;height: 100px;background-color: gray;}
- </style>
- </head>
-
- <body>
- <div id="demo">
- <div class="fu" @click.once="fu()">
- <div class="zi" @click.stop="zi()"></div>
- </div>
- </div>
- <script>
- Vue.createApp({
- data() {
- return {}
- },
- methods: {
- fu() {
- console.log("fufufu");
- },
- zi(){
- console.log("zizizi");
- }
- }
- }).mount("#demo")
- </script>
- </body>
-
- </html>

使用v-model后,用户每次修改输入内容,都会将数据同时绑定,为了避免这种情况的发生,使用lazy修饰符来进行限定。只有当用户的input中失去焦点或者用户点击回车按钮时,才会将的数据进行修改。
- <body>
- <div id="demo">
- <input type="text" v-model.lazy="text">
- <h1>{{text}}</h1>
- </div>
- <script>
- Vue.createApp({
- data() {
- return {
- text:"默认值"
- }
- },
- methods: {
- }
- }).mount("#demo")
- </script>
- </body>

当用户在input中输入数字时,浏览器会默认将输入的数字转化为string类型,使用number修饰符来将输入的数字转为number类型
- <body>
- <div id="demo">
- <input type="text" v-model.number="num">
- <button @click="fun()">点击查看数据类型</button>
- </div>
- <script>
- Vue.createApp({
- data() {
- return {
- num: 66
- }
- },
- methods: {
- fun(){
- console.log(typeof(this.num));
- }
- }
- }).mount("#demo")
- </script>
- </body>

使用trim修饰符来去掉字符串首部或者尾部的所有空格,常用于登陆注册。
<input type="text" v-model.number.trim="num">
修饰符间没有冲突,可连拼,如上。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。