vue教程

创建一个vue实例

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue 实例</title>
    <!-- 引入 Vue.js -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
</head>
<body>
    <!--
        创建vue容器初始化渲染
        1.准备容器
        2.引包(vue的js包) 
        3.创建实例
        4.添加配置项 完成渲染
    -->
    <div id="app">
        <!--这将来会编写一些用于渲染的代码逻辑-->
        {{msg}}
    </div>
    <!-- 创建实例 -->
    <script>
        //引入了vuejs的核心包,在全局环境下,就有了vue构造函数
        const app =new Vue(
            //通过el配置选择器指定了vue管理的是那个盒子
            //#app就指定管理了上面app的那个盒子
            {
                el:'#app',
                //通过data提供数据进行渲染
                data:{
                    msg:"hello vue"
                }

            }
        )
    </script>
</body>
</html>

插值表达式{{}}

插值是用来展示渲染的
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue 实例</title>
    <!-- 引入 Vue.js -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
</head>
<body>
    <!--
        创建vue容器初始化渲染
        1.准备容器
        2.引包(vue的js包) 
        3.创建实例
        4.添加配置项 完成渲染
    -->
    <div id="app">
        <!--这将来会编写一些用于渲染的代码逻辑-->
        {{msg.toUpperCase()}}
        {{msg.toUpperCase()+"你好啊"}}
        <h1>{{msg}}</h1>
    </div>
    <!-- 创建实例 -->
    <script>
        //引入了vuejs的核心包,在全局环境下,就有了vue构造函数
        const app =new Vue(
            //通过el配置选择器指定了vue管理的是那个盒子
            //#app就指定管理了上面app的那个盒子
            {
                el:'#app',
                //通过data提供数据进行渲染
                data:{
                    msg:"hello word"
                }

            }
        )
    </script>
</body>
</html>

vue响应式特性

在这里插入图片描述

        //引入了vuejs的核心包,在全局环境下,就有了vue构造函数
        const app =new Vue(
            //通过el配置选择器指定了vue管理的是那个盒子
            //#app就指定管理了上面app的那个盒子
            {
                el:'#app',
                //通过data提供数据进行渲染
                data:{
                    //响应式数据》数据变化后视图会自动更新
                    msg:"你好,响应式"
                }
                //data中的数据是会被添加到实例上。
                //1.实例.属性名
                //2.实例.属性名=新值
            }
        )

一旦数据变化数据也会变化。

vue指令

在这里插入图片描述
具体指令查看:https://cn.vuejs.org/api/built-in-directives.html#built-in-directives
例如v-html这个指令。
v-html 的内容直接作为普通 HTML 插入
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue 实例</title>
    <!-- 引入 Vue.js -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
</head>
<body>
    <!--
        创建vue容器初始化渲染
        1.准备容器
        2.引包(vue的js包) 
        3.创建实例
        4.添加配置项 完成渲染
    -->
    <div id="app">
        <div v-html="msg"></div>
    </div>
    <!-- 创建实例 -->
    <script>
        //引入了vuejs的核心包,在全局环境下,就有了vue构造函数
        const app =new Vue(
            //通过el配置选择器指定了vue管理的是那个盒子
            //#app就指定管理了上面app的那个盒子
            {
                el:'#app',
                //通过data提供数据进行渲染
                data:{
                    //响应式数据》数据变化后视图会自动更新
                    msg:"<a href='http://ww.baidu.com'>百度</a>"
                }
                //data中的数据是会被添加到实例上。
                //1.实例.属性名
                //2.实例.属性名=新值
            }
        )
    </script>
</body>
</html>

v-if vs. v-show 指令

v-if 是“真实的”按条件渲染,因为它确保了在切换时,条件区块内的事件监听器和子组件都会被销毁与重建。

v-if 也是惰性的:如果在初次渲染时条件值为 false,则不会做任何事。条件区块只有当条件首次变为 true 时才被渲染。

相比之下,v-show 简单许多,元素无论初始条件如何,始终会被渲染,只有 CSS display 属性会被切换。

总的来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要频繁切换,则使用 v-show
较好;如果在运行时绑定条件很少改变,则 v-if 会更合适。

在这里插入图片描述

