Vue基本语法

一、Vue 中应用和组件的基本概念

1. vue的导入

<script src="https://unpkg.com/vue@next"></script>

2. MVVM 设计模式

  • MVVM 设计模式,M -> Model 数据, V -> View 视图, VM -> ViewModel 视图数据连接层。

3. 创建一个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>
    <script src="https://unpkg.com/vue@next"></script>
</head>

<body>
    <div id="root"></div>
    <script>
        // createApp 表示创建一个 Vue 应用, 存储到 app 变量中
        // 传入的参数表示,这个应用最外层的组件,应该如何展示 
        const app = Vue.createApp({
            data() {
                return {
                    message: 'hello world'
                }
            },
            template: "<div>{{message}}</div>"
        });
        // vm 代表的就是 Vue 应用的根组件
        // mount的作用是:用vue应用根组件的模板渲染结果去替换指定DOM元素的innerHTML内容
        const vm = app.mount('#root');
    </script>
</body>

</html>

二、理解Vue中的生命周期函数

1. beforeCreate

  • 在实例生成之前会自动执行的函数。

2. created 

  • 在实例生成之后会自动执行的函数。
  • 意味着以下内容已被配置完毕:数据侦听、计算属性、方法、事件/侦听器的回调函数。
  • 但是此时dom还没有被挂载。该阶段允许执行http请求操作。

补充

  • ajax请求可以在created以及mounted中。

  • 但是,当请求在created中时,此时视图中的dom没有被渲染出来,拿不到真实的dom

  • 而在mounted中,此时dom已经渲染出来了,所以可以直接操作dom。

  • 注意:在服务端渲染不支持mounted,所以在服务端渲染的情况下统一使用created。
  • 不考虑服务器端渲染,一般选在 mounted 周期内请求数据,因为这个周期开始时,当前组件已经被挂载到真实的元素上了。

3. beforeMount

  • 在组件内容被渲染到页面之前自动执行的函数。

4. mounted

  • 在组件内容被渲染到页面之后自动执行的函数。

5.  beforeUpdate

  • 当data中的数据发生变化时会自动执行的函数。

6. updated

  • 当data中的数据发生变化,同时页面完成更新后,会执行的函数。

7. beforeUnmount

  • 在卸载组件实例之前,自动执行的函数。

8. unmounted

  • 在卸载组件实例之后,dom完全销毁,自动执行的函数。

  • 应用API:unmount 卸载应用实例的根组件。

示例:

<!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://unpkg.com/vue@next"></script>
</head>

<body>
    <div id="root"></div>
    <script>
        const app = Vue.createApp({
            data() {
                return {
                    message: 'hello'
                };
            },
            methods: {
                showMessage() {
                    console.log(document.getElementById('root').innerHTML);
                }
            },
            beforeCreate() {
                console.log('beforeCreate:实例化生成之前。');
            },
            created() {
                console.log('created:实例化生成之后');
            },
            beforeMount() {
                console.log('beforeMount:组件内容被渲染到页面之前。');
                this.showMessage();
            },
            mounted() {
                console.log('mounted:组件内容被渲染到页面之后');
                this.showMessage();
            },
            beforeUpdate() {
                console.log('beforeUpdate:当data中的数据发生变化时会自动执行的函数');
                this.showMessage();
            },
            updated() {
                console.log('updated:当data中的数据发生变化,同时页面完成更新后,会执行的函数。');
                this.showMessage();
            },
            beforeUnmount() {
                console.log('beforeUnmount:在卸载组件实例之前,自动执行的函数。');
                this.showMessage();
            },
            unmounted() {
                console.log('unmounted:在卸载组件实例之后,dom完全销毁,自动执行的函数。');
                this.showMessage();
            },
            template: "<div>{{message}}</div>"
        });
        const vm = app.mount('#root');
    </script>
</body>

</html>

三、常用模板语法

1. 插值表达式

  • {{}} :插值表达式,里面可以写js的表达式。

2. v-html 指令

  • v-html:更新元素的 innerHTML,内容按普通 HTML 插入。
  • 和插值表达式一起使用时,v-html的内容会覆盖插值表达式的内容。
data(){
    return {
        message: '<strong>hello</strong>'
    }
},
template: "<div v-html='message'></div>"

3. v-bind 指令

  • v-bind:缩写为“  ”,用于动态地绑定一个或多个 attribute。
