认识了解一下vue

0vue.js是一套构建用户界面的渐进式框架, 声明式渲染和组件系统是Vue的核心库所包含的内容。

  • 构建用户界面 (通过数据渲染成页面模板,展示给前端用户)
  • 渐进式 (循从Vue 模板-指令-组件-路由-vuex 等由简单到复杂的开发学习应用过程)
  • 框架 (半成品的应用 , 不断在维护更新的开源框架 )
  • 声明式渲染 (如同js基础一样, 要使用变量则必须先声明变量 , 这种称之为声明式)
  • 组件化应用构建 (组件系统是Vue的另一个重要的概念 , 因为它是一种抽象的允许使用小型、独立和通常可复用的小积木构建大型应用 ,几乎任意类型的应用界面都可以抽象为一个组件树。)

一、 Vue的开发模式

M-V-VM

  • M (model): 普通的JavaScript数据对象
  • V (view) :前端展示页面(通俗讲就是html内容)
  • VM(ViewModel): 用于双向绑定数据与页面

二 、 初识Vue

  • 通过script标签引入Vue ,

       <!-- 开发环境版本,包含了有帮助的命令行警告 -->
       <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    
       <!-- 生产环境版本,优化了尺寸和速度 -->
       <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
    
  • new Vue() 创建Vue实例对象

    • 第一个参数: el ( 指定Vue负责渲染的容器的选择器)
    • 第二个参数: data { 定义数据 } (定义的是Vue实例需要的数据)
  • 页面展示数据时使用插值表达式 , {{ 变量/表达式 }}

<body>
    <!-- 1. 定义渲染的容器 -->
    <div id="app">
         <p>{{msg}}</p>
    <div>    
    <!-- 2. 引入vue.js文件 ,-->
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <script>
        // 3. 产生vue实例(V是大写的),传递配置选项
        new Vue({
            // el => element,指定vue负责渲染的容器的选择器
            el: "#app",
            // data指定vue实例需要的数据(数据的初始化)
            data: {
                msg: "hello world",
            },
        });
    </script>
</body>

三、Vue模板语法

1、插值表达式

是vue框架提供的一种在HTML模板中绑定数据的方式 , 使用 {{ 变量名 }} 方式进行绑定vue实例中data的数据变量, 会将绑定的数据实时的在视图中显示出来

 在{{ }} 括起来的区域 , 就是一个js语法区域 , 在里面可以写部分的js语法  , 但是不能写 var a = 10  /  分支语句    /  循环语句
    <div id="app">
        <!-- 直接使用变量名 -->
        <h1>{{name}}</h1>
        <!-- 运算 -->
        <h1>{{name + '好'}}</h1>
        <h5>{{ 1 + 1 }}</h5>
        <!-- 使用函数 -->
        <h5>{{title.substr(0,6)}}</h5>
        <!-- 三目运算 -->
        <h5>{{ age > 18 ? '成年' : '未成年'}}</h5>
    </div>

<script>
    new Vue({
        el: "#app",
        data: {
            title: "我是一个标题,你们看到没有",
            name: "张三",
            age: 20,
        },
    });
</script>

2、指令

指令以 v- 开头 , 在vue的html中 , 以v- 开头的自定义属性就是指令。
不常用的指令 (4种)
v-text (填充纯文本)

    相当于之前原生的innerText , 相比插值表达式更加简洁 , 不存在插值表达式的闪动问题。

v-html (填充html片段 , 可以识别标签)

    相当于原生的innerHTML , 它存在安全问题 , 容易被攻击。   

v-cloak

   解决浏览器在加载页面时因存在时间差而产生的闪动问题

