https://www.bilibili.com/video/BV1Rs4y127j8/?spm_id_from=333.337.search-card.all.click
创建Vue项目
npm init vue@latest
cnpm 是npm是镜像
cnpm install
npm run dev
文件夹介绍
.vscode —VSCode工具的配置文件(和vue无关,和开发工具有关 例如Hbulider)
node_modules —Vue项目的运行依赖文件
public —资源文件夹(浏览器图标)
src —源码文件夹
.gitignore —git忽略文件(团队开发)
.index.html —入口HTML文件
package.json —信息描述文件 scripts 项目如何运行 dependencies 项目依赖 devDependencies 版本详细依赖 vitejs的依赖 vite是脚手架
README.md —注释文件
vite.config.js —Vue配置文件 (跨域、其它的打包配置)
模板语法 (文本插值)
Vue使用一种基于HTML的模板语法,使我们能够声明式地将其组件实例的数据绑定到呈现的DOM上,所有的Vue模板都是语法层面合法的HTML,可以被符合规范的浏览器和HTML解析器解析
删除components里面的东西
在App.vue
<template>
<h3>模板语法</h3>
<p>{{msg}}</p>
<p>{{hello}}</p>
</template>
<script>
//函数插值
export default {
data() {
return {
msg : 'Welcome to Your Vue.js App',
hello : 'Hello Vue.js'
}
}
}
</script>
使用JavaScript表达式
每个绑定仅支持单一表达式,也就是一段能够被求值的JavaScript代码,一个简单的判断方法是是否可以合法地写在return后面
<template>
<h3>模板语法</h3>
<p>{{ number + 1}}</p>
<p>{{ ok ? "YES" : "NO" }}</p>
<p>{{ message.split('').reverse().join('') }}</p>
<!-- 这是一个语句,而非表达式 -->
<!-- <p>{{ var a = 2 }}</p> -->
<!-- 条件换行控制也不支持,请使用三元表达式 -->
<!-- {{if(ok){return message}}} -->
{{}}
<p>{{msg}}</p>
<p>{{hello}}</p>
<!-- v-html将其转换为html语句 -->
<p v-html = "rawHtml"></p>
</template>
<script>
//函数插值
export default {
data() {
return {
number:10,
ok:true,
message:"大家好",
msg : 'Welcome to Your Vue.js App',
hello : 'Hello Vue.js',
rawHtml:"<a href='https://www.sougou.com'>你好</a>"
}
}
}
</script>
属性绑定
双大括号不能在HTMLattributes中使用 想要响应式地绑定一个attribute 应该使用v-bind指令
动态绑定多个值
<template>
<div :class="dynamicClass" :id = "dynamicId">测试</div>
<button :disabled="isButtonDisabled">Button</button>
<div v-bind="objectOfAttrs">测试</div>
</template>
<script>
export default{
data(){
return{
dynamicClass:"app", //css中选中的class名字
dynamicId:"appid",
isButtonDisabled:true, //是否禁用按钮ButtonDisabled
objectOfAttrs:{
dynamicClass:"appclass", //css中选中的class名字
dynamicId:"appid"
}
}
}
}
</script>
<style>
.app{
color:red;
font-size: 30px;
}
</style>
条件渲染 if
v-if
v-else
v-else-if
频繁切换用v-show
列表渲染 for
复杂数据格式json
<template>
<div>
<p v-for="item in names">{{ item }}</p>
<div v-for="item in results">
<p>{{ item.id }}</p>
<img :src="item.img" alt="">
</div>
</div>
</template>
<script>
export default {
data(){
return {
names:["1","2","3"],
results:[
{"id":1,"name":"name1","img":"img1.jpg"},
{"id":2,"name":"name2","img":"img2.jpg"},
{"id":3,"name":"name3","img":"img3.jpg"},
]
}
}
}
</script>
v-for也支持使用可选的第二个参数表示当前项的位置索引
也可以使用of作为分隔符来替代in,者更接近于js
遍历对象
<template>
<div>
<p v-for="(item,index) in names">{{ item }}-{{ index }}</p>
<div v-for="item in results">
<p>{{ item.id }}</p>
<img :src="item.img" alt="">
</div>
<p v-for="(value,key,index) of userInfo">{{ value }}-{{ key }}-{{ index }}</p>
</div>
</template>
<script>
export default {
data(){
return {
names:["11111","22222","33333"],
results:[
{"id":1,"name":"name1","img":"img1.jpg"},
{"id":2,"name":"name2","img":"img2.jpg"},
{"id":3,"name":"name3","img":"img3.jpg"},
],
userInfo:{
name:"iwen",
age:20
}
}
}
}
</script>
key
事件处理 v-on
事件参数
可以获取event对象和通过事件传递数据
<template>
<button @click = "addCount">按钮</button>
<p>{{ count }}</p>
</template>
<script>
export default {
data(){
return{
count:0
}
},
methods:{
addCount(e){
console.log(e);
// Vue中的event对象,就是原生JS中的event对象
e.target.innerHTML = this.count;
this.count++;
}
}
}
</script>
<template>
<button @click = "addCount('hello')">按钮</button>
<p>{{ count }}</p>
</template>
<script>
export default {
data(){
return{
count:0
}
},
methods:{
addCount(msg){
console.log(msg);
this.count++;
}
}
}
</script>
<template>
<p @click="getNameHandler(item)" v-for="(item,index) of names" :key="indx">{{ item }}</p>
</template>
<script>
export default {
data(){
return{
names:['<NAME1>','<NAME2>','<NAME3>'],
}
},
methods:{
getNameHandler(name){
console.log(name);
}
}
}
</script>
事件修饰符
.stop 阻止事件冒泡
.prevent 阻止默认事件
.once 时间只会被触发一次
.enter 回车按键触发
<template>
<h3>事件修饰符</h3>
<a @click.prevent = "clickHandle" href="https://www.sougou.com">url</a>
<!-- 阻止事件冒泡 -->
<div @click="clickDiv">div
<p @click.stop="clickP">p</p>
</div>
</template>
<script>
export default {
data(){
return {
}
},
methods:{
clickHandle(e){
// 阻止默认事件
// e.preventDefault();
console.log("nishi");
},
clickDiv(){
console.log("div");
},
clickP(e){
// 阻止事件冒泡
// e.stopPropagation();
console.log("p");
}
}
}
</script>
数组变化监听
1.变更方法
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
<template>
<h3>数组变化监听</h3>
<button @click="addListHandle">添加数据</button>
<ul>
<li v-for="(item,index) of names" :key="index">{{ item }}</li>
</ul>
<button @click="concatHandle">合并数组</button>
<h3>num</h3>
<p v-for="(item,index) of num" :key="index">{{ item }}</p>
<h3>nums</h3>
<p v-for="(item,index) of nums" :key="index">{{ item }}</p>
</template>
<script>
export default {
data(){
return {
names: ['<NAME1>','<NAME2>','<NAME3>'],
num:[1,2,3,4,5],
nums:[5,4,3,2,1]
}
},
methods:{
addListHandle(){
//引起ui更新
// this.names.push("ni")
//不会引起自己更新
this.names.concat(["ni"])
console.log(this.names.concat(["ni"]))
this.names = this.names.concat(["ni"])
},
concatHandle(){
this.num = this.num.concat(this.nums)
}
}
}
</script>
计算属性
将复杂逻辑提取到计算属性实现,而不会直接在模板语法
计算属性:会基于其响应式依赖被缓存
一个计算属性仅会在其响应式依赖更新时才重新计算
方法:在重新渲染发生时再次执行函数
<template>
<h3>{{ a.name }}</h3>
<p>{{ aH2() }}</p>
</template>
<script>
export default {
data(){
return{
a:{
name:"123",
content:[1,2,3]
}
}
},
//计算属性
computed:{
aH(){
return this.a.content.length > 0 ? "yes" : "no";
}
},
methods:{
aH2(){
return this.a.content.length > 0 ? "yes" : "no";
}
}
}
</script>
Class绑定
<template>
<p :class="{'active':isActive,'text':hasError}">Class样式绑定</p>
<p :class = "classObject">Class样式绑定</p>
<p :class="[arrActive,text]">Class样式绑定</p>
<p :class="[isActive ? 'active text' : '' ]">Class样式绑定</p>
<p :class="[isActive ? 'active' : '',{'text':hasError}]">Class样式绑定</p>
</template>
<script>
export default {
data(){
return{
isActive:true,
hasError:false,
classObject:{
'active':true,
'text':true,
},
arrActive:"active",
text:"text"
}
}
}
</script>
<style>
.active{
/* color:red; */
font-size: 30px;
}
.text{
color:blue;
}
</style>
数组和对象的嵌套
只能是数组嵌套对象
Style绑定
<template>
<p :style="{color:activeColor,fontSize:fontsize+'px'}">Style</p>
<p :style="styleObject">Style</p>
</template>
<script>
export default {
data(){
return{
activeColor:'red',
fontsize:30,
styleObject:{
color:'red',
fontSize:"30px"
}
}
}
}
</script>
侦听器(监听页面的数据变化)
<template>
<h3>侦听</h3>
<p>{{message}}</p>
<button @click="updateHandle">按钮</button>
</template>
<script>
export default {
data(){
return{
message:"Hello"
}
},
methods:{
updateHandle(){
this.message = "Hello World"
}
},
watch:{
//名称和data中的属性名
message(newValue,oldValue){
//事件发生变化自动执行
console.log(newValue,oldValue)
}
}
}
</script>
v-model form的输入绑定
.lazy
.number 只接收数字
.trim 去掉前后空格
<template>
<h3>表单</h3>
<input type="text" v-model.lazy="message">
<p>{{ message }}</p>
<input type="checkbox" id="checkbox" v-model="checked">
<label for="checkbox">{{ checked }}</label>
</template>
<script>
export default {
data() {
return{
message: '' ,
checked: false
}
}
}
</script>
模板引用 获取DOM
虽然Vue的声明性渲染模型抽象了大部分对DOM的直接操作,但在某些情况下,我们仍然需要直接访问底层DOM元素
我们可以使用特殊的 ref attribute
<template>
<div ref="container" class="container">{{content}}</div>
<input type="text" ref="username">
<button @click="getElementHandle">按钮</button>
</template>
<script>
/*
内容改变 {{ 模板语法 }}
属性改变 v-bind:指令
事件:v-on:click
如果没有特别的需求,不要操作DOM
*/
export default {
data(){
return{
content:"内容"
}
},
methods:{
getElementHandle(){
//此时获取的元素就是div元素
//innerHTML 原生js属性
console.log(this.$refs.container.innerHTML = "123")
console.log(this.$refs.value)
}
}
}
</script>
组件
组件最大的优势是可复用性
使用构建步骤时,将Vue组件定义在一个单独的.vue文件中
被叫做单文件组件(简称SFC)
组件注册方式
一个Vue组件在使用前需要先被“注册”,这样vue才能在渲染模板时找到其对应的实现
组件注册有两种方式:全局注册和局部注册
全局注册
import { createApp } from 'vue'
import App from './App.vue'
import Header from './pages/Header.vue'
// createApp(App).mount('#app')
const app = createApp(App)
//在这中间写组建的注册
app.component('Header',Header)
// 挂载
app.mount('#app')
组件传递数据 Props
组件与组件之间不是完全独立的,是有交集的,组件之间可以传递数据 只能从父级传递到子级,不能反着
<template>
<h3>Parent</h3>
<Child :title=message demo = "demo" />
</template>
<script>
import Child from './Child.vue'
export default {
data(){
return{
message:"msg"
}
},
components:{
Child
}
}
</script>
<template>
<h3>Child</h3>
<p>{{ title }}</p>
<p>{{ demo }}</p>
</template>
<script>
export default {
data(){
return{
}
},
props: ["title","demo"]
}
</script>
组件传递多种数据类型
数字、对象、数组等
任何类型的值都可以作为props的值被传递
组件事件
组件数据传递
父传子 props
子传父 自定义事件 this.$emit
子事件触发父亲事件,通过事件传递参数