message: '666'
template: "<div v-bind:title='message'>hello</div>"

  • 在绑定 class 或 style attribute 时,支持其它类型的值,如数组或对象。
  • 在绑定 prop 时,prop 必须在子组件中声明。
  • 没有参数时,可以绑定到一个包含键值对的对象。
<!-- 绑定 attribute -->
<img v-bind:src="imageSrc" />

<!-- 动态 attribute 名 -->
<button v-bind:[key]="value"></button>

<!-- 内联字符串拼接 -->
<img :src="'/path/to/images/' + fileName" />

<!-- class 绑定 -->
<div :class="{ red: isRed }"></div>
<div :class="[classA, classB]"></div>
<div :class="[classA, { classB: isB, classC: isC }]"></div>

<!-- style 绑定 -->
<div :style="{ fontSize: size + 'px' }"></div>
<div :style="[styleObjectA, styleObjectB]"></div>

<!-- 绑定一个全是 attribute 的对象 -->
<div v-bind="{ id: someProp, 'other-attr': otherProp }"></div>

<!-- prop 绑定。"prop" 必须在 my-component 声明 -->
<my-component :prop="someThing"></my-component>

<!-- 将父组件的 props 一起传给子组件 -->
<child-component v-bind="$props"></child-component>

4. v-once 指令

  • v-once:只渲染元素和组件一次(使用时不需要表达式)。
message: '666'
template: `<div v-once>{{message}}</div>`

  • 注:改变message的值,DOM不会重新渲染。

5. v-if 指令

  • v-if:根据表达式的真假值来有条件地渲染元素。
show: true
template: `<div v-if='show'>hello</div>`

7. v-on 指令

  • v-on:缩写@,用于绑定事件监听。
data() {
    return {
        message: 'hello'
    }
},
methods: {
    handleClick() {
        this.message = '666666';
    }
},
template: `<div v-on:click='handleClick'>{{message}}</div>`

  • 事件修饰符.prevent - 调用 event.preventDefault()

template: `<a href='https://www.baidu.com' @[event].prevent='handleClick'></a>`

8. 动态属性

  • 动态属性:使用 [] 包裹属性,用于动态改变属性名。
data() {
    return {
        message: 'hello',
        event: 'click',
        name: 'title'
    }
},
methods: {
    handleClick() {
        this.message = '666666';
    }
},
template: `<div 
            :[name]='message' 
            v-on:[event]='handleClick'>
            {{message}}
        </div>`

  • 改变 name

  • 改变 event 

四、数据、方法、计算属性和侦听器

1. data 选项

  • data:类型 Function ,该函数返回组件实例的 data 对象。
  • 实例创建之后,可以通过 vm.$data 访问原始数据对象。
  • 组件实例也代理了 data 对象上所有的 property,因此访问 vm.a 等价于访问 vm.$data.a
data() {
    return {
        a: 'hello',
    }
}

2. methods 选项

  • methods:类型 {} ,用于定义一些方法,如:事件触发时执行的函数。
data() {
    return {
        a: 'hello',
    }
},
methods: {
    handleClick(str1){
        this.a = str1;
    }
},
template: `<div @click='handleClick(66666)'>{{a}}</div>`
  • this 指向vue实例(前提:不是箭头函数)。
  • 只要页面重新渲染,调用方法将总会再次执行函数。
data() {
    return {
        a: 'hello',
    }
},
methods: {
    showTime(){
        now = Date.now();
        console.log(`now: ${now}`);
        return now;
    }
},
template: `<div>{{a}}--{{showTime()}}</div>`

3. computed选项

  • computed:类型 {} ,计算属性的结果会被缓存,只有当依赖的响应式 property 变化时才会重新计算。
  • 定义时必须要有 return,否则使用时无法接收到属性的值。
  • 使用时不需要加(),直接用属性名。
data() {
    return {
        a: 'hello',
        count: 1
    }
},
computed: {
    add() {
        return this.count += 1;
    }
},
methods: {
    showTime() {
        now = Date.now();
        console.log(`now: ${now}`);
        return now;
    }
},
template: `<div>{{a}}--{{showTime()}}--{{add}}</div>`

4. watch选项

  • watch:类型 {} ,侦听响应式 property的变化。
  • 可以得到改变之后的值改变之前的值
  • 使用 watch 选项允许我们执行异步操作 (访问一个 API),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这些都是计算属性无法做到的。
price: 5
watch: {
    price(current, prev){
        setTimeout(()=>console.log(current, prev),1000);
    }
}

5. computed、methods和watch的区别

