第二块 基础Vue

 

主要是了解一下Vue的基础语法

由于渲染问题,代码展示有误,还请麻烦点击按钮进入GitHub查看,详细说明见第0块


1.MVVM设计模式

m -> model数据

v -> view 视图

vm -> viewModel数据视图层

1.1 小案例 - 操作数据视图层

<body>
    <div id="root"></div>
</body>

<!-- 格式化代码 ALT+SHIFT+F -->
<script>
    // 创建一个Vue实例对象(全局常量)
    const app = Vue.createApp({
        data() {
            return {
                message: "hello world"
            }
        },
        template:"<div></div>"
    });
    //vm 代表就是vue应用的根组件
    const vm = app.mount('#root');// 作用与id = root元素
</script>

2.生命周期函数

2.1 说明:在某一时刻自动执行的函数

3.常用模板语法讲解

3.1 v-html 直接显示html

<!-- 格式化代码 ALT+SHIFT+F -->
<script>
    const app = Vue.createApp({
        data() {
            return {
                message: "<strong>hello world</strong>"
            }
        },
        template:`<div v-html="message"></div>`
    });

    const vm = app.mount('#root');
</script>

3.2 v-bind = ”:“ 标签属性值绑定数据

绑定title

<body>
    <div id="root"></div>
</body>

<!-- 格式化代码 ALT+SHIFT+F -->
<script>
    const app = Vue.createApp({
        data() {
            return {
                message: "hello world"
            }
        },
        template:`<div v-bind:title="message">hello </div>`
    });

    const vm = app.mount('#root');
</script>
</html>

绑定disabled

<body>
    <div id="root"></div>
</body>

<!-- 格式化代码 ALT+SHIFT+F -->
<script>
    const app = Vue.createApp({
        data() {
            return {
                disable: true
            }
        },
        template:`<input v-bind:disable="disable"/>`
    });

    const vm = app.mount('#root');
</script>
</html>

3.3 v-once 只渲染一次

<!-- 格式化代码 ALT+SHIFT+F -->
<script>
    const app = Vue.createApp({
        data() {
            return {
                message: "hello world"
            } 
        },
        template:`<div v-once></div>`
    });

    const vm = app.mount('#root');
</script>
</html>

3.4 v-if 选择

<!-- 格式化代码 ALT+SHIFT+F -->
<script>
    const app = Vue.createApp({
        data() {
            return {
                message: "hello world",
                show:false
            } 
        },
        template:`<div v-if="show"></div>`
    });

    const vm = app.mount('#root');
</script>
</html>

3.5 v-on:click=”func” = “@” 绑定函数

<!-- 格式化代码 ALT+SHIFT+F -->
<script>
    const app = Vue.createApp({
        data() {
            return {
                message: "hello world",
                name: 'title',
                event: 'mouseenter'
            }
        },
        methods: {
            handleClick() {
                alert('click')
            }
        },
        // @ v-on:
        // : v-bind
        // [ ] 取值
        template: `
        <div 
        @[event]="handleClick"
        :[name]="message">
            
        </div>`
    });

    const vm = app.mount('#root');
</script>

3.6 事件修饰符(form表单阻止跳转)

<!-- 格式化代码 ALT+SHIFT+F -->
<script>
    const app = Vue.createApp({
        data() {
            return {
                message: "hello world"
            }
        },
        methods: {
            handleClick(e) {
                e.preventDefault();
                alert('click1 阻止成功');
            },
            handleClick2() {
                alert('click2 阻止成功');
            }
        },
        template: `
        <form action="https://www.baidu.com" @click="handleClick">
            <button type="submit">提交</button>
        </form>

        <form action="https://www.baidu.com" @click.prevent="handleClick2">
            <button type="submit">提交</button>
        </form>
        `
    });

    const vm = app.mount('#root');
</script>

4.关于method中箭头函数和函数

4.1 this指向问题

箭头函数 -> this指向顶层windows

普通函数 -> this指向vue实例