show是通过css来控制隐藏,if是通过判断条件控制元素的创建和移除

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue 实例</title>
    <!-- 引入 Vue.js -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <h1 v-show="msg">Hello!</h1>
        <h1 v-if="msg">v-if</h1>
    </div>
    <!-- 创建实例 -->
    <script>
        const app =new Vue(
            {
                el:'#app',
  
                data:{
                  
                    msg: true
                }
            }
        )
    </script>
</body>
</html>

v-else-if 指令

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue 实例</title>
    <!-- 引入 Vue.js -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <p v-if="gender===1">男</p>
        <p v-else>女</p>
        <hr>
        <p v-if="score>=90">A</p>
        <p v-else-if="score>=70">B</p>
        <p v-else>C</p>
    </div>
    <!-- 创建实例 -->
    <script>
        const app =new Vue(
            {
                el:'#app',
  
                data:{
                    gender: 2,
                    score:80
                }
            }
        )
    </script>
</body>
</html>

v-on指令 注册监听

在这里插入图片描述

内联语句

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue 实例</title>
    <!-- 引入 Vue.js -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <button v-on:click="count--">-</button>
        <span>{{count}}</span>
        <!-- 给+号注册点击事件 -->
        <button v-on:click="count++">+</button>
    </div>
    <!-- 创建实例 -->
    <script>
        const app =new Vue(
            {
                el:'#app',
  
                data:{
                    count:100
                }
            }
        )
    </script>
</body>
</html>

或者用@click注册

        <button @click="count++">+</button>

methods中的函数名在这里插入图片描述

methods中用来提供方法。
实现隐藏方法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue 实例</title>
    <!-- 引入 Vue.js -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <button @click="fun">显示隐藏</button>
        <h1 v-show="isshow">测试</h1>
    </div>
    <!-- 创建实例 -->
    <script>
        const app =new Vue(
            {
                el:'#app',
  
                data:{
                    isshow:true
                },
                methods:{
                    fun(){
                        app.isshow=!app.isshow;      
                    }
                }
            }
        )
    </script>
</body>
</html>

v-on 调用传参

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue 实例</title>
    <!-- 引入 Vue.js -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <button @click="fun(5)">减5 </button>
        <button @click="fun(10)">减10 </button>
        <p>当前数值:{{number}}</p>
    </div>
    <!-- 创建实例 -->
    <script>
        const app =new Vue(
            {
                el:'#app',
                data:{
                    number: 100
                },
                methods:{
                    fun(number){
                        this.number-=number;
                    }
                }
            }
        )
    </script>
</body>
</html>

v-bind 动态的设置html标签

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue 实例</title>
    <!-- 引入 Vue.js -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
</head>
<body>
    <div id="app">
       <img v-bind:src="imgUrl">
    </div>
    <!-- 创建实例 -->
    <script>
        const app =new Vue(
            {
                el:'#app',
                data:{
                    imgUrl: "./omg/10.png "
                }
            }
        )
    </script>
</body>
</html>

简写

<div id="app">
   <img :src="imgUrl">
</div>

v-for指令 基于数据循环

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue 实例</title>
    <!-- 引入 Vue.js -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <ul>
            <li v-for="(item,index) in list">
                {{item}} - {{index}}
            </li>
        </ul>
    </div>
    <!-- 创建实例 -->
    <script>
        const app =new Vue(
            {
                el:'#app',
                data:{
                    list: ['1','2','3']
                }
            }
        )
    </script>
</body>
</html>

v-for中的key

在这里插入图片描述
在这里插入图片描述

v-model 表单绑定

在这里插入图片描述

数据变化:视图自动你更新 视图变化:数据自动更新

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue 实例</title>
    <!-- 引入 Vue.js -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        账户:<input v-model="username"><br>
        密码:<input v-model="password"><br>
        <button @click="login">登陆</button>
    </div>
    <!-- 创建实例 -->
    <script>
        const app =new Vue(
            {
                el:'#app',
                data:{
                    username:'',
                    password:''
                },
                methods:{
                    login(){
                        console.log(this.username,this.password)
                    }
                }
            }
        )
    </script>
</body>
</html>

指令修饰符

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue 实例</title>
    <!-- 引入 Vue.js -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <!-- 绑定键盘回车事件 -->
    <input @keyup.enter="fn" v-model="username" type="text">
    </div>
    <!-- 创建实例 -->
    <script>
        const app =new Vue(
            {
                el:'#app',
                data:{
                    username:''
                },
                methods:{
                    fn(){
                        console.log(this.username)
                    }
                }
            }
        )
    </script>