5.1 computed 和 methods

  • computed是计算属性,methods是方法,都可以实现对 data 中的数据加工后再输出。
  • 不同的是 computed 计算属性是基于它们的依赖进行缓存的,计算属性 computed 只有在它的相关依赖发生改变时才会重新求值。
  • 而对于methods只要页面发生重新渲染,methods 调用总会执行该函数。

5.2 computed 和 watch

  • 异同:
    • 它们都是vue对监听器的实现,只不过computed主要用于对同步数据的处理
    • watch则主要用于观测某个值的变化去完成一段开销较大的复杂业务逻辑,可处理异步操作
  • 运用场景:
    • 当我们需要进行数值计算时,并且依赖于其他数据时,应该使用computed
    • 当我们需要在数据变化时执行异步或者开销较大的操作时,应该使用watch

四、样式绑定语法

1. 通过class改变样式

1.1 值为字符串

<!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://unpkg.com/vue@next"></script>
    <style>
        .red {
            color: red;
        }

        .green {
            color: green;
        }
    </style>
</head>

<body>
    <div id="root"></div>
    <script>
        const app = Vue.createApp({
            data() {
                return {
                    classString: 'red'
                }
            },
            template: `<div :class='classString'>hello</div>`
        });
        const vm = app.mount('#root');
    </script>
</body>

</html>

1.2 值为对象

data() {
    return {
        classObject: { red: true, green: false }
    }
},
template: `<div :class='classObject'>hello</div>`

1.3 值为数组

data() {
    return {
        classArray: ['red', 'green']
    }
},
template: `<div :class='classArray'>hello</div>`

1.4 包含子组件的情况 

当子组件只有一个元素时:

const app = Vue.createApp({
    data() {
        return {
            classString: 'red',
            classObject: { red: true, green: false },
            classArray: ['red', 'green']
        }
    },
    template: `
        <div :class='classArray'>hello</div>
        <demo class='red' />
    `
});
app.component('demo', {
    template: `
        <div>one</div>
    `
})

当子组件有多个组件时时,需要用到 $attrs:

data() {
    return {
        classString: 'red',
        classArray: ['red', 'green']
    }
},
template: `
    <div :class='classArray'>
        hello
        <demo :class='classString'/>
    </div>
`
});
app.component('demo', {
template: `
    <div :class='$attrs.class'>one</div>
    <div :class='$attrs.class'>two</div>
    <div class='green'>three</div>
`
})

2. 通过行内样式 style 修改样式

  • 值同样也有三种形式:字符串、对象、数组。
data() {
    return {
        styleString: 'color: blue',
        styleObject: {
            color: 'orange',
            background: 'gold'
        },
        styleArray: ['color: blue', 'background: cyan']
    }
},
template: `
    <div :style='styleString'>one</div>
    <div :style='styleObject'>two</div>
    <div :style='styleArray'>three</div>
`

五、条件渲染

1. v-if 指令

  • 表达式为真值渲染元素,为假值销毁元素。
const app = Vue.createApp({
    data() {
        return {
            show: true
        }
    },
    template: `
        <div v-if='show'>hello</div>
    `
});
const vm = app.mount('#root');

2. v-show 指令

  • 表达式为真值正常渲染元素,为假值时元素会添加 style="display: none;" 属性。
template: `
    <div v-show='show'>hello</div>
`

3. v-else 指令

  • 不需要表达式

  • 限制:前一兄弟元素必须有 v-if 或 v-else-if

  • 用法

    为 v-if 或者 v-else-if 添加“else 块”。

data() {
    return {
        show: false
    }
},
template: `
    <div v-if='show'>if</div>
    <div v-else>else</div>
`

4. v-else-if 指令

  • 限制:前一兄弟元素必须有 v-if 或 v-else-if

  • 用法

    表示 v-if 的“else if 块”。可以链式调用。

data() {
    return {
        showOne: false,
        showTwo: true
    }
},
template: `
    <div v-if='showOne'>if</div>
    <div v-else-if='showTwo'>else-if</div>
`

六、列表循环渲染

1. v-for 指令

  • 可以使用v-for的类型:Array | Object | number | string | Iterable。
  • 作用:基于源数据多次渲染元素或模板块。

1.1 数组的循环渲染

  • 接受的数据依次为:值、索引
const app = Vue.createApp({
data() {
    return {
        listArray: ['a', 'b', 'c'],
    }
},
template: `
    <div v-for='(item, index) in listArray'>
        {{index}}--{{item}}        
    </div>
`
});
const vm = app.mount('#root');