v-once

  只渲染元素或组件一次 , 之后元素或组件将失去响应式 (数据层面) 功能 . 
    <style>
        [v-cloak] {
            display: none;
        }
    </style>

    <div id="app">
        <p v-text="msg"></p>    //hello world
        <!-- v-text  === innerText 纯文本添加 , 不解析, msg内容是什么 , p标签写入什么-->

        <P v-html="msg1"></P>    // 千峰 (斜体字的)
        <!-- v-html  === innerHTML 可以解析标签 结果是解析过的斜体字的千峰 黑客攻击,禁止使用 -->

        <p v-cloak> {{msg}} </p>
        <!-- v-cloak用于解决白屏问题 -->

        <!-- v-once 渲染一次, 之后再发生改变不会重新渲染 -->
        <p v-once> {{msg}} </p>
    </div>

    <script>
        const vm = new Vue({
            el: '#app',
            data: {
                msg: 'hello world',
                msg1: '<i>千峰</i>'
            }
        })
    </script>

常用的指令

1, v-bind

它可以做到 在html内置的属性值中使用变量 ,

        v-bind: 可以缩写为   : 
 <div id="app">
        <!-- 动态属性 -->
        <p v-bind:class="mycolor">千峰教育</p>
        <!-- 简写动态属性 -->
        <p :class="mycolor">千峰教育</p>

        <!-- 动态属性 后面是对象的形式 对象值控制对象的属性 -->
        <p :class="{'name': myname}">全等</p>

        <!-- 动态属性 后面放数组 多个变量 -->
        <p :class="[msg,mycolor]">全都健康</p>

        <!-- style动态属性 -->
        <p :style="myStyle">地方属性</p>
        <p :style="{fontSize:'24px'}">ss</p>
    </div>

    <script>
        new Vue({
            el: '#app',
            data: {
                msg: 'hello world',
                mycolor: 'my-color',
                myname: false,
                myStyle: {
                    fontSize: '50px'
                }
            }
        })
    </script>
2, v-on

绑定事件监听器 , 缩写形式 @
如果事件直接使用函数名且不写小括号 , 那么会默认将事件对象作为唯一参数进行传递 , 可以在定义函数的位置直接定义一个形参 , 并且在函数内可以使用该形参

如果使用常规的自定义函数调用 (写了小括号)) , 如果需要事件对象必须作为一个参数进行传递 , 事件对象的名称必须是 $event

   v-on的事件修饰符
         1, .once  事件只执行一次
         2, .self  只有触发事件源本身时才触发 , 也可用于阻止事件冒泡行为
         3, .stop  阻止事件冒泡
         4, .prevent  阻止事件默认行为


  v-on的按键修饰符
        1,  .enter   回车键的时候调用
        2,  .delete 删除键的时候调用
             
             <input @keyup.enter="submit">
        <button @click.once="clickfun()">点击</button>
        //只执行一次clickfun函数
        <a @click.prevent="clicka" href="http://baidu.com">百度</a>
        //阻止点击之后默认跳转百度网页 , 执行 clicka 的内容
        <div @click.self="clickparent()" style="background-color: aqua;width: 500px;height: 500px;">    //父元素添加 .self ,防止子元冒泡行为
            <div @click.stop="clickchild()" style="background-color: rgb(65, 68, 68);width: 200px;height: 200px;margin: auto;">
            //子元素添加 .stop 防止冒泡
            </div>
        </div>

        <input type="text" @keyup.enter="enterFun">
        //点击enter键 执行 enterFun 
3, v-model

双向绑定数据 , 只适用于 表单
input , textarea , select 绑定的是value
checkbox , radio 绑定的是checked属性

       v-model的修饰符:
           lazy  把input事件变成 blur事件
           number 因为v-model是自动转化为字符串的 , number可以将其转化为number类型
           trim 去除前后的空白
    <div id="app">

        <p> {{msg}} </p>
        <input type="text" v-model="msg">
        <!-- v-model只适用于表单 -->

        <p>{{text}}</p>
        <textarea v-model="text"></textarea>

        <p> {{checkvalue}} </p>
        <label for="bj">北京</label>
        <input type="checkbox" value="北京" v-model="checkvalue" id="bj">
        <label for="tj">天津</label>

        <input id="tj" type="checkbox" value="天津" v-model="checkvalue">
        <label for="sh">上海</label>
        <input type="checkbox" value="上海" v-model="checkvalue" id="sh">


        <p> {{rediovalue}} </p>
        <label for="bei">北京</label>
        <input type="radio" v-model="rediovalue" id="bei" value="beijing">

        <label for="tian">天津</label>
        <input type="radio" v-model="rediovalue" id="tian" value="tianjin">
        <label for="shang">上海</label>
        <input type="radio" v-model="rediovalue" id="shang" value="shanghai">

        <input type="text" v-model.lazy="msg">
        <!-- lazy懒加载,从input事件 到blur事件-->

        <p> {{msg1}} </p>
        <input type="text" v-model.number="msg1">
        <!-- number把当前变量转换成number类型, v-model绑定的变量是自动转换成字符串的 -->

        <p> {{msg2}} </p>
        <input type="text" v-model.trim="msg2">
    
    </div>

    <script>
        new Vue({
            el: '#app',
            data: {
                msg: 'hello',
                msg1: 123,
                msg2: 'htll'
                text: '文本内容',
                selectvalue: 'beijing',
                checkvalue: [],
                rediovalue: ''


            }
        })
    </script>