</body>
</html>

v-bind对于样式控制的增强

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue 实例</title>
    <!-- 引入 Vue.js -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    <style>
        .active{
            color: red;
        }
    </style>
</head>

<body>
    <div id="app">
        <ul>
            <li v-for="(item,index) in list" :key="item.id" @click="activeIndex = index">
            //通过{active: index === activeIndex}"实现动态控制
                <a :class="{active: index === activeIndex}" href="#">{{item.name}}</a>

            </li>
        </ul>
    </div>
    <!-- 创建实例 -->
    <script>
        const app =new Vue(
            {
                el:'#app',
                data:{
                    activeIndex:0,//记录高亮
                    list:[
                        {id:1,name:'京东秒杀'},
                        {id:2,name:'每日特价'},
                        {id:3,name:'品类秒杀'},
                    ]
                }
            }
        )
    </script>
</body>
</html>

:STYLE单独控制某个属性变化
在这里插入图片描述

v-model应用于其他表单元素

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    textarea {
      display: block;
      width: 240px;
      height: 100px;
      margin: 10px 0;
    }
  </style>
</head>
<body>

  <div id="app">
    <h3>小黑学习网</h3>

    姓名:
      <input type="text" v-model="username"> 
      <br><br>

    是否单身:
      <input type="checkbox" v-model="isSingle"> 
      <br><br>

    <!-- 
      前置理解:
        1. name:  给单选框加上 name 属性 可以分组 → 同一组互相会互斥
        2. value: 给单选框加上 value 属性,用于提交给后台的数据
      结合 Vue 使用 → v-model
    -->
    性别: 
      <input v-model="gender" type="radio" name="gender" value="1">男
      <input v-model="gender" type="radio" name="gender" value="2">女
      <br><br>

    <!-- 
      前置理解:
        1. option 需要设置 value 值,提交给后台
        2. select 的 value 值,关联了选中的 option 的 value 值
      结合 Vue 使用 → v-model
    -->
    所在城市:
      <select v-model="cityId">
        <option value="101">北京</option>
        <option value="102">上海</option>
        <option value="103">成都</option>
        <option value="104">南京</option>
      </select>
      <br><br>

    自我描述:
      <textarea v-model="desc"></textarea> 

    <button>立即注册</button>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        username: '',
        isSingle: false,
        gender: "2",
        cityId: '102',
        desc: ""
      }
    })
  </script>
</body>
</html>

计算属性

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    table {
      border: 1px solid #000;
      text-align: center;
      width: 240px;
    }
    th,td {
      border: 1px solid #000;
    }
    h3 {
      position: relative;
    }
  </style>
</head>
<body>

  <div id="app">
    <h3>小黑的礼物清单</h3>
    <table>
      <tr>
        <th>名字</th>
        <th>数量</th>
      </tr>
      <tr v-for="(item, index) in list" :key="item.id">
        <td>{{ item.name }}</td>
        <td>{{ item.num }}个</td>
      </tr>
    </table>

    <!-- 目标:统计求和,求得礼物总数 -->
    <p>礼物总数:{{ totalCount }} 个</p>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        // 现有的数据
        list: [
          { id: 1, name: '篮球', num: 1 },
          { id: 2, name: '玩具', num: 2 },
          { id: 3, name: '铅笔', num: 5 },
        ]
      },
      computed: {
        totalCount () {
          // 基于现有的数据,编写求值逻辑
          // 计算属性函数内部,可以直接通过 this 访问到 app 实例
          // console.log(this.list)

          // 需求:对 this.list 数组里面的 num 进行求和 → reduce
          let total = this.list.reduce((sum, item) => sum + item.num, 0)
          return total
        }
      }
    })
  </script>
</body>
</html>

computed 计算属性 VS methods方法

计算属性是有缓存的,一旦算出来结果就会立刻缓存
下一次读取》直接读缓存就行》性能特别高

在这里插入图片描述

计算属性的完整写法

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
</head>
<body>

  <div id="app">
    姓:<input type="text"><br>
    名:<input type="text"><br>
    <p>姓名:{{ fullName }}</p>
    <button>修改姓名</button>
  </div>

  <script>
    const app = new Vue({
      el: '#app',
      data: {
            firsName:"刘",
            lastName:"备",
      },
      computed: {
  fullName: {
    get() {
      return this.firstName + this.lastName;
    }
  }
},
      methods: {
          changeName(){

          }
      }
    })
  </script>
