zoukankan      html  css  js  c++  java
  • Vue 基础

    Vue 简介

    •  Vue  是一套用于构建用户界面的渐进式框架。
    •  与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。
    •  Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。

    # react 是 facebook开发的

    # vue 是我们国人开发

    vue起步

    • 1. 引包
    • 2. 启动 new Vue(options);

    插值表达式 一定要 双括号 ->  {{ msg }}

    Vue指令

    v-text和v-html

    • {{ }} 和 v-text 的作用一样 都是插入值,直接渲染,innerText
    • v-html 既能插入值,又能插入标签 innerhtml

    v-bind绑定

    v-bind: 相当于 ' : '  简写

    v-on事件处理 监听dom
    v-on 简写  ' @ ' 

    v-on
    事件修饰符
    .once

    <!-- 点击事件将只会触发一次 -->
    <a v-on:click.once="doThis"></a>
    

      


    为什么在 HTML 中监听事件?

    你可能注意到这种事件监听的方式违背了关注点分离 (separation of concern) 这个长期以来的优良传统。

    但不必担心,因为所有的 Vue.js 事件处理方法和表达式都严格绑定在当前视图的 ViewModel 上,它不会导致任何维护上的困难。

    实际上,使用 v-on 有几个好处:

    • 1. 扫一眼 HTML 模板便能轻松定位在 JavaScript 代码里对应的方法。
    • 2. 因为你无须在 JavaScript 里手动绑定事件,你的 ViewModel 代码可以是非常纯粹的逻辑,和 DOM 完全解耦,更易于测试。
    • 3. 当一个 ViewModel 被销毁时,所有的事件处理器都会自动被删除。你无须担心如何清理它们。

    v-for列表渲染

    当 Vue 正在更新使用 v-for 渲染的元素列表时,它默认使用“就地更新”的策略。

    如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序,而是就地更新每个元素,并且确保它们在每个索引位置正确渲染。

    这个类似 Vue 1.x 的 track-by="$index"。

    这个默认的模式是高效的,但是只适用于不依赖子组件状态或临时 DOM 状态 (例如:表单输入值) 的列表渲染输出。

    为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key attribute:

    <div v-for="item in items" v-bind:key="item.id">
        <!-- 内容 -->
    </div>

    建议尽可能在使用 v-for 时提供 key attribute,除非遍历输出的 DOM 内容非常简单,或者是刻意依赖默认行为以获取性能上的提升。

    因为它是 Vue 识别节点的一个通用机制,key 并不仅与 v-for 特别关联。后面我们将在指南中看到,它还具有其它用途。

    不要使用对象或数组之类的非基本类型值作为 v-for 的 key。请用字符串或数值类型的值。

    v-model双向数据绑定

        <p>{{obj.a}} {{obj.b}}</p>
    
        <input type="text" v-model="obj.a" >
    
        data:
          obj:{
               num : 0,
               a:1,
               b:"nima"
    }


    Vue中表单输入绑定应用

    修饰符

    .lazy

    在默认情况下,v-model 在每次 input 事件触发后将输入框的值与数据进行同步 (除了上述输入法组合文字时)。你可以添加 lazy 修饰符,从而转为在 change 事件_之后_进行同步:

    <!-- 在“change”时而非“input”时更新 -->
    <input v-model.lazy="msg">

    .number

    如果想自动将用户的输入值转为数值类型,可以给 v-model 添加 number 修饰符:

    <input v-model.number="age" type="number">


    这通常很有用,因为即使在 type="number" 时,HTML 输入元素的值也总会返回字符串。如果这个值无法被 parseFloat() 解析,则会返回原始的值。


    .trim

    如果要自动过滤用户输入的首尾空白字符,可以给 v-model 添加 trim 修饰符:

    <input v-model.trim="msg">

    侦听器watch的用法

    <div id="app">
        <h3>{{abc[0].name}}</h3>
        <button @click="abc[0].name='addpapa'">changer</button>
    </div>
    <script src="./vue.js"></script> <script > var v = new Vue({ el : '#app', data:{ abc:[ {id:1, name:"123"}, {id:2, name:"bb"}, {id:3, name:"cc"}, ], } // 基本的数据类型可以使用watch直接监听,复杂数据类型object array 要深度监视 watch:{ // key是属于data 对象的属性名,value:监听后的行为,n_v:新值,o_v:旧值 'mmm':function (n_v,o_v) { console.log(n_v, o_v) }, // 深度监视 object | array 对象。数组 'abc':{ deep:'true', //这是字符串 handler:function (new_v) { console.log(new_v[0].name); } } }

    计算属性之computed getter

    计算属性之computed的setter方法

    <div id="app">
        {{content}}
    </div>
    
    <script src="./vue.js"></script>
    <script>
        //  全局的 过滤器
        Vue.filter("m_reverse",(val) => {
           console.log(this)
           return  val.split("").reverse().join("")
        })
        new Vue({
            el:'#app',
            data:{
                msg:"",
            },
            methods:{
                input_mgs:function (event) {
                    const {value} = event.target;
                    this.content = value;
                },
                click_mgs:function () {
                    console.log(this.content)
                }
            },
        })
    </script>

    过滤器  filters
    为数据添加新东西

    <div id="app">
        {{f | my_f("$")}}
        <br>
        {{ff | m_reverse}}
        <br>
        {{content}}
        <input type="text" v-model="content" @input="input_mgs">
        <button @click="click_mgs"  >changer</button>
    </div>
    
    <script src="./vue.js"></script>
    <script>
        //  全局的 过滤器
        Vue.filter("m_reverse",(val) => {
           console.log(this)
           return  val.split("").reverse().join("")
        })
        new Vue({
            el:'#app',
            data:{
                msg:"",
                f:123,
                ff:"aadddd",
            },
            methods:{
                input_mgs:function (event) {
                    const {value} = event.target;
                    this.content = value;
                },
                click_mgs:function () {
                    console.log(this.content)
                }
            },
            //   局部的 过滤器
            filters:{
                my_f:function (f,a) {
                    return a+f
                }
            },
            computed:{
                content:{
                    set:function (new_v) {
                        this.msg = new_v
                        console.log(new_v)
                    },
                    get:function () {
                        return this.msg
                    }
                },
    
            },
        })
    </script>

    音乐播放器 

    练手项目音乐播放器

    <head>
        <meta charset="UTF-8">
        <title>音乐播放器</title>
        <style>
            *{
                padding: 0;
                margin: 0;
            }
            ul {
                list-style: none;
            }
            ul li{
                margin: 30px 30px;
                padding: 20px 10px;
                border-radius: 20px;
            }
            ul li.active{
                background-color: lavender;
            }
        </style>
    </head>
    <body>
    <div id="app">
        <audio :src="get_src" controls autoplay @ended="handleend()" ></audio>
        <ul>
            <li :class="{active:index === dataindex}" v-for='(item, index) in musicData' :key="item.id" @click="handleClick(index)">
                <h3>{{item.id}} 歌名: {{item.name}} </h3>
                <p>作者: {{item.author}}</p>
            </li>
        </ul>
        <button @click="handlenext()">下一首</button>
    </div>
    
    <script src="./vue.js" ></script>
    <script >
        const musicData = [
            {
                id:0,
                name :'信仰',
                author:'hc',
                src:'./static/信仰.mp3'
        },
            {
                id:1,
                name :'春娇与志明',
                author:'hc',
                src:'./static/春娇与志明.m4a'
        },
            {
                id:2,
                name :'暗示分离',
                author:'辉哥',
                src:'./static/暗示分离.mp3'
        },
            {
                id:3,
                name :'突然的自我',
                author:'hc',
                src:'./static/突然的自我.mp3'
        },
            {
                id:4,
                name :'风吹麦浪',
                author:'hc',
                src:'./static/风吹麦浪.m4a'
        }
        ]
    
        new Vue({
            // 绑定 标签
            el: "#app",
            data:{
                musicData,
                // src:"./static/信仰.mp3",
                dataindex: 0,
            },
            // vue 的计算属性
            computed:{
                get_src(){
                    return this.musicData[this.dataindex].src
                },
            },
            methods:{
                handleClick(index){
                    // this.src = src
                    this.dataindex = index
                },
                handleend(){
                    this.handlenext();
                },
                handlenext(){
                    this.dataindex++
                    if (this.dataindex ===this.musicData.length){
                        this.dataindex = 0
                    }
                    // this.src = this.musicData[this.dataindex].src
                }
            }
        })
    </script>

    组件


    局部组件的创建和使用

    • App 组件 html+css+js
    • 1. 创建组件
    • 2. 挂载子组件
    • 建,挂,用
    • 注意: 在组件中这个data 必须是一个函数,返回一个对象
    <div id="App">
    <!--    //  3. 使用子组件-->
        <App></App>
    </div>
    
    <script src="../vue.js" ></script>
    <script>
        //  以首字母开头大写 , 第一个参数是组件名,第二个是 模板
        Vue.component("Vheader",{
            template: `
                <div>我是导航栏 </div>
            `
        })
        Vue.component('Vaside',{
            template:`
                <div> 我是侧边栏 </div>
            `
        })
        // 需要用到的局部变量,代码需要写在 创建好的子组件前面
        const Vbutton={
            template:`
                <button>局部按钮</button>
            `
        }
        // 局部组价
        const Vcontent={
            data(){
                return{}
            },
            template:`
                <div>
                    <div>我是内容栏</div>
                    <Vbutton/>
                    <Vbutton/>
                </div>
            `,
            components:{
                Vbutton,
            },
        }
        // App 组件  html+css+js
        // 1. 创建组件
        // 2. 挂载子组件
        // 建,挂,用
        // 注意: 在组件中这个data 必须是一个函数,返回一个对象
        const App ={
            data(){
                return {
                    msg: "我是App组件"
                }
            },
            <!-- 一定要有一个闭合的标签 -->
            template:`
                <div>
                    <div>
                        <Vheader> </Vheader>
                        <div>
                           <Vaside />
                           <Vcontent/>
                        </div>
                    </div>
                    <h3>{{msg}}</h3>
                    <button @click='handleClick'> 按钮</button>
                </div>
            `,
            methods:{
                handleClick(){
                    this.msg='学习局部组件';
                }
            },
            components: {
                Vcontent,
            }
        }
        var a = new Vue({
            el:'#App',
            data:{},
            components: {
                //  挂载子组件
                App,
            },
        })
    </script>


    全局组件的创建和使用


    vue 提供的监听触发事件 把输出的值,通过事件抛出给父组件

    this.$emit('inputHandler',val)
     $on 绑定事件
     $emit 触发事件

    provide 和 inject

    <div id="App">
        <!--    //  3. 使用子组件-->
        <App> </App>
    </div>
    <script src="../vue.js" ></script>
    <script>
        // provide
        // inject
        // 父组件 provide 来提供变量, 然后再子组件中通过inject 来注入变量,无论组件嵌套多深
        //  做了个中间传递者的功能  中央事件总线
        var c = new Vue
        //  这里的this  是这个A子组件本身的this
        Vue.component('AA',{
            template:`
                <div>AA 使用provide 和 inject -> : {{msg}}</div>
            `,
            inject:["msg"]
    
        })
        Vue.component('A',{
            // data(){
            //     return{
            //         msg:"provide + inject ->  A -> AA -> A "
            //     }
            // },
            template: `
                <div>
                    <AA></AA>
                    <button @click="countNumber">购物车+1</button>
                </div>
            `,
            methods:{
                countNumber(){
                    //  $emit   触发事件
                    c.$emit('add',1)
                }
            }
        })
        //  这里的this  是这个B子组件本身的this
        Vue.component('B',{
            data(){
                return {
                    number:0
                }
            },
            template:`
                <div>  {{number}} </div>
            `,
            // 组件创建
            created(){
                //  $on     绑定事件
                //  $emit   触发事件
                c.$on('add',(n)=>{
                    this.number+=n;
                })
            }
        })
    
        const App ={
            data(){
                return {}
            },
            // 需要绑定一个属性    ( : 属性, @ 事件 )
            template:`
                    <div>
                        <A></A>
                        <B></B>
                    </div>
            `,
        }
        new Vue({
            el:'#App',
            data:{ },
            provide(){
                return {
                    msg:"provide + inject -> App-> A -> AA "
                }
            },
            components: {
                //  挂载子组件
                App,
            },
        })
    </script>

    匿名插槽 

    <slot></slot>

    具名插槽

    <slot name="aa"></slot>

    作用域插槽
    有时让插槽内容能够访问子组件中才有的数据是很有用的

    生命周期

    • beforeCreate
    • created
    • beforeMount
    • mounted
    • beforeUpdate
    •  updated
    •  activated        激活
    • deactivated    停用
    •  需要配合 keep-alive 保存在内存中
    •  beforeDestroy
    •  destroyed
    <div id="App">
        <!--    //  3. 使用子组件-->
        <App></App>
    </div>
    <script src="../vue.js" ></script>
    <script>
        // beforeCreate
        // created
        // beforeMount
        // mounted
        // beforeUpdate
        // updated
        // activated    激活
        // deactivated  停用
        // 需要配合 keep-alive  保存在内存中
        // beforeDestroy
        // destroyed
        Vue.component('test',{
            data() {
                return {
                    msg:"你辉哥哥哥",
                    isRed:false
                };
            },
            methods:{
                handleClick(){
                    this.msg = "Appyourpapa";
                    this.isRed = !this.isRed ;
                }
            },
            template: `
                <div>
                    <button @click="handleClick">改变</button>
                    <h3 :class='{active:isRed}'>{{msg}}</h3>
                </div>
            `,
            beforeCreate(){
                console.log("组件创建之前 -> beforeCreate",this.$data )
            },
            created(){
                // 非常重要的事情,在此时发送ajxa 请求后端数据
                console.log("组件创建完成 -> create", this.$data)
            },
            beforeMount(){
                console.log("组件挂载之前 -> beforeMount", document.getElementById("app"))
            },
            mounted(){
                console.log("组件挂载完成 -> Mount", document.getElementById("app"))
            },
            beforeUpdate(){
                console.log("组件更新之前的DOM -> beforeUpdate", )
            },
            updated(){
                console.log("组件更新完成的DOM -> updated", )
            },
            beforeDestroy(){
                console.log("组件销毁之前的DOM -> beforeDestroy")
            },
            destroyed(){
                console.log("组件销毁完成的DOM -> destroyed")
            },
            activated(){
                console.log("组件被激活了 -> activated")
            },
            deactivated(){
                console.log("组件被停用了 -> deactivated")
            },
        })
        const App ={
            data(){
                return {
                    isShow:true
                }
            },
            methods: {
                clickHandler(){
                    this.isShow = !this.isShow;
                },
            },
            // 一定要有一个闭合的标签 
            // 需要绑定一个属性    ( : 属性, @ 事件 )
            template:`
                <div>
                    <keep-alive>
                        <test v-if="isShow"></test>
                    </keep-alive>
                    <button @click="clickHandler">销毁和创建</button>
                </div>
            `
        }
        new Vue({
            el:'#App',
            data:{ },
            provide(){
                return {
                    msg:"provide + inject "
                }
            },
            components: {
                //  挂载子组件
                App,
            },
        })
    </script>


    异步组件加载

    <script src="../vue.js" ></script>
    <script type='module'>
    
        const App ={
            data(){
                return {
                    isShow:false
                }
            },
            methods: {
                clickHandler(){
                    this.isShow = !this.isShow;
                },
            },
            components:{
                test:()=>import('./test.js')
            },
            template:`
                <div>
                    <test v-if="isShow"></test>
                    <button @click="clickHandler">异步加载</button>
                </div>
            `,
        }
        new Vue({
            el:'#App',
            data:{ },
            provide(){
                return {
                    msg:"provide + inject "
                }
            },
            components: {
                App,
            },
        })
    </script>

    refs的使用

    访问子组件实例或子元素

    有的时候你仍可能需要在 JavaScript 里直接访问一个子组件。为了达到这个目的,你可以通过 ref 这个 attribute 为子组件赋予一个 ID 引用。例如:

    <base-input ref="usernameInput"></base-input>

    现在在你已经定义了这个 ref 的组件里,你可以使用:

    this.$refs.usernameInput

    来访问这个` <base-input> `实例,以便不时之需。比如程序化地从一个父级组件聚焦这个输入框。在刚才那个例子中,该 <base-input> 组件也可以使用一个类似的 ref 提供对内部这个指定元素的访问,例如:

    <input ref="input">

    甚至可以通过其父级组件定义方法:

    methods: {
      // 用来从父级组件聚焦输入框
      focus: function () {
        this.$refs.input.focus()
      }
    }

    允许父级组件通过下面的代码聚焦 `<base-input> `里的输入框:

    this.$refs.usernameInput.focus()

    当 ref 和 v-for 一起使用的时候,你得到的 ref 将会是一个包含了对应数据源的这些子组件的数组。

    nextTick的使用 和 应用

        <div id="App">
            <!--    //  3. 使用子组件-->
            <App></App>
        </div>
    <script src="../vue.js" ></script>
    <script >
    // 在页面上拉取一个接口,这个接口返回一些数据,这些数据是这个页面的一个浮层组件要依赖的, // 然后我在接口一返回数据就展示了这个浮层组件,展示的同时 // 上报一些数据给后台(这些数据是父组件从接口拿的) // 这个时候,神奇的事情发生了,虽然拿到了数据,但是浮层展现的时候, // 这些数据还未更新到组件去,上报失败 const Pop = { data(){ return{ isShow:false, } }, props:{ name : { type: String, default:'', }, }, template:` <div v-if="isShow"> {{name}} </div> `, methods:{ show(){ // 弹窗组件展示 this.isShow = true; console.log(this.name); } } } const App=({ data(){ return{ name :"" } }, created(){ // 模拟异步请求 setTimeout(()=>{ // 更新数据 this.name = "huige" this.$nextTick(()=>{ this.$refs.pop.show(); }) // this.$refs.pop.show(); },1000); }, components:{ Pop }, template: ` <pop ref="pop" :name="name"></pop> ` }) var vm = new Vue({ el:'#App', components: { App } }) </script>

    对象变更检测注意事项

    <div id="App">
        <h3>
            {{user.name}}, {{user.age}}, {{user.phone}}
            <button @click="handlerAdd">添加响应式属性</button>
        </h3>
    </div>
    <script src="../vue.js" ></script>
    <script >
        //  Vue 不能检测对象属性的添加和删除
        new Vue({
            el:'#App',
            data:{
              user:{}
            },
            methods:{
                handlerAdd(){
                    this.user.age = 20
                    // 添加响应式属性, 只有 添加或者删除 有效
                    //  vue 的方法需要都要加 $
                    //1.  Vue.$set(object, key, value)
                    // this.$set(this.user,"age",20)
                    // 2. Object.assign 方法
                    this.user = Object.assign({}, this.user,{
                        age:200,
                        phone:110,
                    })
                }
            },
            created(){
              setTimeout(()=>{
                  this.user={name:"我是你爸爸"}
              },2000)
            },
        })
    </script>


    mixin混入技术

        // 一个公共的组件
        const mymixin={
            data(){
                return{
                    msg:"asd"
                }
            },created(){
                this.hello();
            },
            methods:{
                hello(){
                    console.log("hello mixin")
                }
            }
        }
        new Vue({
            el:'#app',
            data(){
            return {
                msg1:"huige"
            }
        },
        created(){
            console.log("aaa")
        },
        //  mixin 来分发Vue 组件中 的可复用 功能!
        mixins:[mymixin],
        })

    mixin混入技术应用

    <div id="app">  </div>
    <script src="../vue.js" ></script>
    <script>
    // 模态框 和 提示框 逻辑程序的复用 // 全局的mixin 每个创建的组件都会被调用。 // 用法 Vue.mixin({}) const allData={ data() { return { isShow:false } }, methods:{ allData(){ this.isShow= !this.isShow } } } const MoDuleData= { template:` <div v-if='isShow'> <h1> 模态框 </h1> </div> `, mixins:[allData] } const ToolData = { template:` <div v-if='isShow'> <h4> 提示框 </h4> </div> `, mixins:[allData] } new Vue({ el:'#app', data:{}, components:{ MoDuleData, ToolData, }, template:` <div> <button @click="handlemoduel">模态框</button> <button @click="handletool">提示框</button> <MoDuleData ref='modulea'></MoDuleData> <ToolData ref='toola'></ToolData> </div> `, methods: { handlemoduel(){ this.$refs.modulea.allData(); }, handletool(){ this.$refs.toola.allData(); }, } }) </script>
  • 相关阅读:
    前端vue采用formData数据格式传递文件(Post请求)和非文件参数。后端怎样接收的问题(已解决)
    easyExcel 所需的maven 依赖
    基于客户数据的银行信用卡风险控制模型研究-金融风控模型标准评分卡
    chrome 插件知识点(转载)
    EasyNVR调用指定时间端录像播放接口出现黑屏的问题原因以及解决方法
    EasyNVR智能云终端推送视频流至EasyNVS管理平台失败且报错如何排查?
    EasyNVR分发rtsp不标准导致客户端检查报错是什么原因?
    EasyNVR前端在线修改录像存储路径后hls直播失效问题的处理
    EasyNVR实时阅览四分屏状态下最后一路流无法正常播放问题排查
    通过EasyNVR推流到抖音快手直播间无法正常推流是什么原因?
  • 原文地址:https://www.cnblogs.com/huidou/p/13445219.html
Copyright © 2011-2022 走看看