文中给出的完整代码实例都是可以直接运行的
可以在(建议用下面一个,但是要删掉他原本有的代码)
在线运行
本文架构:
前言:
嗯,学习这个的起因是数据库课程设计,老师说我的前端做的不好看qaq
之前看过一点vue2(很少很少一点),所以来学vue3,准备美化一下个人blog
服务器,后端,域名什么的都弄好了
开始
起步:(初步认识)
在这学的Vue3 起步 | 菜鸟教程 (runoob.com)
首先是vue3的引入,还是从vue.global.js的手动引入开始吧
<script src='vue.global.js'></script>
我是把vue.js下载到了本地,下载地址:https://unpkg.com/vue@3.2.36/dist/vue.global.js
当然你也可以用CDN方法(unpkg的很好用,后面的例子也都是基于unpkg演示)
然后是先初略学习两个实例
主要就是data用法和methods用法,document是一个js操作
<script src='https://unpkg.com/vue@next'></script>
const app=Vue.createApp({
data(){
return{count:4}//以$data的形式返回
},//这个地方有个逗号,就这错了几次
methods:{
add(){
this.count++//this指向相关组件
}
}
})
const vm = app.mount('#app')//挂载到app
document.write(vm.$data.count)
这里我把app挂载到了id=‘app’的地方,所以完整代码应该是这样的
<!DOCTYPE html>
<script src='https://unpkg.com/vue@next'></script>
<div id='app'>
{{count}}
</div>
<script>
const app=Vue.createApp({
data(){
return{count:4}//以$data的形式返回
},//这个地方有个逗号,就这错了几次
methods:{
add(){
this.count++//this指向相关组件
}
}
})
const vm = app.mount('#app')//挂载到app
document.write(vm.$data.count)
</script>
运行结果:
好了,我决定先去吃饭qaq(2022-7-29,11:54)
吃完了(2022-7-29 12:58)
语法模板
vue是基于html5的语法格式(差不多这个意思)
存放html字段的一个方法,之前学html讲过
web应用开发被迫学的,第一门没考到90的编程,不过这课很多卷王都是70多
<div id="app">
<p>{{ message }}</p>
</div>
使用 v-html 指令用于输出 html 代码:
暂时还没感觉到有什么用,先记下来
<div id="example1" class="demo">
<p>使用双大括号的文本插值: {{ rawHtml }}</p>
<p>使用 v-html 指令: <span v-html="rawHtml"></span></p>
</div>
<script>
const RenderHtmlApp = {
data() {
return {
rawHtml: '<span style="color: red">这里会显示红色!</span>'
}
}
}
Vue.createApp(RenderHtmlApp).mount('#example1')
</script>
输出结果:
v-bind指令
html没学好,看来半天才转过来,截图放这怕以后忘了
改写一下他给的实例
<!DOCTYPE html>
<head>
<script src='https://unpkg.com/vue@next'></script>
<style>
.class1{
background: #444;
color: #eee;
}
</style>
</head>
<body>
<div id='app'>
//判断开关
<label for='r1'>修改</label><input type='checkbox' v-model='use' id='r1'>
//主体在这
<div v-bind:class="{'class1':use}">//是否使用class1
v-bind
</div>
</div>
<script>
const app=Vue.createApp({
data(){
return{use:false}
}
})
const vm=app.mount('#app')
</script>
</body>
解释一下:
<style> .class
//html中控制格式的代码段,此处定义为class1的格式
<lable>
//开关
<input>
//输入,id='r1'与label对应,v-model=use:控制的是use的值
v-bind:class
//控制class是否显示
运行截图
html中的注释不该这么写,我图个方便
表达式
Vue.js可以使用JavaScript的表达式(妈耶我没学过js)
硬着头皮写一点
<div id="app">
{{5+5}}<br>//算数表达式
{{ ok ? 'YES' : 'NO' }}<br>//三元表达式,类似C语言,ok为true第一个,为flase第二个
{{ message.split('').reverse().join('') }}//类似python的一套操作,当然我更喜欢在后端完成
<div v-bind:id="'list-' + id">菜鸟教程</div>//没看懂
</div>
一个提示
这个地方很简单就不改写了
指令
这里讲了v-if和v-for,前面一个用于选择,后面一个用于循环
写上一个例子吧(sites数组要写逗号,第二次这里bug了)
<!DOCTYPR html>
<head>
<script src='https://unpkg.com/vue@next'></script>
</head>
<body>
<div id='app'>
<p v-if='seen'>是否显示</p>//判断seen的是否为true
<ol>//定义表格
<li v-for='site in sites'>//循环
{{site.text}}
</li>
</ol>
</div>
<script>
const app=Vue.createApp({
data(){
return{
sites: [
{ text: '1' },//这里有逗号
{ text: '2' },//这里有逗号
{ text: '3' }
],
seen:true
}
}
})
const vm=app.mount('#app')
</script>
</body>
参数
简单来说就是在指令(v-xxx)后面加上冒号来指明
写一个例子吧
例子的说明是这个:
嗯。。前面不是说v-bind是用来判断true/false的吗
我查询了一下,发现v-bind实际上是用来绑定一个属性的qaq
地址:v-bind说明
<!DOCTYPE html>
<head>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app">
<p><a v-bind:href="url">csdn社区</a></p>
</div>
<script>
const app =Vue.createApp( {
data() {
return {
url: 'https://www.csdn.net/'
}
}
}).mount('#app')
</script>
</body>
运行截图
这里也讲了v-bind的作用
还提到了v-on指令,先码住
修饰符
对与对应事件调用指令
用户输入/v-model双向绑定
写一个例子
<!DOCTYPE html>
<head>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app">
<p>{{ message }}</p>
<input v-model="message">
</div>
<script>
const app =Vue.createApp({
data() {
return {
message: 'vue前端开发'
}
}
}).mount("#app")
</script>
</body>
运行截图
类似点击触发事件,调用某个方法
写下这个例子
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app">
<p>{{ message }}</p>
<button v-on:click="reverseMessage">反转字符串</button>
</div>
<script>
const app = Vue.createApp({
data() {
return {
message: 'vue前端开发!'
}
},
methods: {
reverseMessage() {
this.message = this.message.split('').reverse().join('')
}
}
}).mount('#app')
</script>
</body>
</html>
运行截图
Vue. js官方的两个缩写
条件语句
所以说我们结束了认识vue的部分,开始学习一些语句
条件语句主要是v-if
当然,有if就必定有else if和else,于是,一个不同于上一节所写的例子就诞生了
<!DCOTYPE html>
<head>
<script src='https://unpkg.com/vue@next'><script>
</head>
<body>
<div id='app'>
<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>
const app=Vue.createApp({
data(){
return{
type:'D'
}
}
}).mount("#app")
</script>
</body>
运行结果
一个提示
还有一个用法v-show,这个用法是输出指定的语句
我们改写一下上面的例子,根据judge来输出(感觉跟单用v-bind区别不大)
<!DCOTYPE html>
<head>
<script src='https://unpkg.com/vue@next'></script>
</head>
<body>
<div id='app'>
<h1 v-show='judge'>判断<h1>
</div>
<script>
const app=Vue.createApp({
data(){
return{
judge:true
}
}
}).mount("#app")
</script>
</body>
运行结果截图
循环语句
主要是v-for,嗯,他是一个迭代器
vue中的数组都是键值对的模式,也有数组/列表那种下标
先写一个初级的例子(多参数的例子),通过参数迭代(一般迭代高维)
<!DOCTYPR html>
<head>
<script src='https://unpkg.com/vue@next'></script>
</head>
<body>
<div id='app'>
<ol>//定义表格
<li v-for="(site, index) in sites">//注意英语括号
{{ site.text }}-{{ index }}
</li>
</ol>
</div>
<script>
const app=Vue.createApp({
data(){
return{
sites: [
{ text: '1' },//这里有逗号
{ text: '2' },//这里有逗号
{ text: '3' }
],
seen:true
}
}
})
const vm=app.mount('#app')
</script>
</body>
运行截图
他举了一个在模板的例子,当然,没什么区别例子代码
还可以通过对象的属性迭代(一般迭代一维)
写一个例子
<!DOCTYPE html>
<head>
<script src='https://unpkg.com/vue@next'></script>
</head>
<body>
<div id="app">
<ul>
<li v-for="value in object">
{{ value }}
</li>
</ul>
</div>
<script>
const app =Vue.createApp({
data() {
return {
object: {
str1: '1',
str2: '2',
str3: '3'
}
}
}
}).mount('#app')
</script>
</body>
运行截图
当然,最多可以同时迭代三个参数qaq,这里不多赘述
<div id="app">
<ul>
<li v-for="(value, key, index) in object">
{{ index }}. {{ key }} : {{ value }}
</li>
</ul>
</div>
也可以迭代整数
<div id="app">
<ul>
<li v-for="n in 10">
{{ n }}
</li>
</ul>
</div>
当然,也可以对数组元素进行一些处理
我为什么不在后端处理(
到晚饭点了,去吃晚饭(我咋天天想着吃饭)(2022-7-29 18:00)
吃完饭打电动(bushi)到现在(2022-7-29 21:31)
补充一个知识点:html5的运算符
html中的运算符_酥皮小熊的博客-CSDN博客_html 运算
例子一:原例子是只输出偶数,改成了只输出3的倍数
<!DOCTYPE html>
<head>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app">
<ul>
<li v-for="n in evenNumbers">{{ n }}</li>
</ul>
</div>
<script>
const app =Vue.createApp({
data() {
return {
numbers: [ 1, 2, 3, 4, 5 ]
}
},
computed: {
evenNumbers() {
return this.numbers.filter(a => a % 3 === 0)
}
}
}).mount('#app')
</script>
</body>
filter是保留下满足目标的数据JavaScript Array filter() 方法 | 菜鸟教程 (runoob.com)
(写完这个贴我必补html,css和js基础)
运行截图
v-for与v-if的一些联合使用
这个例子有点难看懂qaq
<!DOCTYPE html>
<script src="https://unpkg.com/vue@next"></script>
<body>
<div id="app">
<select @change="changeVal($event)" v-model="selOption">
//@change是v-on用法的缩写,v-model是将选项与selOption双向绑定
<template v-for="(site,index) in sites" :site="site" :index="index" :key="site.id">
//template元素https://www.w3school.com.cn/tags/tag_template.asp
<!-- 索引为 1 的设为默认值,索引值从0 开始-->
<option v-if = "index == 1" :value="site.name" selected>{{site.name}}</option>
<option v-else :value="site.name">{{site.name}}</option>
</template>
</select>
<div>您选中了:{{selOption}}</div>
</div>
<script>
const app =Vue.createApp({
data() {
return {
selOption: "test1",//定义一开始显示的值
sites: [
{id:1,name:"test1"},
{id:2,name:"test2"},
{id:3,name:"test3"},
]
}
},
methods:{
changeVal:function(event){
this.selOption = event.target.value;
alert("你选中了"+this.selOption);
}
}
}).mount('#app')
</script>
</body>
整体功能是什么意思呢:你有一个下拉框,你选中其中一个东西,就会提示你选中了什么(跟django的errormessage类似),并且变成对应的选项)
关于template标签做一个笔记HTML <template> 标签 (w3school.com.cn)
一个非常好的实例W3School TIY Editor
一个用法 js获取文本框的值
event.target.value()
这个地方刚学确实有点难看懂,先看后面的等下回来再看
在组件上使用v-for(回头再更新)
教程上说先跳过吧
Vue3组件(重点)
简单来说,就是借助js来完成html的各种重复性操作
全局组件
先借助他的代码来理解一下
<!DOCTYPE html>
<head>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app">
<runoob></runoob>
</div>
<script>
// 创建一个Vue 应用
const app = Vue.createApp({})
// 定义一个名为 runoob 的新全局组件
app.component('runoob', {
template: '<h1>自定义组件!</h1>'
})
app.mount('#app')
</script>
</body>
流程简单来说:创建app,定义组件,将组件挂载到div中
运行截图
再看一个例子
<!DOCTYPE html>
<script src="https://unpkg.com/vue@next"></script>
<body>
<div id="app">
<button-counter></button-counter>
</div>
<script>
// 创建一个Vue 应用
const app = Vue.createApp({})
// 定义一个名为 button-counter 的新全局组件
app.component('button-counter', {
data() {
return {
count: 0
}
},
template: `
<button @click="count++">
点了 {{ count }} 次!
</button>`
})
app.mount('#app')
</script>
</body>
这里的count++是事件,居然还可以这样触发
运行截图
就是这个玩意
`
局部组件
还是直接来看实例吧(看不懂文字就看代码)
<!DOCTYPE html>
<script src="https://unpkg.com/vue@next"></script>
<body>
<div id="app">
<runoob-a></runoob-a>
</div>
<script>
var runoobA = {
template: '<h1>自定义组件!</h1>'
}
const app = Vue.createApp({
components: {
'runoob-a': runoobA
}
}).mount('#app')
</script>
</body>
运行截图
很好理解了,定义一个普通组件,然后在需要的app里面调用
Prop/动态Prop
简单来说,就是传递参数
自己先写一个局部组件+调用+Prop传递参数的例子:
<!DOCTYPE html>
<script src='https://unpkg.com/vue@next'></script>
<body>
<div id='app'>
<test1 value='test1'></test1>
<test1 value='test2'></test1>
<test1 value='test3'></test1>
</div>
<script>
var rb1={
props:['value'],
template:`<h1>{{value}}</h1>`
}
const app=Vue.createApp({
components:{
'test1':rb1
}
}).mount('#app')
</script>
</body>
运行截图
动态Prop
简单来说就是把数据跟app绑定,来达到动态的参数
简单写一个例子:
<!DOCTYPE html>
<script src="https://unpkg.com/vue@next"></script>
<body>
<div id="app">
<site-info
v-for="site in sites"
v-bind:id="site.id"
:title="site.title"
></site-info>
<!--v-bind将组件的数据与app的数据绑定,v-bind:也可以简写为一个冒号:-->
</div>
<script>
const app =Vue.createApp({
data() {
return {
sites: [
{ id: 1, title: 'Google' },
{ id: 2, title: 'Runoob' },
{ id: 3, title: 'Taobao' }
]
}
}
}).component('site-info', {
props: ['id','title'],
template: `<h4>{{ id }} - {{ title }}</h4>`
}).mount('#app')
</script>
</body>
运行截图
Prop验证
这个地方有点难,我们先看看教程怎么讲的
Vue.component('my-component', {
props: {
// 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
propA: Number,
// 多个可能的类型
propB: [String, Number],
// 必填的字符串
propC: {
type: String,
required: true
},
// 带有默认值的数字
propD: {
type: Number,
default: 100
},
// 带有默认值的对象
propE: {
type: Object,
// 对象或数组默认值必须从一个工厂函数获取
default: function () {
return { message: 'hello' }
}
},
// 自定义验证函数
propF: {
validator: function (value) {
// 这个值必须匹配下列字符串中的一个
return ['success', 'warning', 'danger'].indexOf(value) !== -1
}
}
}
})
写一个例子吧:(我也看不懂qaq)
例子来源Vue:Prop验证的使用_Angular baby的博客-CSDN博客_prop 验证
<template>
<div style="margin-top:100px">
<my-component :propA="100" :propB="'sdf'" :propC="'propC11'" :propD="100" :propE="{a:'a'}" :propF="'warning'"></my-component>
</div>
</template>
<script type="text/javascript">
import Vue from 'vue'
Vue.component('my-component', {
props: {
propA: Number,
propB: [String, Number],
propC: {
type: String,
required: true
},
propD: {
type: Number,
default: 100
},
propE: {
type: Object,
default: function () {
return { message: 'hello' }
}
},
propF: {
validator: function (value) {
return ['success', 'warning', 'danger'].indexOf(value) !== -1
}
}
},
template: `
<div>
<p>{{ propA }}</p>
<p>{{ propB }}</p>
<p>{{ propC }}</p>
<p>{{ propD }}</p>
<p>{{ propE }}</p>
<p>{{ propF }}</p>
</div>`
})
export default {
name: 'learn',
components: {
},
data () {
return {
}
},
methods: {
}
}
</script>
<style>
</style>
简而言之,这是在测试自己开发的组件的时候用到的方法,检查传入的参数是否正确
暂时还用不到,现在还在手写Vue阶段,还用不到开发工具
计算属性
这个地方其实可以用methods代替一下,但是computed会快一些,效果是一样的
但是computed会有一个缓存问题
简单的例子在最前面举例过了,这里再写一次(其实我觉得都用methods就好qaq)
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app">
<p>{{ reverseMessage }}</p>
</div>
<script>
const app = Vue.createApp({
data() {
return {
message: 'vue前端开发!'
}
},
computed: {
reverseMessage() {
return this.message.split('').reverse().join('')
}
}
}).mount('#app')
</script>
</body>
</html>
运行截图
setter
感觉反而弄麻烦了,还是都用methods吧(这个例子不是我写的,不一定能运行)
var vm = new Vue({
el: '#app',
data: {
name: 'Google',
url: 'http://www.google.com'
},
computed: {
site: {
// getter
get: function () {
return this.name + ' ' + this.url
},
// setter
set: function (newValue) {
var names = newValue.split(' ')
this.name = names[0]
this.url = names[names.length - 1]
}
}
}
})
// 调用 setter, vm.name 和 vm.url 也会被对应更新
vm.site = '菜鸟教程 http://www.runoob.com';
document.write('name: ' + vm.name);
document.write('<br>');
document.write('url: ' + vm.url);
运行结果(教程给的)
监听属性
vue3使用watch来充当监听属性
先来一个简单的例子
这里的old,new可以自己定义,前面一个是新变量,后面一个是旧变量
<!DOCTYPE html>
<script src="https://unpkg.com/vue@next"></script>
<body>
<div id = "app">
<p style = "font-size:25px;">计数器: {{ counter }}</p>
<button @click = "counter++" style = "font-size:25px;">点我</button>
</div>
<script>
const app = {
data() {
return {
counter: 1
}
}
}
vm = Vue.createApp(app).mount('#app')
vm.$watch('counter', function(new1, old) {
alert('计数器值的变化 :' + old + ' 变为 ' + new1 + '!');
});
</script>
</body>
运行截图
电脑没电了,该睡觉了qaq,明天起来看看项目和数模吧qaq(2022-7-30 0:20)
起床开肝(2022-7-30 14:05)
千米与米之间的转换
先来看例子
简单来说就是监听一个值的同时改变另外一个值
v-model将input和kilometers,meters双向绑定
<!DOCTYPE html>
<script src="https://unpkg.com/vue@next"></script>
<body>
<div id = "app">
千米 : <input type = "text" v-model = "kilometers">
米 : <input type = "text" v-model = "meters">
</div>
<p id="info"></p>
<script>
const vm =Vue.createApp({
data() {
return {
kilometers : 0,
meters:0
}
},
watch : {
kilometers:function(val) {
this.kilometers = val;
this.meters = this.kilometers * 1000
},
meters : function (val) {
this.kilometers = val/ 1000;
this.meters = val;
}
}
}).mount('#app')
vm.$watch('kilometers', function (newValue, oldValue) {
// 这个回调将在 vm.kilometers 改变后调用
document.getElementById ("info").innerHTML = "修改前值为: " + oldValue + ",修改后值为: " + newValue;
})
</script>
</body>
其中有这一行代码:
document.getElementById ("info").innerHTML = "修改前值为: " + oldValue + ",修改后值为: " + newValue;
这一行代码的意思是(js基础不好呜呜)
获取id为info的值/修改标签为info的值document.getElementById().innerHTML
运行结果
vue3-watch监听属性演示案例
异步加载使用Watch(跟ajax一起使用,放到后面仔细说)
先来看一下异步的定义(熟悉这一定义的小伙伴可以跳过)
简单来说,有三个任务啊A,B,C,同步执行就是A,B,C的顺序
异步的话,可以是A,(B,C),即B,C同时执行
可以看看这个什么是异步?
来个例子:异步使用watch的例子
样式绑定
v-bind属性绑定
这个地方在前面讲v-bind的用法提到过:用true和false控制div的样式
<!DOCTYPE html>
<head>
<script src="https://unpkg.com/vue@next"></script>
<style>
.active {
width: 100px;
height: 100px;
background: green;
}
</style>
</head>
<body>
<div id="app">
<div :class="{ 'active': isActive }"></div>
</div>
<script>
const app =Vue.createApp({
data() {
return {
isActive: true
}
}
}).mount('#app')
</script>
</body>
运行截图
当然,也可以传入多个参数
<div class="static" :class="{ 'active' : isActive, 'text-danger' : hasError }">
</div
也可以直接绑定数据里的一个对象
如果本来给div元素指定了一个class,当v-bind绑定的class返回为true时,会覆盖原class
<!DOCTYPE html>
<head>
<script src="https://unpkg.com/vue@next"></script>
<style>
.static {
width: 100px;
height: 100px;
}
.active {
background: green;
}
.text-danger {
background: red;
}
</style>
</head>
<body>
<div id="app">
<div class="static" :class="classObject"></div>
</div>
<script>
const vm=Vue.createApp({
data() {
return {
classObject: {
'active': false,
'text-danger': true
}
}
}
}).mount('#app')
</script>
</body>
运行截图
使用计算属性来绑定
代码实例
简单来说,先在computed中写好规则,然后直接调用(复用性较高,常用)
<!DOCTYPE html>
<head>
<script src="https://unpkg.com/vue@next"></script>
<style>
.static {
width: 100px;
height: 100px;
}
.active {
background: green;
}
.text-danger {
background: red;
}
</style>
</head>
<body>
<div id="app">
<div class="static" :class="classObject"></div>
</div>
<script>
const vm =Vue.createApp({
data() {
return {
isActive: true,
error: null
}
},
computed: {
classObject() {
return {
'active': this.isActive && !this.error,
'text-danger': this.error && this.error.type === 'fatal'
}
}
}
}).mount('#app')
</script>
</body>
运行截图
v-bind数组语法
这个地方很简单,后面一个导入的会覆盖前面一个导入的
<div class="static" :class="[activeClass, errorClass]"></div>
也可以用三元表达式
<div id="app">
<div class="static" :class="[isActive ? activeClass : '', errorClass]"></div>
</div>
先写到这,有点事出去 2022-7-30 16:24