</body>
</html>

watch 监听器

作用:监视数据变化,执行一些逻辑或异步操作
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
        font-size: 18px;
      }
      #app {
        padding: 10px 20px;
      }
      .query {
        margin: 10px 0;
      }
      .box {
        display: flex;
      }
      textarea {
        width: 300px;
        height: 160px;
        font-size: 18px;
        border: 1px solid #dedede;
        outline: none;
        resize: none;
        padding: 10px;
      }
      textarea:hover {
        border: 1px solid #1589f5;
      }
      .transbox {
        width: 300px;
        height: 160px;
        background-color: #f0f0f0;
        padding: 10px;
        border: none;
      }
      .tip-box {
        width: 300px;
        height: 25px;
        line-height: 25px;
        display: flex;
      }
      .tip-box span {
        flex: 1;
        text-align: center;
      }
      .query span {
        font-size: 18px;
      }

      .input-wrap {
        position: relative;
      }
      .input-wrap span {
        position: absolute;
        right: 15px;
        bottom: 15px;
        font-size: 12px;
      }
      .input-wrap i {
        font-size: 20px;
        font-style: normal;
      }
    </style>
        <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>

  </head>
  <body>
    <div id="app">
      <!-- 条件选择框 -->
      <div class="query">
        <span>翻译成的语言:</span>
        <select>
          <option value="italy">意大利</option>
          <option value="english">英语</option>
          <option value="german">德语</option>
        </select>
      </div>

      <!-- 翻译框 -->
      <div class="box">
        <div class="input-wrap">
          <textarea v-model="obj.words"></textarea>
          <span><i>⌨️</i>文档翻译</span>
        </div>
        <div class="output-wrap">
          <div class="transbox">mela</div>
        </div>
      </div>
    </div>

    <script>
      // 接口地址:https://applet-base-api-t.itheima.net/api/translate
      // 请求方式:get
      // 请求参数:
      // (1)words:需要被翻译的文本(必传)
      // (2)lang: 需要被翻译成的语言(可选)默认值-意大利
      // -----------------------------------------------
      
      const app = new Vue({
        el: '#app',
        data: {
          words: '',
        },
        // 具体讲解:(1) watch语法 (2) 具体业务实现
       watch:{
        //该方法会在数据变化的时候执行
        'obj.words'(newValue,oldValue){
          console.log("变化了",newValue,oldValue)
        }
       }
       
      })
    </script>
  </body>
</html>

watch完整写法

在这里插入图片描述
在这里插入图片描述

VUE的生命周期和生命周期的四个阶段

在这里插入图片描述
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>

  <div id="app">
    <h3>{{ title }}</h3>
    <div>
      <button @click="count--">-</button>
      <span>{{ count }}</span>
      <button @click="count++">+</button>
    </div>
  </div>
  <script src="./vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        count: 100,
        title: '计数器'
      },
      //1.创建阶段
      beforeCreate(){
        console.log("响应数据准备好之前")
      },
      created(){
        console.log("响应数据准备好之后")
      },
       //2.挂载阶段
       beforeMount(){
        console.log("模板渲染之前")
       },
       mounted(){
        console.log("模板渲染之后")
       },
       //3.更新阶段(修改数据》更新视图
       beforeUpdatre(){
        console.log("数据修改了视图还没有更新");
       },
       updated(){
        console.log('update数据修改,视图已经更新了')
       },
       //4.卸载阶段
       beforeDestroy(){
        console.log('卸载前')
       },
       destroyed(){
        console.log("卸载后")
       }
    })
  </script>
</body>

</html>

created应用新闻迭代

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    * {
      margin: 0;
      padding: 0;
      list-style: none;
    }
    .news {
      display: flex;
      height: 120px;
      width: 600px;
      margin: 0 auto;
      padding: 20px 0;
      cursor: pointer;
    }
    .news .left {
      flex: 1;
      display: flex;
      flex-direction: column;
      justify-content: space-between;
      padding-right: 10px;
    }
    .news .left .title {
      font-size: 20px;
    }
    .news .left .info {
      color: #999999;
    }
    .news .left .info span {
      margin-right: 20px;
    }
    .news .right {
      width: 160px;
      height: 120px;
    }
    .news .right img {
      width: 100%;
      height: 100%;
      object-fit: cover;
    }
  </style>