1.2 对象的循环渲染

  • 接受的数据依次为:值、键名、索引
data() {
    return {
        listObject: {
            name: 'hy',
            age: 18,
            sex: 'male'
        }
    }
},
template: `
    <div v-for='(item, key, index) in listObject'>
        {{index}}--{{key}}--{{item}}        
    </div>
`

1.3 number的循环渲染

  • 接受的数据依次为:值、索引
  • 从1开始。
template: `
    <div v-for='(item, index) in 3'>
        {{index}}--{{item}}        
    </div>
`

1.4 特殊属性 key 

  • key的作用就是更新组件时判断两个节点是否相同,相同就复用,不相同就删除旧的创建新的。
  • 如果不添加key,组件默认都是就地复用,不会删除添加节点,只是改变列表项中的文本值。
  • 建议尽可能在使用 v-for 时提供 key attribute,除非遍历输出的 DOM 内容非常简单,或者是刻意依赖默认行为以获取性能上的提升。
  • 不要使用对象或数组之类的非基本类型值作为 v-for 的 key。请用字符串或数值类型的值。
template: `
    <div v-for='(item, index) in 3' :key='index'>
        {{index}}--{{item}}        
    </div>
`

2. 数组、对象更新检测

2.1 使用数组的变更函数

  • push():插入最后一项。

  • pop():删除最后一项。

  • shift():删除第一项。
  • unshift():插入第一项。

2.2 直接替换数组

2.3 直接更新数组的内容

 2.4 直接添加对象的内容

3. v-if 与 v-for 同时使用

  •  v-if 的优先级比 v-for 要高,不能将它们写在一起。
  • 可以使用 <template></template> 进行实现。
  • template标签,HTML5提供的新标签,一个父容器,页面加载时会隐藏
data() {
    return {
        listObject: {
            name: 'hy',
            age: 18,
            sex: 'male'
        }
    }
},
template: `
    <template v-for='(item, key) in listObject' :key='key'>
        <div v-if="key !== 'sex'">
            {{key}}--{{item}}
        </div>
    </template>
`

七、事件绑定

1. 接受事件对象

1.1 不传参数时

data() {
    return {count: 0}
},
methods: {
    handleClick(event){
        console.log(event.target);
        this.count += 1;
    }
},
template: `
    <div>
        {{count}}
        <button @click='handleClick'>add</button>
    </div>

`

1.2 传参数时

  • 使用 $event 传递原生DOM事件对象
methods: {
    handleClick(num, event){
        console.log(event.target);
        this.count += num;
    }
},
template: `
    <div>
        {{count}}
        <button @click='handleClick(2, $event)'>add</button>
    </div>

`

2. 多事件处理器

  • 事件处理程序中可以有多个方法,这些方法由逗号运算符分隔。
  • 注意:在绑定事件时,函数名后面要加上括号()
methods: {
    handleClick1(){
        console.log(++this.count);
    },
    handleClick2(){
        console.log(--this.count);
    }
},
template: `
    <div>
        {{count}}
        <button @click='handleClick1(), handleClick2()'>add</button>
    </div>

`

3. 事件修饰符

  • 修饰符是由点开头的指令后缀来表示的。
  • .stop:阻止事件传播。
  • .prevent:阻止事件默认行为。
  • .capture:使用事件捕获模式。
  • .self:点击自己才触发。
  • .once:只触发一次。
  • .passive:常用于提升移动端性能。
<!-- 阻止单击事件继续传播 -->
<a @click.stop="doThis"></a>

<!-- 提交事件不再重载页面 -->
<form @submit.prevent="onSubmit"></form>

<!-- 添加事件监听器时使用事件捕获模式 -->
<!-- 即内部元素触发的事件先在此处理,然后才交由内部元素进行处理 -->
<div @click.capture="doThis">...</div>

<!-- 只当在 event.target 是当前元素自身时触发处理函数 -->
<!-- 即事件不是从内部元素触发的 -->
<div @click.self="doThat">...</div>

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

<!-- 滚动事件的默认行为 (即滚动行为) 将会立即触发   -->
<!-- 而不会等待 `onScroll` 完成,提升scroll的性能  -->
<div @scroll.passive="onScroll">...</div>

4. 按键修饰符

  • 在监听键盘事件时,我们经常需要检查详细的按键。
  • 常用的有:entertabdelete (捕获“删除”和“退格”键)、escspaceupdownleftright。