<!-- 格式化代码 ALT+SHIFT+F -->
<script>
    const app = Vue.createApp({
        data() {
            return {
                message: "hello world"
            } 
        },
        methods:{
            handleClick(){
                // this指向vue实例
                console.log(this.message);
            },
            handleClick2:()=>{
                // this指向顶层windows
                console.log(this);
            }
        },
        template: `<div></div>`
    });
    const vm = app.mount('#root');
</script>

4.2 参数传递

<!-- 格式化代码 ALT+SHIFT+F -->
<script>
    const app = Vue.createApp({
        data() {
            return {
                message: "hello world"
            } 
        },
        methods:{
            formatString(string){
                return string.toUpperCase();
            }
        },
        template: `<div></div>`
    });
    const vm = app.mount('#root');
</script>

4.3 计算属性(computed)和函数的区别

计算属性(computed) -> 只有当计算内容变更时才会重新执行

函数计算 -> 只要页面重新渲染就会改变

计算属性内部会有缓存,效率高一丢丢

<!-- 格式化代码 ALT+SHIFT+F -->
<script>
    const app = Vue.createApp({
        data() {
            return {
                message: "hello world",
                price:1,
                count:5,
            } 
        },
        // 计算属性
        // 只有当计算内容变更时才会重新执行
        computed:{
            total() {
               return this.price * this.count;
            }
        },
        methods:{
            formatString(string){
                return string.toUpperCase();
            },
            // 只要页面重新渲染就会改变
            getTotal(){
                return this.price * this.count;
            }
        },
        template: `<div>,</div>`
    });
    const vm = app.mount('#root');
</script>

4.4 watch 监听

能用computed就是用computed

// 异步监听函数
watch:{
	price(){
		setTimeout(()=>{
		console.log('price change')
	},3000)
},
//获取当前的值和修改前的值
	count(current,prev){
	console.log(current)
	console.log(prev)
	}
},

5.样式绑定

普通绑定、数组绑定、对象绑定(推荐)

子类使用父类样式(:class=”$attrs.class”)

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>lesson 9</title>
  <style>
    .red {
      color: red;
    }
    .green {
      color: green;
    }
  </style>
  <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
  <div id="root"></div>
</body>
<script>
  const app = Vue.createApp({
    data() {
      return {
        classString: 'red',
        classObject: { red: false, green: true },
        classArray: ['red', 'green', {brown: false}],
        styleString: 'color: yellow;background: orange',
        // 使用对象的方式类使用css
        styleObject: {
          color: 'orange',
          background: 'yellow'
        }
      }
    },
    template: `
      <div :style="styleObject">
        Hello World
      </div>
    `
  });

  app.component('demo', {
    template: `
      <!-- 子类使用父类样式 -->
      <div :class="$attrs.class">one</div>
      <div :class="$attrs.class">two</div>
      `
  })

  const vm = app.mount('#root');
</script>
</html>

6.条件渲染

6.1 v-if 与 v-show

v-if 是直接将false的标签移DOM

v-show 是将dispaly:none

如果频繁移入移出选择v-show好一点点

<!-- 格式化代码 ALT+SHIFT+F -->
<script>
  const app = Vue.createApp({
    data() {
      return {
        show : false
      }
    },

    template: `
      <div v-if="show">
        Hello If
      </div>

      <div v-show="show">
        Hello Show
      </div>
    `
  });

  const vm = app.mount('#root');
</script>

6.2 v-if v-else-if v-else联合使用

需要连续使用

<!-- 格式化代码 ALT+SHIFT+F -->
<script>
  const app = Vue.createApp({
    data() {
      return {
        conditionOne:false,
        conditionTwo:true
      }
    },

    template: `
      <div v-if="conditionOne">Hello If</div>
      <div v-else-if="conditionTwo">Hello Else-if</div>
      <div v-else>Hello Else</div>
    `
  });

  const vm = app.mount('#root');
</script>

7.列表循环渲染

7.1 v-for 遍历数组和对象的数据

