前言

本教程参考:B站视频1 BV1Rs4y127j8 B站视频2 BV1nV411Q7RX

Vue 安装

这里介绍的 Vue3 的安装,需要 15.0 或更高版本的Node.js

使用 node -v显示版本号

在cmd界面找到需要存放Vue的文件夹,进入后使用下述命令创建:

npm init vue@latest

配置完相关信息后:

cd <Project-name>
npm install
npm run dev

即可启动Vue项目

目录结构说明:

.vscode			--- 工具的配置文件
node_modules	--- Vue项目的运行依赖文件
public			--- 资源文件夹(浏览器图标)
src				--- 源码文件夹
.gitignore		--- git忽略文件
index.html		--- HTML文件
package.json	--- 信息描述文件
README.md		--- 注释文件
vite.config.js	--- Vue配置文件

Vue选项式Api学习-Vue2风格

app.vue引用模块

src中的 components创建 test.vue,然后在 App.vuetest.vue中加入以下代码,即可引用:

<!-- src/App.vue -->
<script setup>
import test from './components/test.vue'
</script>
<template>
	<!-- 注意这里需要添加引用的文件名 -->
  	<test/>
</template>

<!-- src/components/test.vue -->
<template>
</template>
<script>
export default{
    data(){
        return{
        }
    }
}
</script>

文本插值

在标签中使用 {{ }}形式添加定义的变量,来直接展示变量的值:

<template>
  <h3>模板语法</h3>
  <p>{{ msg }}</p>
</template>
<script>
export default{
  data(){
    return{
      msg:"神奇的语法",
    }
  }
}
</script>

嵌套html代码

在要嵌套的标签中添加属性 v-html=""其中放入变量 html

<template>
  <h3>模板语法</h3>
  <p v-html="html">  </p>
</template>
<script>
export default{
  data(){
    return{
      html:"<a href='https://romcere.top'>romcere</a>"
    }
  }
}
</script>

插入属性

添加 v-bind:实现添加变量属性:

<template>
  <div v-bind:class="msg"></div>
</template>
<script>
export default{
  data(){
      return{
          msg:"active"
      }
  }
}
</script>

如果给 msg赋值 nullundefined会移除这个属性

v-bind:也可以简写为 :,即:<div :class="msg"></div>

同时,也可以使用 v-bind=""添加多个属性:

<template>
  <button v-bind="obj">button</button>
</template>
<script>
export default{
  data(){
      return{
          obj:{
            id:"ID",
            class:"CLASS"
          }
      }
  }
}
</script>

条件渲染

Vue提供两个属性 v-if=""v-else用于判断是否显示该标签:

<template>
    <div v-if="flag">你能看见我吗</div>
	<div v-else-if="">你应该能看见我</div>
    <div v-else>那你还是看见我吧</div>
</template>
<script>
export default{
    data(){
        return{
            flag:false
        }
    }
}
</script>

v-if的标签未显示,则展示 v-else的标签

v-show=""的使用:

<template>
    <div v-show="flag">你能看见我吗</div>
</template>

v-ifv-show的区别:

  1. v-if是通过添加删除来实现的
  2. v-show是通过添加css属性display:none来实现的
  3. 如果需要频繁切换则使用 v-show,如果很少切换则使用 v-if

列表渲染

使用 v-for遍历列表:

<template>
    <p v-for="item in names">{{ item }}</p>
</template>
<script>
export default{
    data(){
        return{
            names:["nums1","nums2","nums3"]
        }
    }
}
</script>

v-for也可以接收数组的索引:

<template>
    <p v-for="(item,index) in names">{{ item }}-{{ index }}</p>
</template>

如果用 v-for遍历对象,则:

<template>
    <p v-for="(value,key,index) in user">{{ value }}-{{ key }}-{{ index }}</p>
</template>

添加 key属性,来添加唯一索引,防止遍历出错:

<template>
    <p v-for="(item,index) in user" :key="item.id"></p>
</template>

key的值一般建议使用id来添加唯一索引,让每一条数据变得唯一

事件处理

使用 v-on来监听DOM事件,使用方法:v-on:click=""@click=""

<template>
	<!-- 内联式,直接使用方法 -->
    <button @click="count1++">count:{{count1}} </button>
	<!-- 方法事件处理 -->
	<button @click="addCount()">count:{{count2}} </button>