4, v-for

循环指令 , 根据一组数组或者对象的选项列表进行渲染.

    <div id="app">
        <ul>
            <li v-for="(item , index) in arr" :key="index">
                下标:{{index}} 元素:{{item}}</li>
        </ul>

        <ul>
            <li v-for="item in arr1" :key="item.id">
                id:{{item.id}} , 姓名:{{item.name}}</li>
        </ul>

        <ul>
            <li v-for="(val , key , index) in obj" :key="index">
                下标: {{index}} 属性: {{key}} , 属性值: {{val}}
            </li>
        </ul>
    </div>

    <script>
        new Vue({
            el: '#app',
            data: {

                arr: [1, 2, 3, 4, 5],
                arr1: [{
                        id: 1,
                        name: '张三'
                    }, {
                        id: 2,
                        name: '李四'
                    }, {
                        id: 3,
                        name: '王五'
                    }

                ],
                obj: {
                    name: '保定',
                    age: 22,
                    address: '保定'
                }
            }
        })
    </script>
5, v-if v-else-if v-else 或者 v-show

v-if v-else-if v-else 根据表达式的布尔值进行判断是否渲染该元素 ,
v-show 是已经全部渲染了 , 根据表达式的真假 , 切换display的属性值

    <div id="app">
        <p v-if="num === 0">零铃铃铃</p>
        <p v-else-if="num === 1">一壹亿壹</p>
        <p v-else>其他</p>

        <p v-show="num1 > 1">大于1</p>
        <p v-show="num1 <0">小于零</p>
        <p v-show="num1>0 &&num1<1">大于零小于1</p>
    </div>

    <script>
        new Vue({
            el: '#app',
            data: {
                num: 1,
                num1: 0.5
            }
        })
    </script>
  v-if 和 v-show的区别:
            v-if 控制这个元素是不是要渲染 , true 是要渲染 , false 是不渲染
            v-show是控制这个元素要不要展示 ,  元素是肯定要渲染的 , false是通过行内样式 隐藏的 , 但是节点存在

  v-if  和v-show 比较?
         如果说不涉及到节点的删除和渲染的话就用 v-if
         如果说切换频繁 , 就用 v-show
6, 自定义指令

除了核心功能默认内置的指令 , vue也允许开发者注册自定义指令 , 自定义指令分为 全局指令 和 局部指令.(全局指令适用于整个项目 , 局部指令适用于当前组件 )

   自定义指令常用 钩子函数:
       1,  bind : 在指令第一次绑定到元素时调用
       2, inserted : 被绑定元素插入父节点时调用 , 
       3, update :数据更新时调用
       4, componentUpdated : 指定元素及子节点更新完成后触发
       5, unbind : 取消绑定后触发

 注意: 不管是定义全局指令 还是 定义局部指令 , 所提及的指令名称均不带 v-前缀名称
    <div id="app">
        <div v-red>武汉上演</div>
        <div v-color="'blue'">防御严寒</div>
        <input type="text" v-model="mobile" v-mobile>
    </div>

    <script>
        Vue.directive('red', {
            inserted: function(el) {
                el.style.color = 'red'

            }

        });
        Vue.directive('color', {
            inserted: function(el, val) {
                el.style.color = val.value

            }
        })

        new Vue({
            el: '#app',
            data: {
                mobile: ''

            },
            directives: {
                mobile: {
                    update: function(el) {
                        let mobile = el.value

                        if (/^1[3-9]\d{9}$/.test(mobile)) {
                            el.style.color = 'yellow'
                        } else {
                            el.style.color = 'pink'
                        }
                    }
                }
            }

        })
    </script>