<script>
  const app = Vue.createApp({
    data() {
      return {
        listArray:['Monday','Tuesday','Wednesday'],
        // 如果listObject内部key重复则只会输出第一个
        listObject:{
            one:'Monday',
            two:'Tuesday',
            three:'Wednesday'
        }
      }
    },

    template: `
      <div>
        <div v-for="(value,index) in listArray">
             --- 
        </div>  
        <hr/>
        <div v-for="(value,key,index) in listObject">
             --  -- 
        </div>  
      </div>
    `
  });

  const vm = app.mount('#root');
</script>

7.2 修改对象和数组的数据

// 1. 使用数组的变更函数 push, pop, shift, unshift, splice, sort, reverse // this.listArray.push(‘hello’); // this.listArray.pop(); // this.listArray.shift(); // this.listArray.unshift(‘hello’); // this.listArray.reverse();

// 2. 直接替换数组

// this.listArray = [‘bye’, ‘world’]

// this.listArray = [‘bye’, ‘wolrd’].filter(item => item === ‘bye’);

// 3. 直接更新数组的内容

// this.listArray[1] = ‘hello’

// 直接添加对象的内容,也可以自动的展示出来

// this.listObject.age = 100;

// this.listObject.sex = ‘male’;

**说明:在遍历时不想展示某个数据时,可以在里面写一层div,并在外层写

<script>
  const app = Vue.createApp({
    data() {
      return {
        listArray: ['dell', 'lee', 'teacher'],
        listObject: {
          firstName: 'dell',
          lastName: 'lee',
          job: 'teacher'
        }
      }
    },
    methods: {
      handleAddBtnClick() {
        // 1. 使用数组的变更函数 push, pop, shift, unshift, splice, sort, reverse
        // this.listArray.push('hello');
        // this.listArray.pop();
        // this.listArray.shift();
        // this.listArray.unshift('hello');
        // this.listArray.reverse();

        // 2. 直接替换数组
        // this.listArray = ['bye', 'world']
        // this.listArray = ['bye', 'wolrd'].filter(item => item === 'bye');

        // 3. 直接更新数组的内容
        // this.listArray[1] = 'hello'

        // 直接添加对象的内容,也可以自动的展示出来
        // this.listObject.age = 100;
        // this.listObject.sex = 'male';
      }
    },
    // <template>是占位符可以避免多包一层div
    //
    template: `
      <div>
        <template
          v-for="(value, key, index) in listObject"
          :key="index"
        >
          <div v-if="key !== 'lastName'">
             -- 
          </div>
        </template>
        <div v-for="item in 10"></div>
        <button @click="handleAddBtnClick">新增</button>
      </div>
    `
  });

8.事件绑定

8.1 传递event、传递参数和event、绑定多个函数

<!-- 格式化代码 ALT+SHIFT+F -->
<script>
  const app = Vue.createApp({
    data() {
      return {
       number:0
      }
    },
    methods:{
        // 传毒参数
        handleClick1(num){
            this.number += num;
        },
        //默认第一个参数为event
        handleClick2(event){
            console.log(event);
            this.number += num;
        },
        //结合传递
        handleClick3(num,$event){
            console.log(event);
            this.number += num;
        },
    },
    template: `
      <div>
       
            <button @click="handleClick3(3)">点击</button>
            <!-- 绑定多个函数 -->
            <button @click="handleClick1(2),handleClick2">点击</button>
      </div>
    `
  });

8.2 事件修饰符

@click.stop 阻止冒泡

@click.self 只执行自身的

@click.prevent 阻止默认行为

@click.capture(从内到外,默认是冒泡从外到内)

@click.once 只执行一次

@scroll.passive可以提高滚动的性能

8.3 按键修饰符

@keydown.enter

@keydown.tap

@keydown.delete

@keydown.esc

@keydown.up

@keydown.down

@keydown.left

@keydown.right

8.4 鼠标修饰符

@click.left 鼠标左键

@click.right 鼠标右键

@click.middle 鼠标滚轮