</head>
<body>

  <div id="app">
    <ul>
      <li  v-for="(item,index) in list" :key="item.id" class="news">
        <div class="left">
          <div class="title">{{item.title}}</div>
          <div class="info">
            <span>{{item.source}}</span>
            <span>{{item.time}}</span>
          </div>
        </div>
        <div class="right">
          <img :src="item.img" alt="">
        </div>
      </li>
    </ul>
  </div>
  <script src="./vue.js"></script>
  <script src="./axios.js"></script>
  <script>
    // 接口地址:http://hmajax.itheima.net/api/news
    // 请求方式:get
    const app = new Vue({
      el: '#app',
      data: {
        list:[]
      },
      async created(){
        //进入页面立即发送请求
        const res = await axios.get('http://hmajax.itheima.net/api/news');
        console.log(res)
        //将数据更新到data中的list
        this.list=res.data.data
      }
    })
  </script>
</body>
</html>

输入框获取焦点


<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>示例-获取焦点</title>
  <!-- 初始化样式 -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/reset.css@2.0.2/reset.min.css">
  <!-- 核心样式 -->
  <style>
    html,
    body {
      height: 100%;
    }
    .search-container {
      position: absolute;
      top: 30%;
      left: 50%;
      transform: translate(-50%, -50%);
      text-align: center;
    }
    .search-container .search-box {
      display: flex;
    }
    .search-container img {
      margin-bottom: 30px;
    }
    .search-container .search-box input {
      width: 512px;
      height: 16px;
      padding: 12px 16px;
      font-size: 16px;
      margin: 0;
      vertical-align: top;
      outline: 0;
      box-shadow: none;
      border-radius: 10px 0 0 10px;
      border: 2px solid #c4c7ce;
      background: #fff;
      color: #222;
      overflow: hidden;
      box-sizing: content-box;
      -webkit-tap-highlight-color: transparent;
    }
    .search-container .search-box button {
      cursor: pointer;
      width: 112px;
      height: 44px;
      line-height: 41px;
      line-height: 42px;
      background-color: #ad2a27;
      border-radius: 0 10px 10px 0;
      font-size: 17px;
      box-shadow: none;
      font-weight: 400;
      border: 0;
      outline: 0;
      letter-spacing: normal;
      color: white;
    }
    body {
      background: no-repeat center /cover;
      background-color: #edf0f5;
    }
  </style>
</head>

<body>
<div class="container" id="app">
  <div class="search-container">
    <img src="https://www.itheima.com/images/logo.png" alt="">
    <div class="search-box">
      <input type="text" v-model="words" id="inp">
      <button>搜索一下</button>
    </div>
  </div>
</div>

<script src="./vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      words: ''
    },
    //等输入框渲染完成,输入框获取焦点
    mounted(){
      document.querySelector("#inp").focus()
    }
  })
</script>

</body>

</html>

工程化开发&脚手架vue CLI

在这里插入图片描述
在这里插入图片描述

组件化开发&根组件

在这里插入图片描述

局部注册

在这里插入图片描述
在这里插入图片描述
新建components局部文件夹,在里面编写局部组件
在这里插入图片描述
编写一个头部局部组件

<template>
  <div class="hm-header">
    我是header
  </div>
</template>

<script>
export default {

}
</script>

<style>
    .hm-header{
        height: 100px;
        line-height: 100px;
        text-align:center;
        font-size: 30px;
    }
</style>

然后引入局部组件使用

<template>
  <div class="App">
    <!-- 头部组件 -->
    <HmHeader></HmHeader>
    <!-- 主体组件 -->
    <!-- 底部组件 -->
  </div>
</template>

<script>
import HmHeader from './components/HmHeader.vue';
export default {
  // 使用变量
  components:{
    // 组件名:组件对象
    HmHeader:HmHeader
  }
}
</script>

<style>
  .App{
    width: 600px;
    height: 700px;
    background-color: aqua;
    margin:0 auto;
    padding:1 ;
  }
</style>

全局注册组件

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在main.JS进行全局注册

// 导入全局组件
import HmButton from './components/HmButton.vue';
Vue.config.productionTip = false
// 进行全局注册
Vue.component('HmButton',HmButton)

直接引入

<template>
    <div class="hm-header">
      我是header
      <HmButton></HmButton>
    </div>
  </template>