四、vue常用属性

1, 计算属性

模板中放入太多的逻辑(方法 ) 会让模板过重难以维护 , 使用计算属性可以让模板变得简洁易于维护. 计算属性是基于它们的响应式依赖进行缓存的 , 计算属性比较适合对多个变量或对象进行处理后返回一个结果值 , 也就是数多个变量中的某一个值发生变化 , 我们监控的这个值也会发生变化

计算属性通过 computed属性对象中定义一个一个的函数 并返回一个值

 注意:
     计算属性必须要有 return
     在某种特定的场景下 , 计算属性的效率要比methods效率高 , 计算属性支持数据的缓存操作 (在依赖数据不变的情况下)
 <!-- 
        执行结果:
        computed本次只执行一次
        methods执行
        methods执行

     -->
    <div id="app">
        <p> {{num}} </p>
        <p> {{doublenum}} </p>
        <p> {{doublenum}} </p>
        <p> {{doublenum2()}} </p>
        <p> {{doublenum2()}} </p>
        <button @click="num++"> + </button>

    </div>
    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                msg: 'hello',
                num: 10 //数据改变当前页面会刷新
            },
            computed: {
                doublenum() {
                    console.log('computed本次只执行一次')
                    return this.num * 2
                }
            },
            methods: {
                doublenum2() {
                    console.log('methods执行')
                    return this.num * 2
                }
            }
        })
    </script>
2, 监听器

使用watch来侦听data中的数据的变化 , watch中的属性一定是data中已经存在的数据 (特殊情况除外), 每个监听的方法可以接受两个参数 , 第一个参数是新的值 , 第二个参数是之前的值 ,

如果需要监听一个对象的改变时 , 普通的watch方法无法监听到对象内部属性的变化 , 此时需要deep属性对对象进行深度监听.

        new Vue({
            el: '#app',
            data: {
                msg: 'hello world',
                obj: {
                    name: '大壮',
                    job: {
                        age: 22
                    }
                }
            },
            watch: {
                 msg: {
                     'handler': 'changemsg',
                     'immediate': true,
                 },
                obj: {
                    'handler': 'changeobj',
                    'immediate': true, //首次执行watch , 没有旧的值
                    'deep': true //是深度监听 , 默认是浅监听

                }
            },
            methods: {
                changemsg(newval, oldval) {
                    console.log('msg改变')
                    console.log(newval)
                    console.log(oldval);
                },
                changeobj(){
                console.log('obj改变')
                }          
            }
        })
3, filter过滤器

用于格式化数据 , 比如字符串格式化为首字母大写 , 将日期格式化为指定的格式.

过滤器可以定义为全局过滤器 和 局部过滤器

全局过滤器    
   
   Vue.filter('过滤器名称' , (val) =>{
          return val进行处理
   })

局部过滤器
    new Vue({
    filters:{
    过滤器名称: (val) =>{
    return val进行处理 
            }
        }
    })

五、生命周期

生命周期: 从vue实例产生开始到vue实例被销毁这段时间所经历的过程.

vue更像工具人 , 在整个过程中只会按照作者预设的程序去做事 , 不能由开发者去控制 , 这样开发时的限制很多 , 因此开放了生命周期 , 允许我们定义vue在特定的时候执行钩子函数( 做自己想要的事情)

