• Vue生命期钩子,Vue组件,Vue-Cli创建项目


    Vue生命期钩子

    vue 的8个生命周期钩子函数



         钩子函数                                      描述 
     beforeCreate 创建Vue示例之前调用 
     created  创建Vue实例成功后调用(可以在此处发送异步请求后端数据)
     beforeMount  渲染DOM之前调用
     mounted  渲染DOM之后调用
     beforeUpdate  重新渲染之前调用(数据更新等操作时,控制DOM重新渲染)
     updated  重新渲染完成之后调用
     beforeDestroy  销毁之前调用
     destroyed  销毁之后调用
     

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
        <script src="./js/vue.js"></script></head>
    <body><div class="container-fluid">
        <div class="row">
            <div class="col-md-6 col-md-offset-3" style="margin-top: 20px"><div id="app">
                    {{name}}
                </div>
            </div>
        </div>
    </div></body><script>var vm = new Vue({
            el: '#app',
            data: {
                name:'lqz'
            },
            methods: {},
    ​
            beforeCreate() {
                console.log('当前状态:beforeCreate')
    ​
            },
            created() {
                console.log('当前状态:created')
    ​
            },
            beforeMount() {
                console.log('当前状态:beforeMount')
    ​
            },
            mounted() {
                console.log('当前状态:mounted')
    ​
              //用的最多,向后端加载数据,创建定时器等
                //挂在,三秒后执行一个任务
    // setTimeout(()=> {
                //     console.log('lqz is nb')
                // },3000)
                this.t = setInterval(function () {
                    console.log('lqz is nb')
                }, 3000)
    ​
            },
            beforeUpdate() {
                console.log('当前状态:beforeUpdate')
    ​
            },
            updated() {
                console.log('当前状态:updated')
    ​
            },
            beforeDestroy() {
                console.log('当前状态:beforeDestroy')
    ​
            },
            destroyed() {
                console.log('当前状态:destroyed')
                clearInterval(this.t)
                this.t = null
                console.log('destoryed')
    ​
            },
    ​
        })
    </script></html>
    View Code

    组件

    jquery-ajax、fetch和axios

    jquery的ajax(不推荐使用)
    fetch(不是所有浏览器都支持,谷歌浏览器支持)
    axios(基本都是用它)

    前后端交互之jquery-ajax

    前端

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
        <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
        <script src="./js/vue.js"></script></head>
    <body><div class="container-fluid">
        <div class="row">
            <div class="col-md-6 col-md-offset-3" style="margin-top: 20px"><div id="app">
                    <button @click="handle_load">点我加载数据</button>
                    <hr>
                    拿回来的数据是:{{name}}
                </div>
            </div>
        </div>
    </div></body><script>var vm = new Vue({
            el: '#app',
            data: {
                name:'lqz'
            },
            methods: {
                handle_load(){
                    $.ajax({
                        url:'http://127.0.0.1:5000/',
                        type:'get',
                        success:data=> {
                            this.name=data
                        }
                    })
    ​
                }
            },
    ​
    ​
            mounted() {
                //跟后端交互,写在这,而不要使用button
                console.log('当前状态:mounted')
                this.handle_load()
    ​
    ​
            },
    ​
    ​
        })
    </script></html>

    后端

    from flask import Flask, make_response
    ​
    app = Flask(__name__)
    ​
    ​
    @app.route('/')
    def index():
        res = make_response('hello world')
        # 运行所有域向我发请求(解决跨域问题)
        res.headers['Access-Control-Allow-Origin']='*'
        return res
    ​
    ​
    if __name__ == '__main__':
        app.run()
     

    前后端交互之fetch

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
        <script src="./js/vue.js"></script></head>
    <body><div class="container-fluid">
        <div class="row">
            <div class="col-md-6 col-md-offset-3" style="margin-top: 20px"><div id="app">
                    <ul>
                        <li v-for="film in films_list">
                            <img :src="film.poster" alt="" width="60px" height="80px">
                            <span>{{film.name}}</span>
                            <hr>
                        </li>
                    </ul>
                </div>
            </div>
        </div>
    </div></body><script>var vm = new Vue({
            el: '#app',
            data: {
                films_list: []
            },
            methods: {
                handle_load() {
                    fetch('http://127.0.0.1:5000/home').then(data => data.json()).then(data => {
                        console.log(data)
                        if (data.status == 0) {
                            this.films_list = data.data.films
                        } else {
                            alert('加载出错')
                        }
    ​
    ​
                    })
    ​
                }
            },
    ​
    ​
            mounted() {
                //跟后端交互,写在这,而不要使用button
                console.log('当前状态:mounted')
                this.handle_load()
    ​
    ​
            },
    ​
    ​
        })
    </script></html>

    前后端交互之axios

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
        <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
        <script src="./js/vue.js"></script></head>
    <body><div class="container-fluid">
        <div class="row">
            <div class="col-md-6 col-md-offset-3" style="margin-top: 20px"><div id="app">
                    <ul>
                        <li v-for="film in films_list">
                            <img :src="film.poster" alt="" width="60px" height="80px">
                            <span>{{film.name}}</span>
                            <hr>
                        </li>
                    </ul>
                </div>
            </div>
        </div>
    </div></body><script>var vm = new Vue({
            el: '#app',
            data: {
                films_list: []
            },
            methods: {
                handle_load() {
                    axios.get('http://127.0.0.1:5000/home').then(data => {
                        //data.data才是后端响应的数据
                        console.log(data)
                        if (data.data.status == 0) {
                            this.films_list = data.data.data.films
                        } else {
                            alert('加载出错')
                        }
                    })
    ​
                }
            },
    ​
    ​
            mounted() {
                //跟后端交互,写在这,而不要使用button
                console.log('当前状态:mounted')
                this.handle_load()
    ​
    ​
            },
    ​
    ​
        })
    </script></html>

    计算属性

    计算属性的特点:只要返回的结果没有发生变化,那么计算属性就只会被执行一次

    计算属性的应用场景:由于计算属性会将返回的结果缓存起来,所以如果返回的数据不经常发生变化
    那么使用计算属性的性能就会比使用函数的性能高

    把输入的首字母大写

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
        <script src="./js/vue.js"></script></head>
    <body><div class="container-fluid">
        <div class="row">
            <div class="col-md-6 col-md-offset-3" style="margin-top: 20px">
                <!-- 这个就是MVVM中的 View -->
                <div id="app">
                    {{name}}
    ​
                    <input type="text" v-model="s">
                    <hr>
        <!-- s.slice 从第0个位置截到第一个位置转成大写,只是第一个字母。还得把后面的字母加上,从第一个截到最后拼上-->
                    输入的值是:{{s.slice(0,1).toUpperCase()+s.slice(1)}}
                    <hr>
        <!-- 写一个函数,跟上面一样,缺点:只要页面有值变化,它会触发update的执行,
        不管是函数还是其它还会再执行一次 -->
                    输入的值是:{{to_upper()}}
                    <hr>
                    输入的值是(计算属性) :{{str_s}}
                </div>
            </div>
        </div>
    </div>
    </body>
    <script>
         // 这个就是MVVM中的View Model
        var vm = new Vue({
            el: '#app',
             // 这个就是MVVM中的Model
            data: {
                s:'',
                name:''
            },
            // 专门用于定义计算属性的
            computed:{
                str_s(){
                    // 计算属性的特点:只要返回的结果没有发生变化,那么计算属性就只会被执行一次
                    //只有该方法中使用的值发生变化,才会重新计算
                    console.log('计算属性的方法,我执行了')
                    return this.s.slice(0,1).toUpperCase()+this.s.slice(1)
                }
            },
             //专门用于存储监听事件回调函数
            methods:{  // 函数的特点:每次调用都会执行
                to_upper(){
                    console.log('我执行了')
                    return this.s.slice(0,1).toUpperCase()+this.s.slice(1)
                }
            },
        })
    </script></html>

    重写过滤案例

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
        <script src="./js/vue.js"></script></head>
    <body><div class="container-fluid">
        <div class="row">
            <div class="col-md-6 col-md-offset-3" style="margin-top: 20px"><div id="app">
                    <p><input type="text" v-model="mytext" @input="handleChange"></p>
                    <ul>
                        <li v-for="data in newdatalist">{{data}}</li>
                    </ul>
                </div>
            </div>
        </div>
    </div></body><script>var vm = new Vue({
            el: '#app',
            data: {
                mytext: '',
                datalist: ['aaa', 'abc', 'abcde', 'abcdef', 'bbb', 'bac'],
            },
    ​
            computed: {
                newdatalist() {
                    var newlist = this.datalist.filter(item => {
                        return item.indexOf(this.mytext) > -1
                    })
                    return newlist
                }
    ​
            },
    ​
    ​
        })
    </script></html>

    虚拟dom优化问题

    1 v-for循环的时候,经常看到有个自定义属性 key

    2 key是一个唯一值,为了虚拟dom替换的时候,效率高

    组件化开发介绍

    Vue的两大核心:1.数据驱动界面改变,2.组件化

    什么是组件?什么是组件化?
        在前端开发中组件就是把一个很大的界面拆分为多个小的界面,每一个小的界面就是一个组件
        将大界面拆分成小界面就是组件化
    ​
    组件化的好处:
        可以简化Vue实例的代码
        可以提高复用性
        -例如:有一个轮播,可以在很多页面中使用,一个轮播有js,css,html
        -组件把js,css,html放到一起,有逻辑,有样式,有html
        
    Vue中如何创建组件?
        创建组件构造器
        注册已经创建好的组件
        使用注册好的组件
        
    全局组件:整个项目中都能使用的组件
    局部组件:只能再局部使用  

    注册全局组件

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="./js/vue.js"></script></head>
    <body><div id="app">
        <myhead></myhead>
        <hr>
        <myhead></myhead>
    </div>
    </body><script>
    ​
        Vue.component('myhead', {
            template: `
                <div>
                        <button @click="handleClick">我是个按钮:点我看美女</button>
                        <button>我又是一个按钮</button>
                </div>
            `,
            methods: {
                handleClick(){
                    alert('美女')
                }
            },
        })
    ​
        var vm = new Vue({
            el: '#app',
            data: {},
            methods: {
            }
        })
    </script>
    </html>

    注册局部组件


    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="./js/vue.js"></script>
    </head>
    <body>
    <div id="app">
        <myhead></myhead>
        <hr>
    </div>
    </body>
    <script>
        Vue.component('myhead', {
            template: `
                <div>
                    <button @click="handleClick">我是个按钮:点我看美女</button>
                    <button>我又是一个按钮--{{name}}</button>
                    {{show}}
                    <hr>
                    看到美女了
                    <child></child>
                </div>
    ​
            `,
            methods: {
                handleClick() {
                    alert('美女')
                }
            },
            components:{
                child:{
                    template:`
                    <div>
                        <img src="./img/1.jpg" alt="" v-show="show" height="60px" width="60px">
                        <button @click="handleRemove">点我图片消失</button>
                    </div>
                    `,
                    data(){
                        return {
                            show:true
                        }
                    },
                    methods:{
                        handleRemove(){
                            this.show=!this.show
                        }
                    }
                }
            },
            data(){
                return {name:'lqz'}
            },
        })
    ​
    ​
        var vm = new Vue({
            el: '#app',
            data: {},
            methods: {}
        })
    </script></html> 

    组件间通信

    1 父子组件传值 (props down, events up)
    2 父传子之属性验证props:{name:Number}Number,String,Boolean,Array,Object,Function,null(不限制类型)
    3 事件机制a.使用 $on(eventName) 监听事件b.使用 $emit(eventName) 触发事件
    4 Ref<input ref="mytext"/>  this.$refs.mytext
    5 事件总线var bus = new Vue();* mounted生命周期中进行监听

    父传子

    在子组件上新增属性
    
    <myhead myname="lqz"></myhead>
    
    在子组件中:定义,myname要跟新增的属性名一致
    
    props:['myname']
    
    在子组件中就可以使用myname变量了,从父组件传入的
    
    注意加不加:的区别
    
    <myhead :myname="lqz"></myhead>
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="./js/vue.js"></script></head>
    <body><div id="app">
    <!--    <myhead myname="lqz"></myhead>--><!--    <hr>-->
    <!--    <myhead :myname="name"></myhead>--><hr>
        <myhead :mybool="false"></myhead>
    ​
    ​
    </div>
    </body><script>
    ​
    ​
        Vue.component('myhead', {
            template: `
                <div>
                    <button>我是按钮</button>
                    我的名字是:
                    <br>
                    传入的布尔值是:{{typeof mybool}}
                </div>
    ​
            `,
    ​
            // props:['myname','mybool']
            //类型限制
            props: {
                mybool: Boolean,
            }
    ​
        })
    ​
    ​
        var vm = new Vue({
            el: '#app',
            data: {
                name: '迪丽热巴'
            },
    ​
    ​
        })
    </script></html>

    通过事件实现子传父

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="./js/vue.js"></script></head>
    <body><div id="app"><myhead @myevent="handleParent" @egon="handleEgon"></myhead>
    ​
    ​
    </div>
    </body><script>
    ​
    ​
        Vue.component('myhead', {
            template: `
                <div>
                    <button @click="handleChild">我是按钮</button>
                </div>
    ​
            `,
            data(){
                return {
                    n:100,
                    m:200
                }
            },
            methods:{
                handleChild(){
                    console.log('子组件的按钮被点击了')
                    // this.$emit('myevent') //触发自定义的事件执行(触发myevent的执行)
                    // this.$emit('myevent',this.n,this.m) //触发自定义的事件执行(触发myevent的执行)
                    // this.$emit('egon')
                }
            },
            mounted(){
                 this.$emit('egon')
            }
    ​
    ​
        })
    ​
    ​
        var vm = new Vue({
            el: '#app',
            data: {
                n:0,
                m:0,
            },
            methods:{
                handleParent(n,m){
                    console.log('自定义的事件执行了')
                    this.n=n
                    this.m=m
                    console.log(n)
                    console.log(m)
    ​
                },
                handleEgon(){
                    console.log('egon被打了')
                }
            }
    ​
    ​
        })
    </script></html>

    通过ref实现父子通信

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="./js/vue.js"></script>
    </head>
    <body><div id="app">
        <input type="text" placeholder="我是父组件的1" ref="myinput">
        <input type="text" placeholder="我是父组件的2" ref="myinput2">
        <input type="password" placeholder="我是父组件的3" ref="myinput3">
        <button @click="handleParentButton">点我执行一个函数</button>
        <hr>
        <myhead ref="mychild"></myhead>
    </div>
    </body><script>
        Vue.component('myhead', {
            template: `
                <div>
                    <button>我是按钮</button>
                </div>
            `,
            data(){
                return {
                    name:'lqz'
                }
            },
            methods:{
                tgc(name){
                    this.name=name
                    alert(name)               
                }
            },
        })
        
        var vm = new Vue({
            el: '#app',
            data: {
    ​
            },
            methods:{
                handleParentButton(){
                    console.log('父组件的button按钮被点击了')
                    //
                    // console.log(this.$refs.myinput3.value)
                    // console.log(this.$refs.myinput3.type)
                    console.log(this.$refs.mychild.tgc('lqz is big'))
                }
            }
        })
        //ref属性如果加在普通标签上,通过this.$refs.myinput,取到的就是这个标签
        //ref属性如果加在组件上,通过this.$refs.mychild,取到的就是这个组件,拿到组件的值,拿到组件的方法,并且可以执行
    </script></html>

    通过事件总线实现组件通信

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="./js/vue.js"></script></head>
    <body><div id="app">
        <myhead></myhead>
        <hr>
        <child1></child1></div>
    </body><script>// 定义一个事件总线
        var bus = new Vue() //new一个vue的实例,就是中央事件总线
    ​
    ​
        Vue.component('myhead', {
            template: `
                <div>
                    <button>我是按钮</button>
                    来自另一个组件的数据:  <span v-text="recv"></span>
                </div>
    ​
            `,
            mounted() {
                //生命周期,当前组件dom创建完后悔执行
                console.log('当前组件dom创建完后悔执行')
                //订阅消息
                bus.$on('suibian', (item) => {
                    console.log('收到了', item)
                    this.recv=item
    ​
                })
            },
            data(){
                return {
                    recv:''
                }
            }
    ​
    ​
        })
    ​
        Vue.component('child1', {
            template: `
                <div>
                    <input type="text" v-model="input_1">
                    <button @click="handleClick">点我</button>
                </div>`,
            methods: {
                handleClick() {
                    bus.$emit('suibian', this.input_1) //发布消息,名字跟订阅消息名一致
                }
            },
            data(){
                return {
                    input_1:''
                }
            }
        })
    ​
    ​
        var vm = new Vue({
            el: '#app',
            data: {},
    ​
    ​
        })
        //ref属性如果加在普通标签上,通过this.$refs.myinput,取到的就是这个标签
        //ref属性如果加在组件上,通过this.$refs.mychild,取到的就是这个组件,拿到组件的值,拿到组件的方法,并且可以执行
    </script></html>

    动态组件

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="./js/vue.js"></script></head>
    <body><div id="app">
        <button @click="who='myhead1'">显示组件1</button>
        <button @click="who='myhead2'">显示组件2</button>
        <button @click="who='myhead3'">显示组件3</button><keep-alive>
            <component :is="who"></component>
        </keep-alive></div>
    </body><script>
    ​
    ​
        Vue.component('myhead1', {
            template: `
                <div>
                    <button> myhead1的按钮</button>
                    <div>
                    我是组件1111的样子
                    </div>
                </div>
    ​
            `,
    ​
        })
        Vue.component('myhead2', {
            template: `
                <div>
                    <button >myhead2的按钮</button>
                     <div>
                    我是组件222的样子
                    <input type="text">
                    </div>
                </div>
    ​
            `,
    ​
        })
        Vue.component('myhead3', {
            template: `
                <div>
                    <button >myhead3的按钮</button>
                               <div>
                    我是组件333的样子
                    <button>点我</button>
                    <hr>
                    <span>xxx</span>
                    </div>
                </div>
    ​
            `,
    ​
        })
    ​
    ​
        var vm = new Vue({
            el: '#app',
            data: {
                who: 'myhead1'
            },
    ​
    ​
        })
        //ref属性如果加在普通标签上,通过this.$refs.myinput,取到的就是这个标签
        //ref属性如果加在组件上,通过this.$refs.mychild,取到的就是这个组件,拿到组件的值,拿到组件的方法,并且可以执行
    </script></html>

     

    Vue-cli创建项目

    1 安装node环境:最新是14
        - 跟python比较
        - node    python
        - npm     pip3
        - 安装cnpm,淘宝做的npm,以后使用npm的地方,都是用cnpm
    2 安装cli脚手架
        -cnpm install -g @vue/cli
        
    3 创建项目
        vue create my-project # 命令行
        # OR
        vue ui  #图形化界面
        

     目录介绍

    image-20210427225921806

    ├─ node_moduls:项目依赖,当前项目的所有第三方包,(上传项目的时候不需要用:把项目给别人,这个文件夹删掉)
           npm install  就会又把依赖重新装上
           pi3 install -r request.txt     
    ├─ public文件夹:(你不用动)
        ├─ favicon.ico  网站图标
        └─ index.html  项目入口页面,单页面开发(整个vue项目就这一个页面,一般不会动它)  
    ├─ src文件夹:代码文件夹(经常动,书写你的所有代码)
        ├─ assets文件夹 :存储项目中自己的一些静态资源,图片,js,css
        ├─ components文件夹:存储项目中的自定义组件(组件,小组件,公共组件)
        ├─ router文件夹:存储VueRouter路由相关文件(装了Router才有,否则没有,页面跳转)
        ├─ store文件夹:存储Vuex相关文件(vuex才有的,状态管理器)
        ├─ views文件夹:存储项目中的自定义组件(大组件,页面级组件,路由级别组件)
        ├─ App.vue:根组件
        └─ main.js:整个项目的入口js
    ├─ .gitignore  # git的忽略文件,讲到git才知道
    ├─ babel.config.js # 不用动
    ├─ package.json     #依赖的模块
    ├─ package-lock.json #依赖的模块
    └─ README.md      # 介绍
        

    项目组件介绍(重点)

    每一个组件都有三部分
    # html内容写在这
    // template 用于编写当前组件的结构代码的
    <template>
        <div class="home"></div>
    </template>
    ​
    ​
    # js内容
    // script 用于编写当前组件的业务代码的
    <script>
        export default {
          name: 'Home',
          data(){
              return {
                 a:'asdfasdfasdfasdfasd'
              }
    ​
          },
    ​
        }
    </script>
    ​
    # style的内容
    // style 用于编写当前组件额样式代码的
    <style>
        
    </style>

    把vue项目编译成纯html,css,js

    webpack:模块化
    打包:npm run build  
    在项目路径下有个dist文件夹:html,css,js
    从来就没有正确的选择,我们只不过是要努力奋斗,使当初的选择变得正确。
  • 相关阅读:
    测试office2010发布cnblog文章
    【转载.SQL注入原理】SQL注入漏洞全接触入门篇
    【转载.SQL注入原理】SQL Server应用程序中的高级SQL注入
    【转载.SQL注入防范】SQL注入技术和跨站脚本攻击的检测
    获取目录对话框
    关于CFormView的滚动条和凹凸解决
    转——windows live writer向cnblog发布文章设置
    【转载.SQL注入原理】SQL注入法攻击一日通
    windows live wirter向cnblog发布日志测试
    android模拟器怎么与PC通信
  • 原文地址:https://www.cnblogs.com/gfeng/p/14747759.html
Copyright © 2020-2023  润新知