组件样式冲突scoped

在这里插入图片描述
在这里插入图片描述
默认的style样式会作用到全局,如果不想影响全局加上scoped属性,这样只会作用于当前组件。

data是一个函数

在这里插入图片描述

组件通信

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

父传子用props方式

<template>
  <div class="app" style="border: 3px solid #000; margin: 10px">
    我是APP组件
    <!-- 1.给组件标签,添加属性方式 赋值 -->
    <Son :title="myTitle"></Son>
  </div>
</template>

<script>
import Son from "./components/Son.vue"
export default {
  name: "App",
  components: {
    Son,
  },
  data() {
    return {
      myTitle: "学前端,就来黑马程序员",
    }
  },
}
</script>

<style>
</style>
<template>
  <div class="son" style="border:3px solid #000;margin:10px">
    <!-- 3.直接使用props的值 -->
    我是Son组件 
  </div>
</template>

<script>
export default {
  name: 'Son-Child',
  // 2.通过props来接受
  props:['title']
  
}
</script>

<style>

</style>

子传父

在这里插入图片描述

<template>
  <div class="app" style="border: 3px solid #000; margin: 10px">
    我是APP组件
    <!-- 1.给组件标签,添加属性方式 赋值 -->
    <Son :title="myTitle" @changeTitle="handleChange"></Son>
  </div>
</template>

<script>
import Son from "./components/Son.vue"
export default {
  name: "App",
  components: {
    Son,
  },
  data() {
    return {
      myTitle: "学前端,就来黑马程序员",
    }
  },
  methods:{
    //3.提供处理函数
    handleChange(newTitle){
      console.log(newTitle)
    }
  }
}
</script>

<style>
</style>
<template>
  <div class="son" style="border:3px solid #000;margin:10px">
    <!-- 3.直接使用props的值 -->
    我是Son组件 
  </div>
</template>

<script>
export default {
  name: 'Son-Child',
  // 2.通过props来接受
  props:['title'],
  methods:{
      changeFn(){
        //1.通过$emit像父组件传递消息
        this.$emit('changeTitle',"船只教育")
      }
  }
  
}
</script>

<style>

</style>

prop校验

在这里插入图片描述

在这里插入图片描述

<template>
  <div class="base-progress">
    <div class="inner" :style="{ width: w + '%' }">
      <span>{{ w }}%</span>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    //设置校验类型
    w:Number
  }


  // 1.基础写法(类型校验)
  // 2.完整写法(类型、是否必填、默认值、自定义校验)
}
</script>

<style scoped>
.base-progress {
  height: 26px;
  width: 400px;
  border-radius: 15px;
  background-color: #272425;
  border: 3px solid #272425;
  box-sizing: border-box;
  margin-bottom: 30px;
}
.inner {
  position: relative;
  background: #379bff;
  border-radius: 15px;
  height: 25px;
  box-sizing: border-box;
  left: -3px;
  top: -2px;
}
.inner span {
  position: absolute;
  right: 0;
  top: 26px;
}
</style>
<template>
  <div class="app">
    <BaseProgress :w="width"></BaseProgress>
  </div>
</template>

<script>
import BaseProgress from './components/BaseProgress.vue'
export default {
  data() {
    return {
      width: 30,
    }
  },
  components: {
    BaseProgress,
  },
}
</script>

<style>
</style>

类型校验

在这里插入图片描述

非父子通信-事件总线

在这里插入图片描述

创建一个空的总线在这里插入图片描述

A组件监听事件
在这里插入图片描述
B组件监听事件
在这里插入图片描述

非父子通宵扩展-provide-inject

在这里插入图片描述
在这里插入图片描述

v-model原理

在这里插入图片描述
在这里插入图片描述

表单类组件封装&v-model简化代码

在这里插入图片描述

sync修饰符

在这里插入图片描述

ref和refs获取dom和组件

在这里插入图片描述

<template>
  <div class="app">
    <div class="base-chart-box">
      这是一个捣乱的盒子
    </div>
    <BaseChart></BaseChart>
  </div>
</template>

<script>
import BaseChart from './components/BaseChart.vue'
export default {
  components:{
    BaseChart
  }
}
</script>

<style>
.base-chart-box {
  width: 300px;
  height: 200px;
}
</style>
<template>
  <div ref="mychart" class="base-chart-box">子组件</div>
</template>

