vue就是个很多js工具代码的js文件,因此可以直接引入到html文件中
我引入的是3.2.10版本的
<script src="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/vue/3.2.10/vue.global.js"></script>
.使用官方脚手架的方式来构建项目环境(面试)
1. cnpm install @vue/cli -g //下载官方脚手架
2. vue create app1 //项目名称
3. 接下来让你选择一些默认要生成的工具,不管直接回车
4. 进入项目文件夹: cd app1 //进入项目文件夹,也可以直接在项目文件夹中打开终端
5. 启动:
npm run serve //生成的打包文件在内存中不会写入磁盘用于开发阶段
或者
npm run build //生成的打包文件在dist中 用于项目上线
基础指令:
1.普通插值表达式插入数据: 在标签尖括号中使用{{}}插入js表达式:变量,函数调用,三目运算等等;
2.文本指令:(面试)
v-html ==>相当于innerHTML
v-text==>相当于innerText
v-pre==>插件表达式就被识别为文本,而不是js表达式
v-cloak==>加上这个属性的标签相当于在构建虚拟节点的时候就会有这个属性,等data的数据生成的时候,这个标签会自动去掉这个属性,可以利用这个特性来在css中把这个元素在加载初期写样式(隐藏)
<h1>{{msg+"666"}}</h1>
<p v-cloak>{{fn()}}</p>
<p v-cloak>{{ count==10?"helloworld":"worldhello" }}</p>
<div v-html="p_html"></div>
<div v-text="p_text"></div>
<p v-pre>{{p_pre}}</p>
3.如何解决vue第一次加载的时候,页面上使用的数据会闪烁?(面试)
3.1.界面加载的时候会把节点直接挂载到文档树中,导致{{msg+"666"}}这个字符串会显示一下
3.2.vue对象生成data数据时候 回去刷新界面 把{{msg+"666"}}字符串替换成结果字符串
3.3.导致界面第一次加载的时候会闪屏
3.4.解决方案:使用v-html,v-text指令操作,或者css中加[v-cloak] {display:none};
4.给元素绑定属性
标准写法:v-bind:src=“变量”
简写形式::src="[10,20,30]"
<a v-bind:href="link">baidu</a>
<a :href="link">baidu</a>
<img v-bind:src="myimg">
<img :src="myimg">
案例:
<div id="app">
<h1>{{msg}}</h1>
<div>{{title}}</div>
</div>
<script>
var app=Vue.createApp({
data() {
return {
msg:"第一次学习Vue",
title:"666661"
}
}
})
app.mount("#app")
</script>
<div id="app">
{{ counter }}
</div>
<script>
const App = {
data() {
return {
counter: 0
}
}
};
Vue.createApp(App).mount('#app');
</script>
data函数必须返回一个对象,这个返回的对象就是就是数据源,它的属性可以直接在模板内部使用
插值表达式和基础指令:
<style>
#app[v-cloak]{
display: none;
}
</style>
<div id="app" v-cloak>
<h1>{{ counter+100 }}</h1>
<h2>{{msg+",vue"}}</h2>
<h3>{{title}}</h3>
<h4>{{obj.name}}</h4>
<h5>{{obj.age+"岁"}}</h5>
<h5>{{obj.age}}岁</h5>
<h1>{{arr[0].price}}---{{arr[0].title}}</h1>
<h1>{{arr[1].price}}---{{arr[1].title}}</h1>
<div>
{{content}}
</div>
<div v-html="content"></div>
<div v-text="content"></div>
<div v-pre>
{{content}}
</div>
</div>
<script>
//JSX
//插值表达式
//双大括号中写的js的表达式
// `${xxx}岁`
// let msg="hello"
//v-html==> div.innerHTML=content
//v-text/{{content}}==>div.innerText=content
//v-pre 静默,跳过vue编译
//vue运行以后会把模版内部的所有 v-cloak 属性去掉
let app=Vue.createApp({
data() {
return {
counter: 200,
msg:"hello",
title:"标题",
obj:{
name:"karen",
age:23
},
arr:[{price:23,title:"商品1"},{price:998,title:"商品2"}],
content:"<a href='#'>华清远见</a>"
}
}
})
app.mount('#app');
</script>
属性绑定:v-bind
<style>
#app[v-cloak]{
display: none;
}
img{
width: 200px;
height: 200px;
}
</style>
<div id="app" v-cloak>
<div>
{{title}}
</div>
<div v-html="title"></div>
<div v-text="title"></div>
<!-- 属性 -->
<input type="text" value="1111"> <br>
<img src="https://img0.baidu.com/it/u=3425868493,3104015061&fm=253&app=120&size=w931&n=0&f=JPEG&fmt=auto?sec=1686070800&t=6cd3cc882bb5b20d7628c33f524efcda"><br>
<a href="https://www.baidu.com/index.html">百度</a><br>
<!--
//{}==> new Object()
v-bind:属性名="变量名"
语法糖==> :属性名="变量名"
-->
<input type="text" v-bind:value="tel"><br>
<img v-bind:src="img1" v-bind:alt="alt1"><br>
<a :href="hqyjurl">华清远见</a><br>
<div :id="box">123</div>
</div>
<script>
let app=Vue.createApp({
data() {
return {
title:'标题',
tel:"66666",
img1:"https://img0.bai454du.com/it/u=4162443464,2854908495&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1686070800&t=6c6ee924c30e160c5951141d20492b78",
alt1:"图片加载失败了,可能网络异常了",
hqyjurl:"http://www.hqyj.cn",
box:"box1"
}
}
})
app.mount('#app');
</script>
事件:
1.方法的写法:
在methods中写方法,供事件或别的方法内部调用
2.事件绑定:
//v-on: 和 @ 都是绑定事件的指令
//指令后面跟事件类型,值就是methds中的方法,可以加小括号也可以不加
<button v-on:click="fn1()">点击事件1</button>
<button @click="fn2">点击事件2</button>
3.事件修饰符(面试)
-
.stop 阻止冒泡,阻止从当前元素经过的所有冒泡行为
-
.prevent 阻止默认事件
-
.capture 添加事件侦听器时让事件在捕获阶段触发
-
.self 其他元素的事件触发时 事件链经过它,无论是捕获还是冒泡阶段都不会触发它的事件,只有它自己是精准对象才会触发事件, 虽然它自己不会被别人影响,但是它自己的事件触发的时候还是会生成事件链经过其他元素,并不阻止继续冒泡到其他元素
-
.once 事件只触发一次,触发完之后,事件就解绑
-
多修饰符一起使用:连点
<div class="box" @click="divBoxHandler"> <input type="button" @click.stop="btnHandler" value="戳他"> </div> <a v-on:click.prevent.once="doThat">阻止点击跳转,但是只会阻止第一次</a>
-
<style> .box1 { border: 1px solid transparent; width: 400px; height: 400px; background-color: antiquewhite; } .box2 { margin: 10px; width: 300px; height: 300px; background-color: chartreuse; } .box3 { margin: 10px; width: 200px; height: 200px; background-color: chocolate; } </style> <div class="app"> <div class="box1" @click="fn1"> box1 <div class="box2" @click.self="fn2"> box2 <div class="box3" @click.once="fn3"> box3 <a href="http://www.baidu.com" @click.prevent="go">baidu</a> </div> </div> </div> </div> <script> // //.stop 阻止冒泡 //.prevent阻止默认事件 //.capture 捕获阶段触发 //.self 只自己是目标元素才触发 let App = { data() { return { } }, methods: { fn1() { console.log("执行box1被点击的业务") }, fn2() { console.log("执行box2被点击的业务") }, fn3() { console.log("执行box3被点击的业务") }, go(){ console.log("go go go") } }, } Vue.createApp(App).mount(".app") </script>
4.事件中的this和数据操作(面试)
-
<body> <div id="app"> <button v-on:click="fn1">btn1</button> <button v-on:click="fn2(100)">btn2</button> <button @click="fn3">btn3</button> <img @click="fn4" :src="img1"> <h1>{{title}}</h1> <button @click="changetitle">changetitle</button> </div> <script> //数据驱动页面 组件化开发 //放在data中的数据 才具备响应式数据 let app = Vue.createApp({ data() { return { test: 100, title:"标题", img1: "https://gimg3.baidu.com/search/src=http%3A%2F%2Fpics2.baidu.com%2Ffeed%2F9213b07eca806538842c45c85eb3e248af3482a6.jpeg%40f_auto%3Ftoken%3De7f4dba5d7385f12db95d346cfcd1cf8&refer=http%3A%2F%2Fwww.baidu.com&app=2021&size=f360,240&n=0&g=0n&q=75&fmt=auto?sec=1686070800&t=b49c7627361603bd9a98c04b8dc5401d" } }, methods: { changetitle(){ this.title="新的标题" }, fn1() { console.log("fn1") }, fn2(arg) { console.log("fn2", arg) }, fn3(arg) { console.log(arg) }, fn4() { console.log(this.img1, this.test) this.img1 = "https://gimg3.baidu.com/search/src=http%3A%2F%2Fpics4.baidu.com%2Ffeed%2Faec379310a55b319595e741900d6c12acefc1746.jpeg%40f_auto%3Ftoken%3Dc5c0cdd2685110cb3a99fb902527b1c6&refer=http%3A%2F%2Fwww.baidu.com&app=2021&size=f360,240&n=0&g=0n&q=75&fmt=auto?sec=1686070800&t=f474de0012d4cb28294bd5183b5ec7c3" } }, }) // console.log(app) app.mount("#app") </script>
样式绑定:
-
用class类名:
-
eg:
-
<style> .box1{ width: 200px; height: 400px; background-color: brown; } .box2{ width: 200px; height: 400px; background-color: brown; display: none; } </style> <div id="app"> <button @click="box_clicked">下拉</button> <div :class="a"> {{msg}} </div> </div> <script> let App={ data(){ return { msg:"hello", a:"box1", flag:true } }, methods: { box_clicked() { this.flag=!this.flag if(this.flag){this.a="box1"} else{this.a="box2"} } }, } Vue.createApp(App).mount("#app") </script>
还有另一种写法:
-
<style> .box1 { width: 200px; height: 300px; background-color: aquamarine; } .box2 { display: none; } </style> <div id="app"> <button @click="box_clicked">下拉</button> <div :class="a">{{msg}}</div> </div> <script> let app = { data() { return { msg: "hello", a: { box1: true, box2: false }, flag: true, }; }, methods: { box_clicked() { this.flag = !this.flag; if (this.flag) { this.a.box2 = false; } else { this.a.box2 = true; } }, }, }; Vue.createApp(app).mount("#app"); </script>
样式绑定
-
用style:
-
<style> .box{ width: 400px; height: 500px; background-color: brown; } </style> <div id="app"> <button @click="fn({box1:'block',box2:'none'})">one</button> <button @click="fn({box1:'none',box2:'block'})">two</button> <div class="box" :style="{display:box1,color:'blue'}"> one </div> <div class="box" :style="{display:box2,color:'red'}"> two </div> <div :style="obj"> three </div> <div :style="[{color:'red',backgroundColor:y},obj2]">four</div> </div> <script> // var obj={name:"karen",lastname:name+"xxx",fn(){this.name}} let App = { data() { return { box1:"block", box2:"none", w:"200px", obj:{color:"skyblue",backgroundColor:"yellow"}, obj2:{fontSize:"30px"}, y:"yellow", } }, methods: { fn(arg) { console.log(arg) this.box1=arg.box1 this.box2=arg.box2 } }, } Vue.createApp(App).mount("#app") </script>
双向数据绑定:
-
响应式数据
变量的值变化 模板也会刷新
vue的数据源变化 模板会跟着变化==>vue底层实现出来的后面来讲
如果用户交互了 改变了DOM节点的值(UI改变) 绑定的数据源也要发生变化(1.自己监听用户交互实现 2.语法糖:v-model)
<div id="app"> <p>{{tel}}</p> <input type="text" v-model.lazy.number.trim.sync="tel"> <button @click="fn1">get</button> <button @click="fn2">set</button> </div> <script> let app = { data() { return { tel:"15885208294" } }, methods: { fn1(){ console.log(this.tel); }, fn2(){ this.tel="新的电话号码:"+this.tel; } }, }; Vue.createApp(app).mount("#app"); </script>
条件渲染:
-
v-show和v-if的原理是什么 哪个更好?
-
v-show是设置了css样式display:none隐藏
v-if是直接把元素删除,显示的时候又创建出来
高频切换的业务: 使用v-show 具有更高渲染消耗低频切换的业务:使用v-if
<div id="app"> <button @click="fn">btn</button> <div v-if="a"> 内容1 </div> <!-- <div v-else-if="b"> 内容2 </div> <div v-else> 内容3 </div> <div>666</div> --> <button @click="fn2">btn2</button> <div v-show="a2"> 内容1 </div> </div> <script> // if(){} // else if(){} // else if(){} // else{} // if(){} // console.log(11) // else{} let App = { data() { return { a:true, b:true, a2:true, b2:true } }, methods: { fn() { this.a=!this.a }, fn2() { this.a2=!this.a2 } }, } Vue.createApp(App).mount("#app") </script>
-
<div id="app"> <div v-for="el in arr"> <h1>{{el}}</h1> <p>你好</p> </div> <div v-for="el in arr2"> <h1>{{el}}</h1> <p>世界</p> </div> <div v-for="el in arr3"> <div class="box1" v-if="el.age>18"> <h1>{{title}}</h1> <h2>{{text}}</h2> </div> <div class="box2" v-else> <h1>{{title}}</h1> <h2>{{text}}</h2> </div> </div> </div> <script> let app = { data() { return { arr:["html","css","js","ts","node","vue"], arr2:[],//克隆0次,数组长度0 arr3:[{ title:"biaoti1", text:"bailu1", city:"chengdu", age:16 }, { title:"biaoti2", text:"bailu2", city:"chengdu", age:19 }, { title:"biaoti3", text:"bailu3", city:"chengdu", age:22 }, ] }; }, methods: { }, }; Vue.createApp(app).mount("#app"); </script>
循环渲染:
-
//v-for这个指令所在的元素的整个模板会被克隆 数组的元素个数有多少就克隆几次
//vue2.x v-for的优先级更高
//vue3x v-if的优先级更高
//官方无论是在2.x 3.x版本都不建议把v-if和v-for写在同一个元素上:
// vue "冰"元素 template
// DOM:
//document.createDocumentFragment()
//document.createElement("div")
//React: <> </>
//wx: <block></block>
-
<style> .box1 { width: 600px; height: 200px; background-color: rosybrown; margin: 10px; } .box2 { width: 600px; height: 200px; background-color: red; margin: 10px; } </style> <div id="app"> <!-- <div>{{arr[0]}}</div> <div>{{arr[1]}}</div> <div>{{arr[2]}}</div> <div>{{arr[3]}}</div> <div>{{arr[4]}}</div> <div>{{arr[5]}}</div> --> <div v-for="el in arr"> <h1>{{el}}</h1> <p>测试</p> </div> <div v-for="el2 in arr2">666</div> <div v-for="el in arr3"> <h1>{{el.title}}</h1> <p>{{el.text}}</p> <a :href="el.url">{{el.text}}</a> <div> <span v-for="el2 in el.arr">{{el2}}</span> </div> </div> <hr> <div v-for="el in arr4"> <div class="box1" v-if="el.age>=18"> <h1>{{el.name}}</h1> <p>{{el.age}}岁</p> </div> <div class="box2" v-else> <h1>{{el.name}}</h1> <p>{{el.age}}岁</p> <button>点击验证-</button> </div> </div> <hr> <div v-for="el in arr5"> <h1>{{el.text}}</h1> <template v-if="el.v"> <span v-for="el in el.arr">{{el}}</span> </template> </div> </div> <script> let App = { data() { return { arr: ["html", "css", "js", "ts", "node", "vue"], arr2: [], arr3: [{ title: "标题1", text: "内容1", url: "http://www.baidu.com", arr: ["自营", "热卖"] }, { title: "标题2", text: "内容2", url: "http://www.hqyj.com", arr: ["热卖"] }, { title: "标题3", text: "内容3", url: "http://www.sina.cn", arr: [] }], arr4: [{ name: "karen", age: 23 }, { name: "jack", age: 17 }, { name: "marry", age: 40 }, { name: "zhangsan", age: 16 }], arr5: [{ text: "内容1", v: false, arr: ["label1", "label2"] }, { text: "内容2", v: false, arr: ["label2"] }, { text: "内容3", v: true, arr: ["label1", "label2", "label3"] }] } }, methods: { }, } Vue.createApp(App).mount("#app") </script>