✨Vue.js

介绍

【前端】Vue学习笔记_插槽

Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。

  • Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。
  • 另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。


官方网站:​​Vue.js (vuejs.org)​

官方文档:​​介绍 — Vue.js (vuejs.org)​


组件化应用构建

组件系统是 Vue 的另一个重要概念,因为它是一种抽象,允许我们使用小型、独立和通常可复用的组件构建大型应用。仔细想想,几乎任意类型的应用界面都可以抽象为一个组件树。

【前端】Vue学习笔记_前端_02

实例生命周期钩子

每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。


生命周期图示

下图展示了实例的生命周期。你不需要立马弄明白所有的东西,不过随着你的不断学习和使用,它的参考价值会越来越高。

【前端】Vue学习笔记_Vue_03

✨课程链接

​【狂神说Java】Vue最新快速上手教程通俗易懂_哔哩哔哩_bilibili​

!建议结合视频以及官方文档学习


✨学习笔记

第一个Vue

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>

</head>
<body>

<!--View层 模板-->
<div id="app">
<span v-bind:title="message">
鼠标悬停查看此页面动态绑定提示信息
<span/>
</div>

<!--<!&ndash;导入vue.js&ndash;>-->
<!--<script src="lib/vue.min.js"></script>-->

<!--<!&ndash; 开发环境版本,包含了有帮助的命令行警告 &ndash;>-->
<!--<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>-->

<!-- 生产环境版本,优化了尺寸和速度 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>

<script>
var vm = new Vue({
el:"#app",
data:{
message:"hello vue!"
}
})
</script>


</body>
</html>


基本语法

判断

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>

</head>
<body>

<!--View层 模板-->
<div id="app">
<h1 v-if="type==='A'">A</h1>
<h1 v-else-if="type==='B'">B</h1>
<h1 v-else="ok">C</h1>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>

<script>
var vm = new Vue({
el:"#app",
data:{
type : 'A'
}
})
</script>


</body>
</html>


循环

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>

</head>
<body>

<!--View层 模板-->
<div id="app">

<li v-for="(item, index) in items">
{{item.message}} -> {{index}}
</li>

</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>

<script>
var vm = new Vue({
el:"#app",
data:{
items:[
{message:'msg1'},
{message:'msg2'},
{message:'msg3'},
]
}
})
</script>


</body>
</html>


事件

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>

</head>
<body>

<!--View层 模板-->
<div id="app">
<button v-on:click="sayHi">sayHi</button>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
<script>

var vm = new Vue({
el:"#app",
data: {
message:'msg'
},
methods: {
sayHi:function () {
alert(this.message)
}
}
})
</script>


</body>
</html>


双向绑定

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>

</head>
<body>

<!--View层 模板-->
<div id="app">

下拉框
<select v-model="selected">
<option value="" disabled>--请选择--</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>

<span>选了:{{selected}}</span>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>

<script>
var vm = new Vue({
el:"#app",
data: {
selected: ''
}
})
</script>


<!--<!&ndash;View层 模板&ndash;>-->
<!--<div id="app">-->
<!-- 性别:-->
<!-- <input type="radio" name="sex" value="man" v-model="message"> 男-->
<!-- <input type="radio" name="sex" value="woman" v-model="message"> 女-->

<!-- <p>-->
<!-- 选中了谁:{{message}}-->
<!-- </p>-->
<!--</div>-->
<!--<div id="app">-->
<!-- 输入的文本 <input type="text" v-model="message"> {{message}}-->
<!--</div>-->

<!--<!&ndash; 生产环境版本,优化了尺寸和速度 &ndash;>-->
<!--<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>-->

<!--<script>-->
<!-- var vm = new Vue({-->
<!-- el:"#app",-->
<!-- data: {-->
<!-- message: ''-->
<!-- }-->
<!-- })-->
<!--</script>-->


</body>
</html>


组件

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>

<!--View层 模板-->
<div id="app">
<!-- 组件:传递给组件中的值props-->
<component v-for="item in items" v-bind:test="item"></component>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>

<script>

// 定义组件
Vue.component("component", {
// props不要使用驼峰命名
props:["test"],
template:"<li>{{test}}</li>"
});

var vm = new Vue({
el:"#app",
data:{
items:["Java", "Python"]
}
})
</script>

</body>
</html>


Axios异步通信

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>

<!-- v-cloak 解决闪烁问题-->
<style>
[v-clock]{
display: none;
}
</style>

</head>
<body>