<script>
import * as echarts from 'echarts'

export default {
  mounted() {
    // 基于准备好的dom,初始化echarts实例
    // document.querySelector 会查找项目中所有的元素
    // $refs只会在当前组件查找盒子
    // var myChart = echarts.init(document.querySelector('.base-chart-box'))
    var myChart = echarts.init(this.$refs.mychart)
    // 绘制图表
    myChart.setOption({
      title: {
        text: 'ECharts 入门示例',
      },
      tooltip: {},
      xAxis: {
        data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子'],
      },
      yAxis: {},
      series: [
        {
          name: '销量',
          type: 'bar',
          data: [5, 20, 36, 10, 10, 20],
        },
      ],
    })
  },
}
</script>

<style scoped>
.base-chart-box {
  width: 400px;
  height: 300px;
  border: 3px solid #000;
  border-radius: 6px;
}
</style>

在这里插入图片描述

vue异步更新 nextTick

在这里插入图片描述
在这里插入图片描述

<template>
  <div class="app">
    <div v-if="isShowEdit">
      <input type="text" v-model="editValue" ref="inp" />
      <button>确认</button>
    </div>
    <div v-else>
      <span>{{ title }}</span>
      <button>编辑</button>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      title: '大标题',
      isShowEdit: false,
      editValue: '',
    }
  },
  methods: {
   handleEdit(){
    //1.显示输入框
    this.isShowEdit =true
    //2.让输入框获取焦点
    this.$nextTick(()=>{
      this.$refs.inp.focus()
    })
   }
  },
}
</script>

<style>
</style>

Vue 自定义指令-基础语法

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

自定义指令-封装v-loading

在这里插入图片描述

插槽-默认插槽

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

插槽-后备内容

在这里插入图片描述
在这里插入图片描述

具名插槽

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
一旦起了名字就是具名插槽,需要添加template包裹起来
在这里插入图片描述

作用域插槽

在这里插入图片描述
在这里插入图片描述

<template>
  <div>
    <MyTable :data="list">
      <template #default="obj">
        <button @click="del(obj.row.id)">删除</button>
       </template>
    </MyTable>
    <MyTable :data="list2">
    </MyTable>
  </div>
</template>

<script>
import MyTable from './components/MyTable.vue'
export default {
  data () {
    return {
      list: [
        { id: 1, name: '张小花', age: 18 },
        { id: 2, name: '孙大明', age: 19 },
        { id: 3, name: '刘德忠', age: 17 },
      ],
      list2: [
        { id: 1, name: '赵小云', age: 18 },
        { id: 2, name: '刘蓓蓓', age: 19 },
        { id: 3, name: '姜肖泰', age: 17 },
      ]
    }
  },
  components: {
    MyTable
  }
}
</script>

<template>
  <table class="my-table">
    <thead>
      <tr>
        <th>序号</th>
        <th>姓名</th>
        <th>年纪</th>
        <th>操作</th>
      </tr>
    </thead>
    <tbody v-for="(item,index) in data" :key="item.id">
      <tr>
        <td>1</td>
        <td>小张</td>
        <td>8</td>
        <td>
          <!-- 给slot标签传值 -->
          <slot :row="item"> </slot>
        </td>
      </tr>
    </tbody>
  </table>
</template>

<script>
export default {
  props: {
    data: Array,
  },
}
</script>

<style scoped>
.my-table {
  width: 450px;
  text-align: center;
  border: 1px solid #ccc;
  font-size: 24px;
  margin: 30px auto;
}
.my-table thead {
  background-color: #1f74ff;
  color: #fff;
}
.my-table thead th {
  font-weight: normal;
}
.my-table thead tr {
  line-height: 40px;
}
.my-table th,
.my-table td {
  border-bottom: 1px solid #ccc;
  border-right: 1px solid #ccc;
}
.my-table td:last-child {
  border-right: none;
}
.my-table tr:last-child td {
  border-bottom: none;
}
.my-table button {
  width: 65px;
  height: 35px;
  font-size: 18px;
  border: 1px solid #ccc;
  outline: none;
  border-radius: 3px;
  cursor: pointer;
  background-color: #ffffff;
  margin-left: 5px;
}
</style>

组件标签封装-my-tag

在这里插入图片描述

单页应用&路由

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

路由的使用

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

组件存放

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

路由封装抽离

在这里插入图片描述
wwwwwwwwwww

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值