昨日回顾
1 局部组件
-全局组件,局部组件
2 组件编写方式与Vue实例的区别
-数据不共享
-组件中的data必须是个函数
3 组件通信之父子通信
-在组件上加一个属性 mytext='值' :mytext='js变量/代码'
-props: ['mytext',]
-属性验证props: {mytext:String}
5 组件通信之子传父
-通过事件
-在子组件中绑定事件(给按钮绑定事件,在函数中执行:this.$emit('myevent',100,this.name,99))
-会触发组件上 <child @myevent='handleClick'></child>
6 组件通信之子传父案例
7 ref属性
-<div ref='xxx'></div>
-<child ref='child1'></child>
-放在标签上 this.$refs.xxx ---> dom
-放在组件上 this.$refs.child1--->组件对象--》对象中的数据,函数,可以直接使用
8 事件总线
-不同组件之间通信Vue的实例(对象) var bus=new Vue()
-两个组件通信:一个需要监听,一个需要发送
-监听
bus.$on('suibian',(item)=>{
console.log('收到了',item)
this.recv_text=item
})
-发送
bus.$emit('suibian',this.text)
9 动态组件
-在html中使用时
<keep-alive>
<component :is="who"></component>
</keep-alive>
10 插槽
-在组件child中预留插槽
<div>
<slot></slot>
<hr>
我是首页
<slot></slot>
<input type="text">
</div>
-父组件中更使用
<child> 标签,数据</child>
12 具名插槽
<div>
<slot name='a'></slot>
<hr>
我是首页
<slot name='b'></slot>
<input type="text">
</div>
-父组件中更使用
<child>
<div slot='a'>放到a中</div>
<div slot='b'>放到b中</div>
</child>
今日内容
1 生命周期
https://cn.vuejs.org/v2/guide/instance.html#%E5%AE%9E%E4%BE%8B%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E9%92%A9%E5%AD%90
1 mounted用的最多:向后端发送请求,定时器初始化
2 destroyed:组件销毁--->给组件写一个定时器-->组件销毁,定时器清除
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="js/vue.js"></script>
<title>Title</title>
</head>
<body>
<div id="box">
<child v-if="isShow"></child>
{{name}}
</div>
</body>
<script>
Vue.component('child', {
template: `
<div>我是组件的div</div>`,
data(){
return {
t:null,
}
},
beforeCreate() {
console.log('beforeCreate')
},
created() {
console.log('created')
},
beforeMount() {
console.log('beforeMount')
},
mounted() {
//用的最多,向后端加载数据,创建定时器等
console.log("页面已被vue实例渲染, data, methods已更新");
console.log('mounted')
//起一个定时器,每隔三秒,打印一行
this.t = setInterval(function () {
console.log('daada')
}, 3000)
},
beforeUpdate() {
console.log('beforeUpdate')
},
updated() {
console.log('updated')
},
beforeDestroy() {
console.log('beforeDestroy')
},
destroyed() {
//组件销毁,清理定时器
clearInterval(this.t)
this.t = null
console.log('destroyed')
},
})
var vm = new Vue({
el: '#box',
data: {
name:'lqz',
isShow:true
},
beforeUpdate() {
console.log('根的---beforeUpdate')
},
updated() {
console.log('根的---updated')
},
})
</script>
</html>
补充定时任务和延迟任务
setTimeout(function () {
alert(33333)
},3000) //延迟3s钟干什么事
setInterval(
function () {
alert(444)
},3000
)//每隔3s钟干什么事
2 swiper学习
https://www.swiper.com.cn/
vue中的钩子函数: monunted和update
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="js/vue.js"></script>
<link rel="stylesheet" href="https://unpkg.com/swiper/swiper-bundle.min.css">
<script src="https://unpkg.com/swiper/swiper-bundle.min.js"></script>
<title>Title</title>
<style>
.swiper-container {
width: 60%;
height: 600px;
}
</style>
</head>
<body>
<div id="box">
<div class="swiper-container">
<div class="swiper-wrapper">
<div class="swiper-slide" v-for="data in datalist">
<img :src="data" alt="">
</div>
</div>
<!-- 如果需要分页器 -->
<div class="swiper-pagination"></div>
<!-- 如果需要导航按钮 -->
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>
</div>
</div>
</body>
<script>
var vm = new Vue({
el: '#box',
data: {
datalist: []
},
mounted() {
//大坑
setTimeout(() => {
//this指的是function这个函数
//使用了箭头函数以后,this指的是上一层
this.datalist = ['https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1608145297276&di=dd396caeaa0bb6a2a50609a109cd3120&imgtype=0&src=http%3A%2F%2Fattachments.gfan.com%2Fforum%2Fattachments2%2Fday_110915%2F1109151356c0717d7e6a91e985.jpg', 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1608145297276&di=dd396caeaa0bb6a2a50609a109cd3120&imgtype=0&src=http%3A%2F%2Fattachments.gfan.com%2Fforum%2Fattachments2%2Fday_110915%2F1109151356c0717d7e6a91e985.jpg', 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1608145297276&di=dd396caeaa0bb6a2a50609a109cd3120&imgtype=0&src=http%3A%2F%2Fattachments.gfan.com%2Fforum%2Fattachments2%2Fday_110915%2F1109151356c0717d7e6a91e985.jpg']
}, 3000)
},
updated() {
//只要js数据发生变化,组件就会执行updated方法,轮播图又会重新创建
var mySwiper = new Swiper('.swiper-container', {
// direction: 'vertical', // 垂直切换选项
loop: true, // 循环模式选项
// 如果需要分页器
pagination: {
el: '.swiper-pagination',
},
// 如果需要前进后退按钮
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
},
})
},
})
</script>
</html>
3 自定义组件的封装
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="js/vue.js"></script>
<link rel="stylesheet" href="https://unpkg.com/swiper/swiper-bundle.min.css">
<script src="https://unpkg.com/swiper/swiper-bundle.min.js"></script>
<title>Title</title>
<style>
.swiper-container {
width: 60%;
height: 600px;
}
</style>
</head>
<body>
<div id="box">
<swipper>
<div class="swiper-wrapper">
<div class="swiper-slide" v-for="data in datalist">
<img :src="data" alt="">
</div>
</div>
</swipper>
<hr>
<hr>
<br>
<swipper :key="datalist2.length">
<div class="swiper-wrapper">
<div class="swiper-slide" v-for="data in datalist2">
{{data}}
</div>
</div>
</swipper>
</div>
</body>
<script>
Vue.component('swipper',{
template:`
<div class="swiper-container">
<slot></slot>
<div class="swiper-pagination"></div>
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>
</div>
`,
mounted() {
var mySwiper = new Swiper('.swiper-container', {
// direction: 'vertical', // 垂直切换选项
loop: true, // 循环模式选项
// 如果需要分页器
pagination: {
el: '.swiper-pagination',
},
// 如果需要前进后退按钮
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
},
})
}
// updated() {
// //每次更新都会执行该代码,会耗费资源
// var mySwiper = new Swiper('.swiper-container', {
// // direction: 'vertical', // 垂直切换选项
// loop: true, // 循环模式选项
//
// // 如果需要分页器
// pagination: {
// el: '.swiper-pagination',
// },
//
// // 如果需要前进后退按钮
// navigation: {
// nextEl: '.swiper-button-next',
// prevEl: '.swiper-button-prev',
// },
//
//
// })
// },
})
var vm = new Vue({
el: '#box',
data: {
datalist: [],
datalist2: []
},
mounted() {
//大坑
setTimeout(() => {
//this指的是function这个函数
//使用了箭头函数以后,this指的是上一层
this.datalist = ['https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1608145297276&di=dd396caeaa0bb6a2a50609a109cd3120&imgtype=0&src=http%3A%2F%2Fattachments.gfan.com%2Fforum%2Fattachments2%2Fday_110915%2F1109151356c0717d7e6a91e985.jpg', 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1608145297276&di=dd396caeaa0bb6a2a50609a109cd3120&imgtype=0&src=http%3A%2F%2Fattachments.gfan.com%2Fforum%2Fattachments2%2Fday_110915%2F1109151356c0717d7e6a91e985.jpg', 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1608145297276&di=dd396caeaa0bb6a2a50609a109cd3120&imgtype=0&src=http%3A%2F%2Fattachments.gfan.com%2Fforum%2Fattachments2%2Fday_110915%2F1109151356c0717d7e6a91e985.jpg']
this.datalist2 = ['111','222','333','5555']
}, 3000)
},
updated() {
//只要js数据发生变化,组件就会执行updated方法,轮播图又会重新创建
},
})
</script>
</html>
4 自定义指令
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="js/vue.js"></script>
<title>Title</title>
</head>
<body>
<div id="box">
<!-- <div v-mystyle> 我是div</div>-->
<!-- <p v-mystyle> 0pppp</p>-->
<!-- <p > sfasfsdafsd </p>-->
<div v-mystyle="'green'"> 我是div</div>
<div v-mystyle="'red'"> 我是div</div>
<div v-mystyle="color"> 我是div</div>
</div>
</body>
<script>
//自定义指令,不需要写v使用的时候,加上v-名字
// Vue.directive('mystyle', {
// inserted() { //在标签上使用这个指令,就会触发inserted的执行
// console.log('我执行了')
// },
// })
//只要使用了我的指令,背景就变红色
// Vue.directive('mystyle', {
// inserted(ev) { //ev就是dom对象
// ev.style.background='red'
// },
// })
//只要使用了我的指令,背景就变成我传入的颜色
Vue.directive('mystyle', {
inserted(ev, color) { //ev就是dom对象
console.log(ev)
console.log(color.value)
ev.style.background = color.value
},
update(el, input) {
el.style.background = input.value
}
})
var vm = new Vue({
el: '#box',
data: {
color: 'red'
},
})
</script>
</html>
5 过滤器
可以处理带有w.h的url,显示不同大小的图片
"img":"http://p0.meituan.net/w.h/movie/b16c1c0d5ac9e743c6ffbbf7eba900522725807.jpg",
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="js/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<title>Title</title>
</head>
<body>
<div id="box">
<ul>
<li v-for="item in datalist">
<h2>{{item.nm}}</h2>
<p>主演是:{{item.star}}</p>
<!-- <img :src="geturl(item.img)" alt="">-->
<img :src="item.img | repUrl" alt="">
</li>
</ul>
</div>
</body>
<script>
Vue.filter('repUrl', function (url) {
return url.replace('w.h', '128.180')
})
var vm = new Vue({
el: '#box',
data: {
datalist: null
},
methods: {
geturl(url) {
return url.replace('w.h', '129.180')
}
},
mounted() {
axios.get("http://127.0.0.1:5000/").then(res => {
console.log(res.data)
this.datalist = res.data.coming
}).catch(err => {
console.log(err);
})
}
})
</script>
</html>
6 单文件组件
# 原来写的组件存在的问题
全局定义 (Global definitions) 强制要求每个 component 中的命名不得重复
字符串模板 (String templates) 缺乏语法高亮,在 HTML 有多行的时候,需要用到丑陋的 \
不支持 CSS (No CSS support) 意味着当 HTML 和 JavaScript 组件化时,CSS 明显被遗漏
没有构建步骤 (No build step) 限制只能使用 HTML 和 ES5 JavaScript,而不能使用预处理器,如 Pug (formerly Jade) 和 Babel
# 以后每个组件就是一个 xx.vue-----最终----->html,css,js
并且还可以使用 webpack 构建工具
# CLI 会为你搞定大多数工具的配置问题
7 vue-cli
1 安装node(昨天装了),官网下载,一路下一步----》node,npm
2 淘宝镜像(cnpm,)npm install -g cnpm --registry=https://registry.npm.taobao.org
3 装完以后,本地就有cnpm命令,以后再装模块,就使用cnpm安装
2 cnpm install -g @vue/cli # -g 全局安装
3 装完以后就会走vue命令
4 通过vue命令创建项目
vue create 项目名(命令行下创建项目)
vue ui (图形化界面,点点点创建项目)
-点一点就会(bable,eslint)
注意:
新建的这些项目的本质是:cli从git上给你拉了一个空项目(模板),以后再模板上继续写就可以了
5 注意
vue:2.x
bable:兼容性相关(es6的语法,自动转成es5兼容浏览器)
eslint:语法检查,代码格式化
6 运行项目
npm run serve :在浏览器中访问
7 使用ide打开编写
pycharm打开
项目目录介绍
dist: 打包的项目目录(打包后会生成)
node_modules: 项目依赖(删掉,不上传git,使用npm install重新安装)
public: 共用资源
--favicon.ico
--index.html: 项目入口页面,单页面开发
src: 项目目标,书写代码的地方
-- assets:资源,静态图片
-- components:组件(swiper组件...)
-- views:视图组件(也是组件)
-- App.vue:根组件
-- main.js: 入口js
-- router.js: 路由文件
-- store.js: 状态库文件
vue.config.js: 项目配置文件(没有可以自己新建)
package.json:项目配置依赖(等同于python项目的reqirement.txt)
"scripts": {
"serve": "vue-cli-service serve", npm run serve 运行项目
"build": "vue-cli-service build", npm run build 构建项目---》html,css,js
"lint": "vue-cli-service lint" npm run lint 格式化代码
}