</template>
<script>
export default{
    data(){
        return{
            count1:0,
            count2:0
        }
    },
    // !!!所有的方法都放在这里
    methods:{
        addCount(){
            // 使用this调用外部变量
            this.count2++;
        }
    }
}
</script>

获取 event对象:

<template>
	<!-- 不加() -->
	<button @click="addCount($event)">test</button>
</template>
<script>
export default{
    data(){
        return{
            count:0
        }
    },
    methods:{
        // event简写成e,这里的event就是原生JS的Event对象
        addCount(e){
            e.target.innerHTML = "Add:" + this.count;
            this.count++;
        }
    }
}
</script>

传递参数:

<template>
	<button @click="addCount('hello',$event)">test</button>
</template>
<script>
export default{
    data(){
        return{
            count:0
        }
    },
    methods:{
        // 传递参数
        addCount(msg,e){
            console.log(msg)
            e.target.innerHTML = "Add:" + this.count;
            this.count++;
        }
    }
}
</script>

事件修饰符:即常用的 event.xxx方法

具体参考:https://cn.vuejs.org/guide/essentials/event-handling.html#event-modifiers

例如:

<template>
	<a @click="clickHiden($event)" href="https://romcere.top">romcere</a>
</template>
<script>
export default{
    data(){
        return{
            count:0
        }
    },
    methods:{
        clickHiden(e){
            // 阻止默认点击事件
            e.preventDefault();
            console.log("点击了");
        }
    }
}
</script>
<!-- 或者直接使用@click.prevent="" -->
<a @click.prevent="clickHiden()" href="https://romcere.top">romcere</a>

数组变化侦测

<template>
	<button @click="click()">点我</button>
    <p v-for="item in names">{{ item }}</p>
</template>
<script>
export default{
    data(){
        return{
            names:["nums1","nums2","nums3"]
        }
    },
    methods:{
        click(){
            // 使用此方法会直接更新数组信息
            // this.names.push("nums4");
            // 使用此方法不会直接变更,需要重新赋值
            this.names = this.names.concat("nums4")
        }
    }
}
</script>

计算属性

computed总是在响应式计算更新时才计算,而 methods总在页面重渲染时执行;使用 computed可以减少缓存

<template>
	<!-- 这里len不要加(),因为它不是函数 -->
    <p>{{ len }}</p>
	<!-- 常规写法 -->
	<p>{{ this.names.length > 1 ? 'Yes' : 'NO' }}</p>
</template>
<script>
export default{
    data(){
        return{
            names:["nums1","nums2","nums3"]
        }
    },
    // !!!放置计算数学的方法
    computed:{
        len(){
            return this.names.length > 1 ? 'Yes' : 'NO';
        }
    }
}
</script>

Class与Style增强

绑定class类有很多种方法:

<template>
	<!-- 使用isActive来判断active类是否显示 -->
    <p :class="{'active':isActive}" >测试文字1</p>
	<!-- 使用对象添加类 -->
	<p :class="activeOBJ" >测试文字2</p>
	<!-- 数组添加或数组嵌套对象 -->
	<p :class="[isActive,activeOBJ]" >测试文字3</p>
</template>
<script>
export default{
    data(){
        return{
            isActive:false,
            activeOBJ:{
                'active':true
            }
        }
    }   
}
</script>
<style>
.active{
    color:red;
}
</style>

绑定Style:

<template>
	<!-- 使用此方法动态添加style -->
    <p :style="{color:activrColor,fontSize:fontSize + 'px'}" >测试文字</p>
	<!-- 以对象方式添加 -->
    <p :style="styleOBJ" >测试文字</p>
</template>
<script>
export default{
    data(){
        return{
            activeColor:'green',
            fontSize:30,
            styleOBJ:{
                color:"red",
                fontSize:"30px"
            }
        }
    }
}
</script>

侦听器

用于侦听数据的更改

<template>
	<!-- 侦听的是此数据的变化 -->
    <p>{{ msg }}</p>
    <button @click="edit">修改</button>
</template>
<script>
export default{
    data(){
        return{
            msg:"hello"
        }
    },
    methods:{
        edit(){
            this.msg="world"
        }
    },
    <!-- 侦听器 -->
    watch:{
        <!-- 这里的函数名必须与侦听的数据名保持一致 -->
        msg(newValue,oldValue){
            // 数据发生变化,自动执行的函数
            console.log(newValue,oldValue)
        }
    }
}
</script>