vue生命周期的主要阶段:
  • 创建

     beforeCreate     创建前   
                         vue实例创建前阶段 , 咋此时不能获取data中的数据 
     created          创建后
                         vue实例已经创建完成 , 在此时可以获取data中的数据和methods中的方法
     beforeMount      挂载前
                         还没有将渲染模板挂载在el元素上 , 
     mounted          挂载后
                         页面加载完毕的时候 , 就是此时 , 默认情况下 , 在组件的生命周期中只会触发一次
    
  • 更新 (元素或组件的变更操作)

     beforeUpdate      更新前
     updated           更新后
                          可以重复触发
    
  • 销毁 (销毁相关属性)

     beforeDestroy     销毁前
     destroyed         销毁后
                           销毁( 手动 )  使用 this.$destroy()
    

六、网络请求

1,fetch (不常用 , 了解)

优点:

1, 浏览器内置的, 相比于jQuery而言 , 省去了导入js包的麻烦

2, 可以看做xhr的升级版

3, 主持promise

4, 支持多种请求类型 ,但是默认为get请求类型

有几种语法形式:

   语法1:
         fetch(url)
         .then( res => res.json())
         .then( res => console.log(res))


   语法2:
       fetch(url , {
              methods: 'post'  , // 或者是get
              body:JSON.stringify(data) ,    //发送的json数据
              headers: new Headers({
                        'Content-Type' : 'application/json'
                 }),
                 }).then(res => res.json()) 
                 . then( res => connsole.log(res))

   语法3:
        fetch(url , {
              methods: 'post'  , // 或者是get
              body:"username=zhangsan&age=11" ,    //发送的json数据
              headers: new Headers({
                        'Content-Type' : 'application/json'
                 }),
                 }).then(res => res.json()) 
                 . then( res => connsole.log(res))       
        })
2, axios

axios是一个基于promise的HTTP库 , 可以用在浏览器和node.js 中 , axios是vue作者推荐使用的网络请求库 , axios具有以下特性:

  • 1, 支持浏览器和node.js

  • 2, 支持promise

  • 3, 能够拦截请求和响应 (拦截器)

  • 4, 自动转换json数据

在使用axios之前需要在对应的模板文件中引入axios的js库文件

   <script src="https://unpkg.com/axios/dist/axios.min.js"></script>

