vue之vue的生命周期、swiper、自定义组件的封装、自定义指令、过滤器、单文件组件及vue-cli

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>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值