<div id="vue" v-clock>
<div>{{info.name}}</div>
<div>{{info.links}}</div>

<a v-bind:href="info.url">点击跳转 -> TIOBE</a>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

<script type="text/javascript">
var vm = new Vue({
el:'#vue',
// data: 属性
data(){
return{
// 请求的返回参数合适 必须和json字符串一样
info:{
name:null,
url:null,
},
links:null
}
},
// 钩子函数 链式编程
mounted(){
// =>ES6新特性
axios.get('data.json').then(response=>(this.info = response.data))
}
})

</script>

</body>
</html>
{
"name": "Data",
"url": "https://www.tiobe.com/tiobe-index/",
"links": [
{
"name":"baidu",
"url": "https://www.baidu.com/"
},
{
"name": "bilibili",
"url": "https://www.bilibili.com/"
}
]
}


计算属性

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>

<!--View层 模板-->
<div id="app">
<!-- currentTime1() 记得加()调用方法-->
<p>currentTime1: {{currentTime1()}}</p>
<p>currentTime2: {{currentTime2}}</p>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>

<script>
var vm = new Vue({
el:"#app",
data:{
message:"test"
},
methods:{
currentTime1:function () {
// 重复调用后时间戳发生变化
// 返回一个时间戳
return Date.now();
}
},
// 计算属性 methods computed 方法名不能重名 重名之后只会调用methods中的方法
computed:{
currentTime2:function () {
// 重复查看属性不会发生变化 类似缓存
// 修改 this.message 后重新修改时间戳
this.message;
// 返回一个时间戳
return Date.now();
}
}
})
</script>


</body>
</html>


插槽

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>

<!--View层 模板-->
<div id="app">

<todo>
<todo-title slot="todo-title" :title="title"></todo-title>
<todo-items slot="todo-items" v-for="item in todoItems" :item="item"></todo-items>
</todo>

<!-- <p>列表数据</p>-->
<!-- <ul>-->
<!-- <li>Java</li>-->
<!-- <li>Python</li>-->
<!-- <li>C++</li>-->
<!-- </ul>-->
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>

<script>
// slot:插槽
Vue.component("todo",{
template:
'<div>\
<slot name="todo-title"></slot>\
<ul>\
<slot name="todo-items"></slot>\
</ul>\
</div>'
});

Vue.component('todo-title', {
// props不要使用驼峰命名
props:['title'],
template: '<div>{{title}}</div>'
});

Vue.component('todo-items', {
props:['item'],
template: '<li>{{item}}</li>'
});

var vm = new Vue({
el:"#app",
data:{
title:"插槽列表测试",
todoItems:['Java', 'Python', 'C++']
}
})
</script>
</body>
</html>


自定义事件内容分发

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>

<!--View层 模板-->
<div id="app">

<todo>
<todo-title slot="todo-title" :title="title"></todo-title>
<todo-items slot="todo-items" v-for="(item,index) in todoItems"
:item="item" :index="index" v-on:remove="removeItems(index)"></todo-items>
</todo>

</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>


<!--bind:绑定前端与vue的数据-->
<!--props绑定前端与组件的数据-->
<!--this.$emit()将事件分发回前端 前端v-on:remove再将事件给removeItems处理-->
<!--而key则是将index返回到vue实例-->

<!--前端 bind:自定义事件="remove"-->
<!--组件 删除事件() this.$emit("自定义事件")-->
<!--Vue实例 removeItems()-->


<script>
// slot:插槽
Vue.component("todo",{
template:
'<div>\
<slot name="todo-title"></slot>\
<ul>\
<slot name="todo-items"></slot>\
</ul>\
</div>'
});

Vue.component('todo-title', {
// props不要使用驼峰命名
props:['title'],
template: '<div>{{title}} </div>'
});

Vue.component('todo-items', {
props:['item', 'index'],
// 只能绑定当前组件的方法
template: '<li>{{index}} -> {{item}} <button @click="remove">删除</button></li>',
methods:{
remove:function (index) {
// this.$emit() 自定义事件分发
this.$emit('remove', index);
}
}
});

var vm = new Vue({
el:"#app",
data:{
title:"插槽列表测试",
todoItems:['Java', 'Python', 'C++']
},
methods: {
removeItems:function (index) {
// 一次删除一个元素
this.todoItems.splice(index, 1);
console.log("删除了 " + this.todoItems[index]);
}
}
})
</script>
</body>
</html>


✨参考及引用

​https://cn.vuejs.org/v2/guide/​