<!-- 只有在 `key` 是 `Enter` 时调用 `vm.submit()` -->
<input @keyup.enter="submit" />

5. 其他修饰符

八、表单中双向绑定指令的使用

  • v-model指令:在表单控件或者组件上创建双向绑定。

1. input(text)文本中的双向绑定

  • 不用写value,绑定的数据默认就是value。
data() {
    return {message: 'hello'}
},
template: `
    <div>
        <input v-model='message'/>
        {{message}}
    </div>
`

2. textarea 多行文本中的双向绑定

  • 不用写value,绑定的数据默认就是value。
  • 在文本区域插值不起作用,应该使用 v-model 来代替。
<textarea v-model='message'/>    // 正确写法

<textarea>{{message}}</textarea>    // 错误写法

3. input(Checkbox)复选框中的双向绑定

  • 单个复选框,绑定的值为布尔值。
  • checkbox 默认的value是 “on”不会改变,checked 值会随着是否选中变为true或false。
data() {
    return {message: true}
},
template: `
    <div>
        <input type='checkbox' v-model='message' />
        {{message}}
    </div>
`

  • 多个复选框,绑定到同一个数组(需要给复选框设置value值)。
  • 同样value值设置之后不会发生改变,checked 值会随着是否选中变为true或false。
  • 绑定的message数据会在选中时向数组末尾推入选中元素的value值,反之取消选中时会从数组末尾推出该元素的value值。
data() {
    return {message: []}
},
template: `
    <div>
        <input type='checkbox' v-model='message' value='xm'/>
        <input type='checkbox' v-model='message' value='hw'/>
        <input type='checkbox' v-model='message' value='ip'/>
        {{message}}
    </div>
`

  • 修改选中值和取消值,需要添加 true-value 和 false-value 属性。
  • 这里的 true-value 和 false-value 属性并不会影响输入控件的 value 属性。
  • 这个设置在单个复选框模式中才有效。
data() {
    return {
        message: 'yes'
    }
},
template: `
    <div>
        <input type='checkbox' v-model='message' true-value='yes' false-value='no' value='666'/>
        {{message}}
    </div>
`

4. input (Radio) 单选框中的双向绑定

  • message初始给空字符串即可,如果给数组也会变成字符串。
data() {
    return {message: ''}
},
template: `
    <div>
        <input type='radio' v-model='message' value='xm'/>
        <input type='radio' v-model='message' value='hw'/>
        <input type='radio' v-model='message' value='ip'/>
        {{message}}
    </div>
`

5. select 选择框中的双向绑定

  • 注意是在 select 标签上添加 v-model 指令。
  • 单选时
data() {
    return {message: ''}
},
template: `
    <div>
        <select v-model='message'>
            <option disabled value="">Please select one</option>
            <option>A</option>
            <option>B</option>
            <option>C</option>
        </select>
        {{message}}
    </div>
`

  • 多选时,在 select 标签上添加 multiple 属性,绑定到一个数组。
data() {
    return {message: []}
},
template: `
    <div>
        <select v-model='message' multiple>
            <option>A</option>
            <option>B</option>
            <option>C</option>
            <option>666666</option>
        </select>
        {{message}}
    </div>
`

  •  用 v-for 渲染的动态选项
data() {
    return {
        message: [],
        // 字符串写法
        // options:[
        //     'A','B','C'
        // ]
        // 对象写法
        options: [
            {value:'A',text:'A'},
            {value:'B',text:'B'},
            {value:'C',text:'C'}
        ]
    }
},
template: `
    <div>
        <select v-model='message' multiple>
            <option v-for='item in options' :value=item.value>{{item.text}}</option>
        </select>
        {{message}}
    </div>
`

6. 修饰符

6.1 .lazy 

  • 在默认情况下,v-model 在每次 input 事件触发后将输入框的值与数据进行同步。
  • 添加 lazy 修饰符,从而转为在 change 事件之后进行同步(回车或失去焦点)。
<input v-model.lazy='message'/>

6. 2 .number

  • number 修饰符可以将用户的输入值转为数值类型。
template: `
    <div>
        <input v-model.number='message' type="number"/>
        {{typeof message}}
    </div>
`

6.3 .trim

  • trim 修饰符会自动过滤用户输入的首尾空白字符
data() {
    return {
        message: ''
    }
},
template: `
    <div>
        <input v-model.trim='message'/>
        {{message}}
    </div>
`

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值