文章目录
1、vue的生命周期
表示一个vue实例从创建到销毁的这个过程,将这个过程的一些时间节点赋予了对应的钩子函数
钩子函数: 满足特点条件被回调的方法
1.1、8个生命周期函数
1、mounted使用频率最高: 向后端发送请求,定时器初始化
2、destroyed: 组件销毁 ---> 组件写一个定时器 ---> 组件销毁 ---> 定时器清除
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script src="js/vue.js"></script>
<div id="box">
<child v-if="isShow"></child>
{{name}}
</div>
<script>
// 定义一个全局组件
Vue.component('child', {
template:
`<div>
<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('定时器触发了');
}, 3000)
},
beforeUpdate() {
console.log('beforeUpdate');
},
updated() {
console.log('Update');
},
beforeDestroy() {
console.log('beforeDestroy');
},
destroyed() {
console.log('destroy');
// 组件销毁,清理定时器
clearInterval(this.t);
this.t = null;
}
});
var vm = new Vue({
el: '#box',
data: {
name: 'allen',
isShow: true,
},
methods: {},
beforeUpdate() {
console.log('根组件beforeUpdate触发了');
},
updated() {
console.log('根组件Update触发了');
},
})
</script>
</body>
</html>
补充(定时任务和延迟任务)
<script>
// 延迟3s执行
setTimeout(function () {
alert(33333)
},3000)
// 每隔3s执行
setInterval(function () {
alert(444)
},3000)
</script>
2、swiper
Swiper 使用方法(官网):https://www.swiper.com.cn/usage/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="https://unpkg.com/swiper/swiper-bundle.min.css">
<script src="https://unpkg.com/swiper/swiper-bundle.min.js"></script>
<style>
.swiper-container {
width: 600px;
height: 300px;
}
</style>
</head>
<body>
<script src="js/vue.js"></script>
<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 class="swiper-scrollbar"></div>-->
</div>
</div>
<script>
var vm = new Vue({
el: '#box',
data: {
datalist: [],
},
methods: {},
mounted() {
// 模拟网络延迟3秒获取轮播图数据
setTimeout(() => {
// this指的是function这个函数
// 使用了箭头函数以后,this指的是上一层
this.datalist = [
'图片路径1',
'图片路径2',
'图片路径3',
];
}, 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',
},
// 如果需要滚动条
// scrollbar: {
// el: '.swiper-scrollbar',
// },
})
},
})
</script>
</body>
</html>
3、自定义组件的封装
将swiper封装成组件使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="https://unpkg.com/swiper/swiper-bundle.min.css">
<script src="https://unpkg.com/swiper/swiper-bundle.min.js"></script>
<style>
.swiper-container {
width: 100%;
height: 300px;
}
</style>
</head>
<body>
<script src="js/vue.js"></script>
<div id="box">
<swiper :key="datalist.length">
<div class="swiper-wrapper">
<div class="swiper-slide" v-for="data in datalist">
<img :src="data" alt="">
</div>
</div>
</swiper>
<hr>
<hr>
<hr>
<swiper :key="datalist2.length">
<div class="swiper-wrapper">
<div class="swiper-slide" v-for="data in datalist2">
<img :src="data" alt="">
</div>
</div>
</swiper>
</div>
<script>
// 自定义组件
Vue.component('swiper', {
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',
},
// 如果需要滚动条
// scrollbar: {
// el: '.swiper-scrollbar',
// },
})
}
});
var vm = new Vue({
el: '#box',
data: {
datalist: [],
datalist2: [],
},
mounted() {
// 模拟网络延迟3秒获取轮播图数据
setTimeout(() => {
// this指的是function这个函数
// 使用了箭头函数以后,this指的是上一层
this.datalist = [
'图片路径1',
'图片路径2',
'图片路径3',
];
this.datalist2 = [
'图片路径4',
'图片路径5',
'图片路径6',
];
}, 3000)
},
})
</script>
</body>
</html>
4、自定义指令
4.1、定义
1、自定义指令: directives
2、钩子函数* 参数 el,binding,vnode(vnode.context)* bind,inserted,update,componentUpdated,unbind
3、函数简写
4、自定义指令-轮播
*inserted 插入最后一个元素时调用(vnode.context.datalist.length-1)
*this.$nextTick()
4.2、基本使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script src="js/vue.js"></script>
<div id="box">
<div v-mystyle>我是div</div>
</div>
<script>
// 定义自定义指令的时候不加v-前缀
Vue.directive('mystyle', {
inserted(ev) {
// 在标签上使用这个指令,就会触发inserted的执行
console.log('我执行了');
// 只要使用了我的指令,背景就变红色
console.log(ev); // <div></div>, 就是dom对象
ev.style.background = 'red';
}
});
var vm = new Vue({
el: '#box',
data: {},
})
</script>
</body>
</html>
4.3、利用自定义指令传入指定参数修改背景色
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script src="js/vue.js"></script>
<div id="box">
<!--这个是指传入字符串red-->
<div v-mystyle="'red'">我是div</div>
<!--这个是指传入js变量-->
<div v-mystyle="color">我是div</div>
</div>
<script>
// 定义自定义指令的时候不加v-前缀
// 只要使用了我的指令,背景就变成我传入的颜色
Vue.directive('mystyle', {
inserted(ev, color) {
console.log(ev);
console.log(color);
ev.style.background = color.value;
},
update(el, input) {
el.style.background = input.value;
},
});
var vm = new Vue({
el: '#box',
data: {
color: 'green',
},
})
</script>
</body>
</html>
5、过滤器
https://cn.vuejs.org/v2/guide/filters.html
ele图片转换,猫眼电影图片转换
5.1、film.json
{"coming":[{"id":1240838,"haspromotionTag":false,"img":"http://p1.meituan.net/w.h/movie/38dd31a0e1b18e1b00aeb2170c5a65b13885486.jpg","version":"","nm":"除暴","preShow":false,"sc":8.6,"globalReleased":true,"wish":76513,"star":"王千源,吴彦祖,春夏","rt":"2020-11-20","showInfo":"今天50家影院放映79场","showst":3,"wishst":0,"comingTitle":"11月20日 周五"},{"id":1228788,"haspromotionTag":false,"img":"http://p0.meituan.net/w.h/movie/b16c1c0d5ac9e743c6ffbbf7eba900522725807.jpg","version":"","nm":"一秒钟","preShow":false,"sc":8.6,"globalReleased":true,"wish":54493,"star":"张译,刘浩存,范伟","rt":"2020-11-27","showInfo":"今天11家影院放映12场","showst":3,"wishst":0,"comingTitle":"11月27日 周五"},{"id":1358968,"haspromotionTag":false,"img":"http://p0.meituan.net/w.h/movie/d33858dbfc207da3b36c0dc7fff7a8bb2028677.jpg","version":"","nm":"汪汪队立大功之超能救援","preShow":false,"sc":8.3,"globalReleased":true,"wish":24833,"star":"杨鸥,韩娇娇,李敏妍","rt":"2020-11-13","showInfo":"今天5家影院放映7场","showst":3,"wishst":0,"comingTitle":"11月13日 周五"},{"id":345809,"haspromotionTag":false,"img":"http://p1.meituan.net/w.h/moviemachine/7c4ba9633635503044a8f8fb6426aa8d416264.jpg","version":"v2d imax","nm":"隐形人","preShow":false,"sc":8.4,"globalReleased":true,"wish":9894,"star":"伊丽莎白·莫斯,奥利弗·杰森-科恩,阿尔迪斯·霍吉","rt":"2020-12-04","showInfo":"今天21家影院放映30场","showst":3,"wishst":0,"comingTitle":"12月4日 周五"},{"id":1330790,"haspromotionTag":false,"img":"http://p0.meituan.net/w.h/movie/88e54f3e670789ba1f08e48a5f1170c1188102.jpg","version":"","nm":"明天你是否依然爱我","preShow":false,"sc":0,"globalReleased":false,"wish":217668,"star":"杨颖,李鸿其,黄柏钧","rt":"2020-12-24","showInfo":"2020-12-24 下周四上映","showst":4,"wishst":0,"comingTitle":"12月24日 周四"},{"id":1277751,"haspromotionTag":false,"img":"http://p0.meituan.net/w.h/movie/303c2e671cc4df875c151d688ecbd8962085989.jpg","version":"v2d imax","nm":"赤狐书生","preShow":false,"sc":7.7,"globalReleased":true,"wish":177525,"star":"陈立农,李现,哈妮克孜","rt":"2020-12-04","showInfo":"今天26家影院放映43场","showst":3,"wishst":0,"comingTitle":"12月4日 周五"},{"id":1225578,"haspromotionTag":false,"img":"http://p0.meituan.net/w.h/moviemachine/cf7d6942f2aa9189cce20519b490b6b1879487.jpg","version":"","nm":"野性的呼唤","preShow":false,"sc":9.2,"globalReleased":true,"wish":14703,"star":"哈里森·福特,丹·史蒂文斯,凯伦·吉兰","rt":"2020-11-13","showInfo":"今天暂无场次","showst":3,"wishst":0,"comingTitle":"11月13日 周五"},{"id":1302281,"haspromotionTag":false,"img":"http://p0.meituan.net/w.h/moviemachine/1d2b4985d0187b437d41a73994ba2e191607376.jpg","version":"","nm":"奇妙王国之魔法奇缘","preShow":true,"sc":0,"globalReleased":false,"wish":20308,"star":"卢瑶,张洋,陈新玥","rt":"2020-12-26","showInfo":"2020-12-26 下周六上映","showst":4,"wishst":0,"comingTitle":"12月26日 周六"},{"id":1301902,"haspromotionTag":false,"img":"http://p0.meituan.net/w.h/movie/f686425a1ad1f502254abef593d508bf428685.jpg","version":"","nm":"沉默东京","preShow":false,"sc":5.8,"globalReleased":true,"wish":52,"star":"佐藤浩市,石田百合子,西岛秀俊","rt":"2020-12-04","showInfo":"今天暂无场次","showst":3,"wishst":0,"comingTitle":""},{"id":1286015,"haspromotionTag":false,"img":"http://p0.meituan.net/w.h/moviemachine/a0c6d6e130abe399e4cba58be2b1f871840268.jpg","version":"","nm":"宝可梦:超梦的逆袭 进化","preShow":false,"sc":8.2,"globalReleased":true,"wish":53255,"star":"松本梨香,大谷育江,市村正亲","rt":"2020-12-04","showInfo":"今天10家影院放映10场","showst":3,"wishst":0,"comingTitle":"12月4日 周五"}]}
5.2、后端代码
import json
from flask import Flask, jsonify, make_response
app = Flask(__name__)
@app.route('/')
def index():
with open('./film.json', 'rt', encoding='utf-8') as f:
dic = json.load(f)
res = jsonify(dic)
res = make_response(res)
res.headers['Access-Control-Allow-Origin'] = '*'
return res
if __name__ == '__main__':
app.run()
5.3、前端代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script src="js/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<div id="box">
<ul>
<li v-for="item in datalist">
<h2>电影名: {{item.nm}}</h2>
<p>主演:{{item.star}}</p>
<!--方式一: 利用函数-->
<p><img :src="getUrl(item.img)" alt=""></p>
<!--方式二: 利用过滤器-->
<p><img :src="item.img|repUrl" alt=""></p>
</li>
</ul>
</div>
<script>
Vue.filter('repUrl', function (url) {
return url.replace('w.h', '200.180');
});
var vm = new Vue({
el: '#box',
data: {
datalist: null,
},
methods: {
getUrl(img) {
return img.replace('w.h', '200.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>
</body>
</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
以后每个组件就是一个 xxx.vue ---> 最终形成 ---> html、css、js,并且还可以使用 webpack 构建工具
CLI 会为你搞定大多数工具的配置问题
7、vue-cli
7.1、环境搭建
安装node
官网下载安装包,傻瓜式安装:https://nodejs.org/zh-cn/
安装cnpm
npm install -g cnpm --registry=https://registry.npm.taobao.org
安装脚手架
cnpm install -g @vue/cli
清空缓存处理
npm cache clean --force
7.2、项目的创建
7.2.1、创建项目
vue create 项目名(命令行下创建项目)
要提前进入目标目录(项目应该创建在哪个目录下)
选择自定义方式创建项目,选取Router, Vuex插件
标准eslint,自动修复(ESlint+Standard config--》lint on save+Lint and fix on commit)
vue ui 使用图形界面创建项目(图形化界面,鼠标点击创建项目)
注意:
1、新建的这些项目的本质是: cli从git上给你拉了一个空项目(模板),以后再模板上继续写就可以了
2、vue: 2.x
bable: 兼容性相关(es6的语法,自动转成es5兼容浏览器)
eslint: 语法检查,代码格式化
7.2.2、启动/停止项目
npm run serve / ctrl+c
注意: 要提前进入项目根目录
7.2.3、打包项目
npm run build
注意: 要在项目根目录下进行打包操作
7.2.4、package.json
"scripts": {
"serve": "vue-cli-service serve", # 运行项目
"build": "vue-cli-service build", # 编译项目成html、css、js
"lint": "vue-cli-service lint" # 代码格式化
},
7.3、项目目录
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)
7.4、配置文件: vue.config.js
https://cli.vuejs.org/zh/config/ 配置参考
module.exports={
devServer: {
port: 8888
}
}
修改端口,可以选择
7.5、简单使用
1、在根组件App.vue中添加:
<router-link to="/course">Course</router-link>
2、在views中编写组件Course.vue:
<template>
<div>
<h2>Course课程详细列表</h2>
<Test></Test>
</div>
</template>
<script>
import Test from "../components/Test"; // 导入Test组件
export default {
name: "Course",
components: {
Test // 一定要记得注册
},
}
</script>
<style scoped>
</style>
3、Course.vue中使用到components组件中的Test,编写Test.vue:
<template>
<div>
<h2>Hi Test!!!</h2>
<form action="">
<p>用户名: <input type="text"></p>
<p>密码: <input type="password"></p>
<p><input type="submit"></p>
</form>
</div>
</template>
<script>
export default {
name: "Test",
}
</script>
<style scoped>
</style>
4、在router文件夹下index.js中添加路由:
<script>
import Course from "../views/Course";
const routes = [
{
path: '/course',
name: 'Course',
component: Course
}
]
</script>