表单输入绑定

input输入的内容,可以实时读取:

<template>
    <form>
        <input type="text" v-model="msg">
        <p>{{ msg }}</p>
    </form>
</template>
<script>
export default{
    data(){
        return{
            msg:""
        }
    }
}
</script>

修饰符.lazy:失去焦点后得到、.number:去掉数字得到、.trim:去掉前后空格得到

获取DOM操作

如果没有特别的需求,不需要操作DOM:

<template>
	<!-- 使用ref属性 -->
    <div ref="container">{{ content }}</div>
    <button @click="getItem">获取元素</button>
</template>
<script>
export default{
    data(){
        return{
            content:"内容"
        }
    },
    methods:{
        getItem(){
            // 使用this.$refs.<ref-name>获取DOM
            console.log(this.$refs.container)
        }
    }
}
</script>

引用组件

App.vue中写入以下代码来引用组件:

<template>
  <test/>
</template>
<script>
import test from './components/test.vue'
export default{
  // 在components中放入组件名
  components:{
    test
  }
}
</script>

组合式API学习

ref-reactive区别

ref为引用类型,需要使用.value才能访问到值;reactive则可以直接访问到数据

reactive一般用来存储复杂数据类型;ref一般存储变量、方法

v-on 点击事件

可简写为 @

<el-button v-on:click="add"/>
<el-button @click="add"/>

@keyup.xxx 按键修饰符

<!-- 输入enter键时,执行该输入框的方法 -->
<el-input @keyup.enter="add"/>

v-show 显示与隐藏

提前渲染,适用于频繁切换显示状态

<!-- isShow为true时展示 -->
<p v-show="isShow">Romcere romcere.top</p>

v-if 条件渲染

是否渲染元素,不适用于频繁切换显示状态,否则对性能有影响

<p v-if="isShow">这是v-if</p>
<p v-else-if="isShow">这是v-else-if</p>
<!-- 当不满足上述条件时,则渲染 -->
<p v-else>这是v-else</p>

v-bind 动态属性绑定

可简写为 :

<img v-bind:src="imageUrl" >
<img :src="imageUrl" >

v-for 遍历循环

<el-input v-for="item in dataForm"/>

v-model 双向数据绑定

<!-- 当修改inputValue值时,inputValue被同时更改 -->
<el-input v-model="inputValue" />
<!-- 只能赋给输入框初值,不能获取到输入框的值;即inputValue不能被更改 -->
<el-input :value="inputValue" />

v-model.xxx 修饰符

<!-- 可以在v-model后加.xxx来对inputValue值提前进行处理 -->
<el-input v-model.trim="inputValue" />

v-text v-html 渲染数据

<h3 v-text="romcere.top" />
<!-- 此时会将<i>标签解析嵌套入<h3>标签内,然后显示文本 -->
<h3 v-html="<i style="color:blue">romcere.top</i> />

computed 计算属性

<template>
	<h3> add:{{add}} </h3>
	<h3> add:{{add}} </h3>
	<!-- 调用两次sub方法,但实际上只调用了一次(只打印了一次sub),说明有缓存 -->
	<h3> sub:{{sub}} </h3>
	<h3> sub:{{sub}} </h3>
</template>
<script setup>
    const x = ref(10)
    const y = ref(20)
    const add = ref(()=>{
        console.log("add") // 打印两次
        return x+y
    })
	const sub = computed(()=>{
        console.log("sub") // 打印一次,有缓存可以提高性能
        return x+y
    })
</script>

watch 侦听器

<template>
    <el-input v-model="inputValue" />
</template>
<script setup>
    const inputValue = ref('')
    // 侦听inputValue,当其值变化时进行操作
	watch(inputValue,(newValue,oldValue)=>{
        console.log('newValue:',newValue,'oldValue:',oldValue)
    })
</script>

watchEffect 自动侦听器

<template>
    <el-input v-model="inputValue" />
</template>
<script setup>
    const inputValue = ref('')
    // 使用此方法,会在页面渲染后就开始监听
	watchEffect(()=>{
        console.log("----开始监听----")
        console.log(inputValue.value)
        console.log("----监听结束----")
    })
</script>

defineProps 父传子

<!-- 子组件 文件名为Web.vu -->
<template>
	<span>{{web}}</span>
</template>
<script setup>
	const props=defineProps({
        web:String
    })