@click.ctrl 按住ctrl使用

9.双向绑定

9.1 input和textarea标签的双向绑定 v-model=”xxx”

以及checkbox用法

<!-- 格式化代码 ALT+SHIFT+F -->
<script>
    const app = Vue.createApp({
        data() {
            return {
                message: [],
                isRight: true,
                choice: '',
            }
        },
        template: `
      <div>
       
       Monday    <input type="checkbox" v-model="message" value="monday" />
       Tusedat   <input type="checkbox" v-model="message" value="tusedat" />
       Wednesday <input type="checkbox" v-model="message" value="wednesday" />
      </div>
        <br/>

        
        <div>
            Monday    <input type="radio" v-model="choice" value="monday" />
            Tusedat   <input type="radio" v-model="choice" value="tusedat" />
            Wednesday <input type="radio" v-model="choice" value="wednesday" />
            </div>
        <br/>

      <div>
       
       onr   <input type="checkbox" v-model="isRight" />
       two   <input type="checkbox" v-model="isRight" />
      </div>
    `
    });

    const vm = app.mount('#root');
</script>

9.2 select选择

<!-- 格式化代码 ALT+SHIFT+F -->
<script>
    const app = Vue.createApp({
        data() {
            return {
                message: ''
            }
        },
        template: `
      <div>
       
       <select v-model="message">
        <option disabled value=''>请选择内容</option>
        <option value='A'>A</option>
        <option value='B'>B</option>
        <option value='C'>B</option>
        </select>
        </div>
        `
    });

    const vm = app.mount('#root');
</script>

9.3 读取对象

<!-- 格式化代码 ALT+SHIFT+F -->
<script>
    const app = Vue.createApp({
        data() {
            return {
                message: '',
                message1: '',
                options:[{
                    text:'A',value:{value:'A'}
                },{
                    text:'B',value:{value:'B'}
                },{
                    text:'C',value:{value:'C'}
                }]
            }
        },
        template: `
      <div>
       
       <select v-model="message">
        <option disabled value=''>请选择内容</option>
        <option value='A'>A</option>
        <option value='B'>B</option>
        <option value='C'>B</option>
        </select>
        </div>

        <br/>
        <div>
       
       <select v-model="message1" multiple>
        <option v-for="item in options" :value="item.value"></option>
        </select>
        </div>
        `
    });

    const vm = app.mount('#root');
</script>

9.4 (玩) 替换checkbox的false和true值

<body>
    <div id="root">
        
        <!-- 使用true-value 替换绑定显示的true和false -->
        <input type="checkbox" v-model="message" true-value="hello" false-value="world" />
    </div>
</body>

<!-- 格式化代码 ALT+SHIFT+F -->
<script>
    const app = Vue.createApp({
        data() {
            return {
                message: 'hello',
            }
        },
    });

    const vm = app.mount('#root');
</script>

输入控件的修饰符

<body>
    <div id="root">
        
        <!-- 快速绑定 -->
        <input v-model="message1" />
        <br/><br/><br/>
        
        <!-- 失去焦点才绑定 -->
        <input v-model.lazy="message2" />
        <br/><br/><br/>
        
        <!-- 强制数字转换,会先转换为number,再放入DOM -->
        <input v-model.number="message3" type="number"/>
        <br/><br/><br/>
        
        <!-- 去掉两头的空格,再放入DOM -->
        <input v-model.trim="message4"/>
        
    </div>
</body>

<!-- 格式化代码 ALT+SHIFT+F -->
<script>
    const app = Vue.createApp({
        data() {
            return {
                message1: 'hello',
                message2: 'hello',
                message3: 123,
                message4: 'hello',
            }
        },
    });

    const vm = app.mount('#root');
</script>

10 总结

可以感受到Vue在底层还是做了很多事情的,写标签有点像写jsp(JSTL,哈哈),双向的数据绑定我觉得是挺神奇的,event事件可操作的性也很强,还有不再为样式而写,可以“面向对象”对数值进行操作,还是很强大的。