Vue
需要引入vue.js
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"</script>
最明显的区别:vue 中不用操作 dom 元素
1.创建dom结构,作为vue实例挂载点,vue实例中的所有数据只能在此dom范围内使用
<div id="app"> </div>
2.通过 new Vue 创建 vue 实例
3.el 属性指定当前 vue 实例的挂载点
4.data 中是模型数据,这些数据依赖于当前的vue实例,可以在控制台中通过下面方式访问data中数据
app.msg 访问控制台的数据
5.可以通过插值表达式使用 data 中的数据
1.数据绑定
1.1内容绑定
将 data 中的数据显示成内容(开始标签与结束标签之间)使用 {{}}获取纯文本
<div id="app"> <p>{{title}}</p> </div>
如果要显示 html 内容,需要使用 v-html 指令
<p v-html="content"></p>
1.2 属性绑定
将data中的数据作为某个元素的属性的值使用 v-bind:属性名称 指令,属性可以是内置,也可以是自定义的
<p v-bind:id="id">{{title}}</p>
v-bind: 可以缩写为 :
<p v-bind:id="id" :class="title_class">{{title}}</p>
2 表单控件的值
2.1表单控件的值
可以用 v-model 指令在表单 、 及 元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素
v-model 在内部为不同的输入元素使用不同的 property 并抛出不同的事件:
1.text 和 textarea 元素使用 value property 和 input 事件;2.checkbox 和 radio 使用 checked property 和 change 事件;
3.select 字段将 value 作为 prop 并将 change 作为事件。
文本框和文本域:
<input type="text" v-model="message">
<textarea v-model="message" cols="30" rows="10"></textarea>
复选框:复选框,v-model 绑定的是 checked 属性
<div id="app">
<label for="one">第一</label>
<input type="checkbox" id="one" v-model="first">
<label for="two">第二</label>
<input type="checkbox" id="two" v-model="second">
<label for="three">第三</label>
<input type="checkbox" id="three" v-model="third">
</div>
var vm = new Vue({
el: '#app',
data: {
first: true,
second:false,
third:false
}
})
单选按钮
var vm = new Vue({
el: '#app',
data: {
gender: ''
}
})
<div id="app">
<label for="man">男</label>
<input type="radio" id="man" value="man" v-model="gender">
<label for="women">女</label>
<input type="radio" id="women" value="women" v-model="gender">
{{gender}}
</div>
设置多个单选框的 v-model 为同样的值,就可以省略 name 属性
选择某个单选框后,此单选框的 vlue 属性值会赋值给 gender 属性
设置 gender 属性的值为某个单选框的 value 值,此单选框就会默认选中
2.2选择框
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<select v-model="city">
<option disable value="">请选择</option>
<option value="bj">北京</option>
<option value="sh">上海</option>
<option value="gz">广州</option>
</select>
<p>{{city}}</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let app=new Vue({
el:'#app',
data:{
city: '',
},
})
</script>
</body>
</html>
2.3表格渲染
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
</style>
</head>
<body>
<table id="app" class="">
<thead>
<th>姓名</th>
<th>学历</th>
<th>出生日期</th>
</thead>
<tbody>
<tr v-for="item in students">
<td>{{item.name}}</td>
<td>{{item.education}}</td>
<td>{{item.birth}}</td>
</tr>
</tbody>
</table>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
students: [],
},
created: function () {
fetch('data.json')
.then((res) => {
return res.json()
})
.then((res) => {
this.students = res
})
},
})
</script>
</body>
</html>
[
{ "id": 1, "name": "张三", "education": "专科", "birth":"1998.3.5" },
{ "id": 2, "name": "李四", "education": "本科", "birth":"1999.3.5"},
{ "id": 3, "name": "王五", "education": "研究生", "birth":"1995.3.5"}
]
2.4条件渲染
可以单独使用 v-if,或者 v-if 和 v-else,或者 v-if 和 v-else-if 搭配使用
v-if在单独使用的时候,与 v-show 的作用是一样的,
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="app">
<h1 v-if="isMary">完成</h1>
<h1 v-else>失败</h1>
<!-- 运行很少的条件的时候 -->
<h2 v-if="isif">v-if</h2>
<!-- 频繁切换 -->
<h2 v-show="type"> v-show</h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
isMary:false,
isif:true,
type:true
},
})
</script>
</body>
</html>
2.5样式处理
2.5.1vue操作class
- class 与 v-bind:class 可以共存,但是其实最终操作的都是元素的 class 属性
- v-bind:class 的值可以是字符串、对象或者数组
- v-bind:class 的值如果为对象,如{active:isActive,color:isColor},则属性名称是 style 中定义的样式类名称,属性值是 data 中定义的变量名称
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<style>
.c1 {
width: 200px;
height: 100px;
background-color: red;
}
.c2 {
width: 200px;
height: 100px;
background-color: blue;
}
.zhuyao {
width: 300px;
height: 200px;
border: 1px black solid;
}
.ciyao{
color: chocolate;
}
.huodong {
background-color: orange;
}
</style>
<body>
<div id="app">
<!-- <p v-bind:id="id" v-bind:class="c1" style="width: 200px;height: 100px;"></p> -->
<p v-bind:class="pcan"></p>
<!-- <p v-bind:class="{huodong:istrue}">对象表示法</p> -->
<!-- 多个属性共存 -->
<!-- class属于静态属性class v-bind:class属于动态class -->
<p class="zhuyao" v-bind:class="{huodong:istrue,ciyao:color}">多个属性共存</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
id: 11,
pcan: 'c2',
istrue:true,
color:true,
},
})
</script>
</body>
</html>
2.5.2 vue操作style
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="app">
<p :style="{width: a,height: b,backgroundColor:c}"></p>
<p :style="obj"></p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
a:'200px',
b:'200px',
c:'red',
obj:{
width:'300px',
height:'300px',
backgroundColor:'blue',
}
},
})
</script>
</body>
</html>
2.6 事件
2.6.1事件绑定
vue 中通过 v-on 指令为元素注册事件监听
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="app">
<button v-on:click="greet">点击按钮</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data:{
name:'onlife'
},
methods: {
greet:function(){
console.log(this.name);
//事件当中,this指向的是当前的vue实例
this.name='ms'
}
},
})
</script>
</body>
</html>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oUhCFPqd-1615375705796)(D:\前端分班\上课\vue的md图片\1.gif)]
2.6.2切换背景颜色
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
.box {
width: 500px;
height: 500px;
border: 5px solid black;
background-color: orange;
}
.big {
background-color: red;
}
</style>
</head>
<body>
<div id="app">
<div v-on:click="change" class="box" :class={big:isbig}></div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
isbig: false
},
methods: {
change: function () {
this.isbig = !this.isbig
}
}
})
</script>
</body>
</html>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-USvG4xN5-1615375705799)(D:\前端分班\上课\vue的md图片\2.gif)]
2.6.3换肤案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
html,body,#app{
height: 100%;
}
nav{
height: 150px;
background-color: rgba(red, green, blue, alpha);
text-align: center;
}
img{
height: 120px;
margin: 15px 20px;
}
</style>
</head>
<body>
<div id="app" :style="{backgroundImage:bgimg}">
<nav>
<img src="focus.jpg" v-on:click="change('focus.jpg')" alt="">
<img src="focus1.jpg" v-on:click="change('focus1.jpg')" alt="">
<img src="focus2.jpg" v-on:click="change('focus2.jpg')" alt="">
</nav>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
bgimg:'url(focus.jpg)'
},
methods:{
change:function(url){
console.log(url);
this.bgimg = `url(${url})`
}
}
})
</script>
</body>
</html>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ps3jHSzv-1615375705800)(D:\前端分班\上课\vue的md图片\3.gif)]
3计算属性和选择器
3.1计算属性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="app">
<table>
<thead>
<tr>
<th>编号</th>
<th>姓名</th>
<th>发表时间</th>
</tr>
</thead>
<tbody>
<tr v-for="item in bloglist">
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.create_time}}</td>
</tr>
</tbody>
</table>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
numbers: '12345',
blogList: [
{ id: 1, name: '张三', create_time: 1623456789000 },
{ id: 2, name: '李四', create_time: 161437485764 },
{ id: 3, name: '王五', create_time: 1583273648567 }
]
},
// 用户自定义的方法
methods: {
},
// 计算属性
computed: {
reversednumbers: function () {
return this.numbers.split('').reverse().join('')
},
bloglist: function () {
this.blogList.forEach(item => {
item.create_time = moment((item.create_time)).format('YYYY-MM-DD HH:mm:ss')
})
return this.blogList
}
}
})
</script>
</body>
</html>
3.2侦听器
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="app">
<input type="text" v-model="age">
<span>{{message}}</span>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
age:30,
message:''
},
methods:{},
compute:{},
watch:{
age:function(newValue, oldValue){
if(newValue>=18){
this.message = '已成年'
}else{
this.message='未成年'
}
}
}
})
</script>
</body>
</html>
vue里面的方法
methods 用户自定义方法
computed 计算属性
watch 侦听器
格式化时间代码
return moment(this.create_time).format('YYYY-MM-DD HH:mm:ss')
侦听事件
watch:{
age:function(newValue, oldValue){
if(newValue>=18){
this.message = '已成年'
}else{
this.message='未成年'
}
}
}
vue 中的计算属性是不支持异步操作的,只能计算一些同步的值,但是可以使用 vue-async-computed 插件实现这一点
4.vue编写表格的增删改查
数据的绑定
<button v-on:click="add">添加</button>
<table>
<thead>
<tr>
<th>编号</th>
<th>标题</th>
<th>创建时间</th>
</tr>
</thead>
<tbody>
<tr v-for="item in blogList">
<td>{{item.id}}</td>
<td>{{item.title}}</td>
<td>{{formatTime(item.create_time)}}</td>
<td>
<button @click="edite(item.id)">编辑</button>
<button @click="handleDel(item.id)">删除</button>
</td>
</tr>
</tbody>
</table>
弹出框的隐藏和展示
<div class="popular" v-show="add_isActive">
<div><label for="title">博客标题:</label><input id="title" type="text" v-model="title"></div>
<button @click="handleAdd">Submit</button>
</div>
//当点击的时候弹出添加的弹出框
add: function () {
this.add_isActive = true
},
// 关闭新增博客层
close: function (event) {
if (event.target.id == 'app') {
this.add_isActive = false
this.edite_isActive = false
}
},
博客的添加
<div class="popular" v-show="add_isActive">
<div><label for="title">博客标题:</label><input id="title" type="text" v-model="title"></div>
<button @click="handleAdd">Submit</button>
</div>
// 新增数据
handleAdd: function () {
this.maxId++
let obj = { id: this.maxId, title: this.title, create_time: Date.now() }
this.blogList.push(obj)
this.add_isActive = false
this.title = ''
},
博客的编辑
<div class="popular" v-show="edite_isActive">
<div><label for="title">更新博客:</label><input id="title" type="text" v-model="title"></div>
<button @click="handleEdite">Submit</button>
</div>
// 显示待编辑的弹框
edite: function (id) {
this.editeId = id
this.edite_isActive = true
let obj = this.blogList.find(item => {
return item.id == id
})
this.title = obj.title
},
//更新数据编辑数据
handleEdite: function(){
this.blogList.forEach(item =>{
if(item.id == this.editeId){
item.title = this.title
}
})
this.edite_isActive=false
this.title=''
},
博客的删除
<button @click="handleDel(item.id)">删除</button>
handleDel: function(id){
function ff(arg){
return arg.id == id
}
let index = this.blogList.findIndex(f1)
this.blogList.splice(index,1)
}
知识点
v-for 列表渲染
v-show 用于列表的展示和隐藏
组件@click操作,那么你需要写@click进行点击操作。
时间处理函数
formatTime: function (arg) {
return moment(arg).format('YYYY-MM-DD HH:mm:ss')
},
<script src="./moment.min.js"></script>
this和event.target的区别
js中事件是会冒泡的,所以this是可以变化的,但event.target不会变化,它永远是直接接受事件的目标DOM元素;
findIndex()
作用:从数组中查找第一个符合条件的元素,然后返回该元素的索引,如果找到第一个符合条件的元素就不再继续往下找,如果找不到,则返回-1。
splice(index,num) 作用一 删除 返回【当前】被删除后元素组成的新数组
find 获取当前id的索引值
5.vue组件
5.1 组件的创建和使用
1.创建组件
//component 组件名称
//template 组件的DOM结构
vue.component('ms-button',{
template:'<button>按钮</button>'
})
2.在模块当中如何使用组件
<div id="app">
<ms-button><ms-button>
</div>
5.2组件中获取data数据的值
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RD0hMv6c-1615375705803)(D:\前端分班\上课\vue的md图片\QQ截图20210304112004.png)]
5.3传递出数据
5.3.1传递静态数据
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-04EI0isd-1615375705805)(D:\前端分班\上课\vue的md图片\QQ截图20210304113239.png)]
5.3.2传递动态数据
v-bind 指令的作用是:使用v-bind传递动态数据,所以才可以传递动态数据
5.3.3遍历循环数组
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="app">
// li绑定key值为 v-for提供的index参数
// 分别控制两个变量:改变id值,对li进行排序
<ms-list v-for="(item,index) in posts" :key="index" :post="item"></ms-list>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
Vue.component('ms-list',{
props:{
post:Object //设置属性的对象类型
},
template:`<li>{{post.title}}</li>`
})
let app = new Vue({
el: '#app',
data: {
posts:[
{id:1,title:'111'},
{id:2,title:'222'},
]
},
})
</script>
</body>
</html>
5.4组件的vue实例
5.4.1组建的vue实例[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7NS2TyH9-1615375705808)(D:\前端分班\上课\vue的md图片\QQ截图20210304170710.png)]
5.4.2prop案例的介绍
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AA1xsXbp-1615375705810)(D:\前端分班\上课\vue的md图片\QQ截图20210304171107.png)]
5.4.3组件的互斥效果
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
.active {
color: red;
}
</style>
</head>
<body>
<div id="app">
<ul>
<list-item @change-active="handleActive" v-for="(item,index) in posts" :post="item" :current_id="currentId">
</list-item>
</ul>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
Vue.component('list-item', {
props: ['post', 'current_id'],
template: `<li @click="changeActive(post.id)" :class="{active:current_id==post.id}">{{current_id}}-{{post.title}}</li>`,
methods: {
changeActive: function (id) {
this.$emit('change-active', id)
}
}
})
let app = new Vue({
el: '#app',
data: {
currentId: -1,
posts: [
{ id: 1, title: '任务一' },
{ id: 2, title: '任务二' }
]
},
methods: {
handleActive: function (id) {
this.currentId = id
}
}
})
</script>
</body>
</html>
emit: 1、父组件可以使用 props 把数据传给子组件。 2、子组件可以使用 $emit 触发父组件的自定义事件。
若你不想额外增加一个div,此时应该使用template来实现
Vue.component 将一个组件进行了全局注册,所有的 vue 实例都可以使用这个组件
3.5号知识点
findIndex知识:
methods:{
handleDel:function(id){
//findIndex是从数组当中找到符合条件的索引值
let index=this.posts.findIndex(item=>{
return item.id==id
})
console.log(index)
this.posts.splice(index,1)
}
}
emit知识:
del:function(id){
//向上面的发射一个单机事件,可以让下面的父组件监听到当前的事件
this.$emit('del-post',id)
}
prop总结:
-
js 中的变量不支持–连接符(post-title),但是可以使用驼峰写法(postTitle)或则使用_连接符(post_title)_
-
html中不区分大小写,无论html中的属性是大写还是小写还是大小写混合,最终渲染时,都会转换成小写解决方案有两种
-
props中的属性和在html中使用此属性时都是用_连接符
-
props 中定义属性时使用驼峰写法,html中使用属性时,使用–连接符,这两个属性是等价的
prop的类型:
props: {
title: String,
likes: Number,
isPublished: Boolean,
commentIds: Array,
author: Object,
callback: Function,
contactsPromise: Promise // or any other constructor
}
key的使用:
建议尽可能在使用 v-for
时提供 key
attribute,除非遍历输出的 DOM 内容非常简单,或者是刻意依赖默认行为以获取性能上的提升。
可以提升页面的加载速度。
6.路由
6.1.1组件的路由
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
a {
padding: 50px;
}
</style>
</head>
<body>
<div id="app">
<nav>
<a href="#/follow">任务一</a>
<a href="#/recommend">任务二</a>
<a href="#/hotList">任务三</a>
<a href="#/smallVideo">任务四</a>
<a href="#/success">任务五</a>
</nav>
<component :is="component_name"></component>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
//创建任务一组件 局部组件
let follow = {
template: `<h3>完成进度20</h3>`
}
let recommend = {
template: `<h3>完成进度40</h3>`
}
let hotList = {
template: `<h3>完成进度60</h3>`
}
let smallVideo = {
template: `<h3>完成进度80</h3>`
}
let success = {
template: `<h3>完成进度1000</h3>`
}
let app = new Vue({
el: '#app',
data: {
component_name:""
},
components:{
'follow':follow,
'recommend':recommend,
'hotList':hotList,
'smallVideo':smallVideo,
'success':success
}
})
window.onhashchange=function(){
let hash=window.location.hash
switch(hash){
case '#/follow':
app.component_name='follow'
break
case '#/recommend':
app.component_name='recommend'
break
case '#/hotList':
app.component_name='hotList'
break
case '#/smallVideo':
app.component_name='smallVideo'
break
case '#/success':
app.component_name='success'
break
}
}
</script>
</body>
</html>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ka4cttcX-1615375705811)(D:\前端分班\上课\vue的md图片\组件的路由案例.gif)]
6.1.2组件的嵌套局部案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
nav{
width: 500px;
margin: 10px ;
}
nav ul{
list-style: none;
}
</style>
</head>
<body>
<div id="app">
<ms-list :data="posts"></ms-list>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
Vue.component('ms-list',{
props:['data'],
template:` <nav>
<ul>
<el-ms-list v-for="item in data" :title="item.title"></el-ms-list>
</ul>
</nav>`
})
Vue.component('el-ms-list',{
props:['title'],
template:`<li><a href="">{{title}}<a></li>`
})
let app = new Vue({
el: '#app',
data: {
posts:[
{id:1,title:'234123'},
{id:2,title:'234123'},
{id:3,title:'234123'}
]
},
})
</script>
</body>
</html>
6.1.3嵌套案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
nav{
width: 1200px;
margin: 10px ;
}
nav ul li{
list-style: none;
float: left;
}a{
text-decoration: none;
}
img{
width: 200px;
height: 150px;
padding-left: 30px;
}span{
float: left;
margin-top: 30px;
padding-left: 5px;
}h3{
font-size: 17px;
padding-left: 66px;
padding-top: 10px;
}
</style>
</head>
<body>
<div id="app">
<ms-list :data="posts"></ms-list>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
Vue.component('ms-list',{
props:['data'],
template:`
<nav>
<ul>
<el-ms-list :key="item.id" v-for="item in data" :title="item.title" :shuzi="item.shuzi" :author="item.author" :src="item.src"></el-ms-list>
</ul>
</nav>`
})
Vue.component('el-ms-list',{
props:['src','title','shuzi','author'],
template:`
<li><img :src="src" alt=""></img>
<div class="box">
<a href="">{{title}}</a>
<span>{{shuzi}}</span>
<h3>{{author}}</h3>
</div>
</li>
`
})
let app = new Vue({
el: '#app',
data: {
posts:[
{id:1, src:'1.jfif', title:'中国数字化营销大会暨颁........',shuzi:'453',author:'cson直播大本营'},
{id:2, src:'2.jfif', title:'黄东旭张文博使用BPF........',shuzi:'34',author:'homeofkernel'},
{id:3, src:'3.jfif', title:'每周训练5小时,自信从........',shuzi:'34',author:'CSDN资讯'},
{id:4, src:'4.jfif', title:'《大咖来了》女神节特辑........',shuzi:'243',author:'CSDN资讯'},
{id:5, src:'5.jfif', title:'数据处理:深度解析并演........',shuzi:'45',author:'CSDN资讯'},
{id:6, src:'6.png', title:'黑客入门必去的五个学习...........',shuzi:'32',author:'程序媛柚柚'},
{id:7, src:'7.png', title:'开发一个小游戏能赚多少..........',shuzi:'23',author:'编程之力'},
{id:8, src:'8.png', title:'1看电影学编程:人理解迭...........',shuzi:'53',author:'v3u.cn'},
{id:7, src:'7.png', title:'开发一个小游戏能赚多少..........',shuzi:'23',author:'编程之力'},
{id:8, src:'8.png', title:'1看电影学编程:人理解迭...........',shuzi:'53',author:'v3u.cn'}
]
},
})
</script>
</body>
</html>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9V6KnUhs-1615375705812)(D:\前端分班\上课\vue的md图片\嵌套案例.png)]
vue路由 Vue Router
需要引入:
添加路由链接
可以使用超链接,或者使用 router-link 组件
<router-link to="/follow">关注</router-link>
添加路由填充位
<router-view></router-view>
创建组件
const follow={
template:`<p>111</p>`
}
const follow1={
template:`<p>222</p>`
}
const follow2={
template:`<p>333</p>`
}
前端工程化
1.webpack
1.1按需要导出和导入
使用 export 关键字直接放到要导出的变量或者函数前面
export let a=20
导入时
import {d} from './a.js'
- 模块中可以按需导出多个成员
- 模块中 export default 与 按需导出可以并存
1.2webpack的完整步骤
- 初始化项目 npm init -y
- 安装webpack
npm install webpack webpack-cli --save-dev
- webpack 配置
根目录下新建 webpack.config.js
module.exports={
mode:'development' // 开发模式
}
- 配置启动命令
打开 package.json ,在 scripts 属性中加入如下代码
"dev":"webpack"
- 打包
在终端中输入:
npm run dev
- 运行
在 index.html 中,引入 main.js,再次运行 index.html 即可成功
1.3重新配置入口文件和出口文件
const path=require('path')
module.exports = {
mode:'development',
//入口文件
entry:path.resolve(__dirname,'index.js'),
output:{
path:path.resolve(__dirname,'opload'),
filename:'mainyao.js',
},
};
1.4自动打包
安装
npm install --save-dev webpack-dev-server
修改 pacjkage.json 中的启动命令
"dev":"webpack serve --open"
说明:在 v5 中使用上面的 webpacl serve 命令
但是在v5之前版本中使用 webpack-dev-server 命令
运行
npm run dev
可见其在项目跟目录,所以要修改 src/index.html 的引入路径为
<script src="/mainyao.js"></script>
1.5生成预览页面
安装
npm install --save-dev html-webpack-plugin
在 webpack.config.js 中编写代码
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nUxFgzg8-1615375705814)(D:\前端分班\上课\vue的md图片\3.9照片1.png)]
重新运行 npm run dev后
再次访问:http://localhost:8080/,就会运行index.html
1.6 处理css文件
src 目录下新建 css 目录,新建 index.css
编写样式
* {
margin: 0;
padding: 0;
}
ul {
list-style-type: none;
}
li {
line-height: 45px;
}
index.js 中导入 index.css
安装 loader
npm install --save-dev css-loader style-loader
配置 webpack.config.js
1.7处理less文件
安装
npm install less-loader less -D
rules 中增加一条规则
css 目录中新建 a.less
body {
background-color: #ccc;
ul {
list-style-type: none;
li {
line-height: 35px;
}
}
}
index.js 中引入 a.less
1.7处理图片
url-loader
url-loader
功能类似于 file-loader
, 但是在文件大小(单位为字节)低于指定的限制时,可以返回一个 DataURL。
简单来说,就是当图片尺寸<指定的尺寸时,返回的是 base64 格式,否则返回的还是一个图片路劲
安装
npm i url-loader url-loader -D
配置 webpack.config.js
{test:/\.png$/,use:[{
loader:'url-loader',
options:{
limit:200000
}
}]
},
a.cs 中编写代码,为 body 设置背景图片
body {
background-image: url(../images/11.png);
}
重新运行
npm run dev