</script>
<!-- 父组件 -->
<template>
	<Web :temp="Romcere."></Web>
</template>
<script setup>
	import Web from '@/xxx'
</script>

defineEmits 子传父-事件传递

<!-- 子组件 -->
<script setup>
	const emits=defineEmits(['getWeb'])
    // 第一个参数为要传递方法名,第二个参数为传递的数据
    emits('getWeb',[url:'Romcere.'])
</script>
<!-- 父组件 -->
<template>
	<Web @getWeb="emitsGetWeb"></Web>
</template>
<script setup>
	import Web from '@/xxx'
    // 这里的data为子组件传递的数据
    const emitsGetWeb=(data)=>{
        console.log(data.url)
    }
</script>

defineExpose 子传父-暴露自己的属性或方法

<!-- 子组件 -->
<script setup>
	function show(){
    console.log("这是子组件")
  }
  defineExpose({
    show,
    count:1
  })
</script>
<!-- 父组件 -->
<template>
	<Temp ref="childRef"></Temp>
	<el-button @click="handleClick"></el-button>
</template>
<script setup>
	import Temp from '@/xxx'
  // 需先定义ref
  const childRef = ref(null)
  function handleClick(){
    childRef.value.show()
    console.log(childRef.value.count)
  }
</script>

provide-inject 跨组件通信-依赖注入

该方法可以将父组件数据传到子组件的子组件

<!-- 父组件 -->
<script setup>
	const web = ref({
        url:'romcere.top'
    })
    // 第一个参数为传递的方法名,第二个参数为传递的数据
    provide('provideWeb',web)
</script>
<!-- 子子组件 -->
<script setup>
    // 接收到父父组件的数据
	const web=inject('provideWeb')
    console.log('provideWeb',web)
</script>

slot 匿名插槽-具名插槽

<!-- 子组件 -->
<template>
    <slot name="web"></slot>
</template>
<!-- 父组件 -->
<template>
	<Web>
        <!-- v-slot:web也可简写为#web -->
    	<template v-slot:web>
			<a href='romcere.top'>romcere.top</a>
		</template>
    </Web>
</template>
<script setup>
    import Web from '@/xxx'
</script>

作用域插槽

子组件可以向父组件传递数据

<!-- 子组件 -->
<template>
    <slot name="web" title="Romcere."></slot>
</template>
<!-- 父组件 -->
<template>
	<Web>
        <!-- 这里的data用于接收子组件传递的数据 -->
    	<template #web="data">
			<a href='romcere.top'>{{data.title}}</a>
		</template>
    </Web>
</template>
<script setup>
    import Web from '@/xxx'
</script>

生命周期函数

定义:指从组件实例从创建到销毁的过程中,不同时间点 自动调用 的函数

挂载阶段:

onBeforeMount:在组件实例即将

被挂载到DOM树之前调用;常用于执行初始化操作。

如:获取异步数据、设置初始属性值等
onMounted:在组件

成功挂载到DOM并完成首次渲染后调用;此时可访问和操作DOM元素。

更新阶段:

onBeforeUpdate(由于响应式数据变化):在

组件更新前即将重新渲染时调用;根据新的参数判断是否要进行处理,甚至可以选择阻止此次更新

onUpdate:在

组件完成更新并重新渲染后调用,可以基于渲染结果处理更新后的数据

卸载阶段:

onBeforeUnmount:在

组件从DOM中销毁前调用;用于释放资源

如:清理计时器、解绑事件监听器
onUnmounted:在

组件已经从DOM中移除并销毁后调用;确保组件所占用的资源被释放

错误处理:

onErrorCaptured:在

捕获到组件中的错误时调用;用于处理错误

如:记录错误日志

toRef toRefs 转换为ref对象

toRefs将一个响应式对象的所有属性转换为ref对象

toRef将一个响应式对象的某个属性转化为ref变量

<template>

</template>
<script setup>
    let web={
        name:"Romcere.",
        url:"romcere.top"
    }
    let web=toRefs(web)
    // 第一个参数为要转换的对象,第二个参数为要转换属性名
    let web=toRef(web,url)
    console.log(typeof web.url)
</script>

Pinia-stores 状态管理

解决问题:1.全局状态管理 2.简化组件间通信 3.状态持久化 

文章作者: Romcere.
本文链接:
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Romcere.
Web前端 Vue
喜欢就支持一下吧