有几种语法形式:

            methods: {
                getData0() {
                    axios.get('https://api.i-lynn.cn/college', {
                            params: {
                                id: 1,
                                name: '大壮'
                            }
                        })
                        .then(res => {
                            console.log(res)
                            this.data = res.data.data
                        })
                }

                ,
                getData1() {
                    axios.get('https://api.i-lynn.cn/college?name=dazhuang')
                        .then(res => {
                            console.log(res)
                            this.data = res.data.data;
                        })
                },
                getData2() {
                    axios.post('https://api.i-lynn.cn/college', 'name=dazhuang&age=22').then(
                        res => {
                            console.log(res)
                            this.data = res.data.data
                        }
                    )
                },
                getData3() {
                    axios({
                        method: 'post',
                        url: 'https://api.i-lynn.cn/college',
                        timeout: 1000, // 超过没响应 报超时错误
                        headers: {
                            //表单提交
                            // 'Content-Type': 'application/x-www-form-urlencoded'
                            //json提交  默认
                            //  'Content-Type': 'application/json'
                        },
                        data: {
                            username: 'zhangsan',
                            type: 2
                        }
                    }).then(res => {
                        console.log(res)
                        this.data = res.data.data
                    })
                }

axios与fetch相比 , fetch最终的res就是我们的返回值 , 而axios这里的res不是我们的返回值 , 而是axios的请求响应的响应对象 , 我们的返回数据在res.data中.

七、脚手架

cnpm i -g @vue/cli 脚手架

vue --version 查看版本

vue create myapp myapp项目名称

八、组件

组件化把某个页面进行拆分, 最后再做合并 ,组件.vue文件结尾都是组件 , 组件有template script style 三部分组件, template模板( 不止可以写标签 , 还可写vue指令 ) ,
组件命名无论是 vue还是 react , 都需要使用大驼峰命名法

组件的使用:

  1, 定义组件
  2, 引入并注册组件
  3, 使用组件

组件分全局组件和局部组件
在main.js中引入注册的组件是全局组件 ,

  import Child2 from ' ./components/Child2 '
  Vue.component(' Child2' , Child2 )    
       // 全局注册 , 第一参数是组件别名 , 第二参数是 组件

     在某个组件内部注册的组件是局部组件

九、组件通信

父子通信:
父 – 子 传值 父组件通过动态属性绑定一个值 , 子组件通过props数组来接收参数变量。

子 – 父 传值 子组件调用事件,this.$emit触发父组件的自定义事件并传参

单项数据流: 父组件的数据向子组件流传 , 并且自动随之改变.

bus通信或事件总线通信

1, 创建一个全局的事件中心 一般建立一个js文件 ,

   import Vue from 'vue'
   export default new Vue()

2, 写自定义事件 , (A向B通信 , 要把自定义事件写在B上)
3, A组件触发B的自定义事件并且传参 (事件.$emit() )

1, 什么是vue生命周期?

      vue生命周期分为创建 , 更新 , 销毁三个阶段
         创建阶段有  beforeCreate created beforeMount mounted
         更新阶段有  beforeUpdate updated
         销毁阶段有 beforeDestroy destroyed

2, 发送ajax请求在mounted还是在created里面 , 为什么?

 created代码会执行多次 , mounted只执行一次

3, vue的渲染过程?

vue只是一个框架 , 最终都要生成html页面 , 需要几步才能生成html页面

1, vue通过object.defineproperty把data数据变成set get 监听形式 (拿到data的数据 , 变成get set 监听形式) ,

2,vue通过render函数 , 传入数据 , 生输出vdom ,

3,vue通过patch函数 , 输入vdom , 直接渲染挂在dom上.

4, vue的更新过程?

1, vue触发set函数 , 触发更新流程 ,

2, vue通过调用render函数 , 传入数据 , 重新输出新的vdom

3, vue通过patch函数 输入的旧vdom 和新vdom 进行diff比较( 同行比较 , 少了创建 , 多了删除), 旧的vdom相对于新vdom中多的元素删除 , 少的元素创建 , 最后挂在渲染到真实的dom容器上

diff如何更新?
按vdom树的层级进行比较 , 标签不同的删除重建 , 标签相同的修改属性

5, 销毁自定义事件 , 计时器 , 自定义dom事件在哪个生命周期写?

beforeDestroy 这个生命周期写

6,组件框架中的data为什么是个函数?

为了组件被复用的时候都可以生成一个独立的数据拷贝 , 互相隔离不受影响.

7, v-for为什么要加key ,

为了提高性能 , 给标签一个主键.
在 删除其中某个元素时 , 其他元素可以直接复用. 大大提高性能

8, 为什么index不做key?

如果index 作为key的变量 , 数组下标永远从0开始 , 删除其中某个元素实际删除的是最后的元素 , 浪费性能

9, 单项数据流为啥是单项?

一个父组件对应多个子组件 , 父组件数据更新 , 多个子组件无条件更新 的就是 单向数据流

子组件更新 , 父组件更新不行吗?
子组件更新不能带动父组件更新 , 如果想修改父组件的数据 , 需要重新拷贝一份.

10, 父组件如何调用子组件中的函数?

ref通信 , (功能强大 , 不仅可以获取组件的实例 , 还可以获取标签节点 )

扩展:

  • v-if 控制节点创建和销毁 , v-show通过css方式控制元素显示或者隐藏 , 接口是渲染的

  • keep-alive 缓存组件 , 组件创建之后保存到内存中 , 不会销毁 , 是挺高性能的方法之一

    • include=“ChildB” 是指将 ChildB 这个组件进行缓存
    • exclude=“ChildB” 是排除ChildB这个组件, 剩下的组件都缓存
  • 父子组件

    • 子组件的创建阶段的渲染生命周期在父组件beforeMount之后 , mounted之前 ,
    • 子组件的更新阶段在父组件beforeUpdate之后 , 在updated之前更新.
    • 子组件的销毁阶段在父组件beforeDestroy之后 , 在destroy之前.

    附加:
    1、根目录下 npm init -y
    2、全局安装 cnpm i -g browser-sync
    3、package.json 添加自定义命令
    “start”: “browser-sync start -s -f */ --directory --watch”
    4、启动
    http://localhost:3000/ 访问即可

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值