赞
踩
目录
是一套用于构建用户界面的前端框架。
数据驱动视图
vue 会监听数据的变化,从而自动重新渲染页面的结构
双向数据绑定
MVVM
MVVM 是 vue 实现数据驱动视图和双向数据绑定的核心原理。MVVM 指的是 Model、View 和 ViewModel,
- <!-- 希望 Vue 能够控制下面的这个 div,帮我们在把数据填充到 div 内部 -->
- <div id="app">{{ username }}</div> //视图部分
-
- <!-- 1. 导入 Vue 的库文件,在 window 全局就有了 Vue 这个构造函数 -->
- <script src="./lib/vue-2.6.12.js"></script>
- <!-- 2. 创建 Vue 的实例对象 -->
- <script>
- // 创建 Vue 的实例对象
- const vm = new Vue({
- // el 属性是固定的写法,表示当前 vm 实例要控制页面上的哪个区域,接收的值是一个选择器
- el: '#app',
- // data 对象就是要渲染到页面上的数据
- data: {
- username: 'zhangsan'
- }
- })
- </script>
指令的概念
指令(Directives)是 vue 为开发者提供的模板语法,用于辅助开发者渲染页面的基本结构。
v-text 语法
- <div id="app">
- <p v-text="username"></p>
- <p v-text="gender">性别:</p>
- </div>
{{ }} 语法
- <p>姓名:{{ username }}</p>
- <p>性别:{{ gender }}</p>
v-html 语法
v-on:
@
v-on:
简写是 @
语法格式为:
- <button @click="add"></button>
-
- methods: {
- add() {
- // 如果在方法中要修改 data 中的数据,可以通过 this 访问到
- this.count += 1
- }
- }
$event
的应用场景:如果默认的事件对象 e 被覆盖了,则可以手动传递一个 $event。例如:
- <button @click="add(3, $event)"></button>
-
- methods: {
- add(n, e) {
- // 如果在方法中要修改 data 中的数据,可以通过 this 访问到
- this.count += 1
- }
- }
事件修饰符:
.prevent
阻止默认行为
<a @click.prevent="xxx">链接</a>
.stop
阻止事件冒泡
<button @click.stop="xxx">按钮</button>
- <div id="app">
- <input type="text" @keyup.esc="clearInput" @keyup.enter="commitAjax">
- </div>
- <div id="app">
- <p>用户的名字是:{{ username }}</p>
- <input type="text" v-model="username">
-
- <hr>
- <select v-model="city">
- <option value="">请选择城市</option>
- <option value="1">北京</option>
- <option value="2">上海</option>
- <option value="3">广州</option>
- </select>
- </div>
语法:
<input type="text" v-model.number="n1"> + <input type="text" v-model.number="n2"> = <span>{{ n1 + n2 }}</span>
v-if v-show
v-show
的原理是:动态为元素添加或移除 display: none
样式,来实现元素的显示和隐藏
v-if
的原理是:每次动态创建或移除元素,实现元素的显示和隐藏
在实际开发中,绝大多数情况,不用考虑性能问题,直接使用 v-if 就好了!!!
v-if 指令在使用的时候,有两种方式:
直接给定一个布尔值 true 或 false
<p v-if="true">被 v-if 控制的元素</p>
给 v-if 提供一个判断条件,根据判断的结果是 true 或 false,来控制元素的显示和隐藏
<p v-if="type === 'A'">良好</p>
- <tr v-for="(item, index) in list" :key="item.id">
- <td>{{ index }}</td>
- <td>{{ item.id }}</td>
- <td>{{ item.name }}</td>
- </tr>
- <div id="app">
- <p>message 的值是:{{ message | capi }}</p>
- </div>
- <script>
- const vm = new Vue({
- el: '#app',
- data: {
- message: 'hello vue.js'
- },
- // 过滤器函数,必须被定义到 filters 节点之下
- // 过滤器本质上是函数
- filters: {
- // 注意:过滤器函数形参中的 val,永远都是“管道符”前面的那个值
- capi(val) {
- // 字符串有 charAt 方法,这个方法接收索引值,表示从字符串中把索引对应的字符,获取出来
- // val.charAt(0)
- const first = val.charAt(0).toUpperCase()
- // 字符串的 slice 方法,可以截取字符串,从指定索引往后截取
- const other = val.slice(1)
- // 强调:过滤器中,一定要有一个返回值
- return first + other
- }
- }
- })
- </script>
- // 使用 Vue.filter() 定义全局过滤器
- Vue.filter('capi', function (str) {
- const first = str.charAt(0).toUpperCase()
- const other = str.slice(1)
- return first + other + '~~~'
- })
连续调用多个过滤器
过滤器传参
第一个参数已经固定,传参只能在第二个
过滤器仅在 vue 2.x 和 1.x 中受支持,在 vue 3.x 的版本中剔除了过滤器相关的功能。
语法格式如下:
- <div id="app">
- <input type="text" v-model="username">
- </div>
-
- <script>
- const vm = new Vue({
- el: '#app',
- data: {
- username: 'admin'
- },
- // 所有的侦听器,都应该被定义到 watch 节点下
- watch: {
- // 侦听器本质上是一个函数,要监视哪个数据的变化,就把数据名作为方法名即可
- // 新值在前,旧值在后
- username(newVal,oldVal) {
- console.log(neVal,oldVal)
-
- }
- }
- })
- </script>
语法:
- watch: {
- // 侦听器本质上是一个函数,要监视哪个数据的变化,就把数据名作为方法名即可
- // 新值在前,旧值在后
- username(newVal) {
- if (newVal === '') return
- // 1. 调用 jQuery 中的 Ajax 发起请求,判断 newVal 是否被占用!!!
- $.get('请求url/' + newVal, function (result) {
- console.log(result)
- })
- }
- }
immediate 选项语法:
- <script>
- const vm = new Vue({
- el: '#app',
- data: {
- username: 'admin'
- },
- // 所有的侦听器,都应该被定义到 watch 节点下
- watch: {
- // 定义对象格式的侦听器
- username: {
- // 侦听器的处理函数
- handler(newVal, oldVal) {
- console.log(newVal, oldVal)
- },
- // immediate 选项的默认值是 false
- // immediate 的作用是:控制侦听器是否自动触发一次!
- immediate: true
- }
- }
- })
- </script>
语法: 深度侦听 、 侦听的是对象的子属性的变化
- <script>
- const vm = new Vue({
- el: '#app',
- data: {
- // 用户的信息对象
- info: {
- username: 'admin',
- address: {
- city: '北京'
- }
- }
- },
- // 所有的侦听器,都应该被定义到 watch 节点下
- watch: {
- /* info: {
- handler(newVal) {
- console.log(newVal)
- },
- // 开启深度监听,只要对象中任何一个属性变化了,都会触发“对象的侦听器”
- deep: true
- } */
- // 如果要侦听的是对象的子属性的变化,则必须包裹一层单引号
- 'info.username'(newVal) {
- console.log(newVal)
- }
- }
- })
- </script>
- <script>
- // 创建 Vue 实例,得到 ViewModel
- var vm = new Vue({
- el: '#app',
- data: {
- // 红色
- r: 0,
- // 绿色
- g: 0,
- // 蓝色
- b: 0
- },
- methods: {
- // 点击按钮,在终端显示最新的颜色
- show() {
- console.log(this.rgb)
- }
- },
- // 所有的计算属性,都要定义到 computed 节点之下
- // 计算属性在定义的时候,要定义成“方法格式”
- computed: {
- // rgb 作为一个计算属性,被定义成了方法格式,
- // 最终,在这个方法中,要返回一个生成好的 rgb(x,x,x) 的字符串
- rgb() {
- return `rgb(${this.r}, ${this.g}, ${this.b})`
- }
- }
- });
特点:
好处:
选择2.X
选择
assets 文件夹:存放项目中用到的静态资源文件,例如:css 样式表、图片资源
components 文件夹:程序员封装的、可复用的组件,都要放到 components 目录下
main.js 是项目的入口文件。整个项目的运行,要先执行 main.js
App.vue 是项目的根组件。
vue 规定:每个组件对应的模板结构,需要定义到 <template> 节点中。
- <script>
- // 默认导出。这是固定写法!
- export default {
- // data 数据源
- // 注意:.vue 组件中的 data 不能像之前一样,不能指向对象。
- // 注意:组件中的 data 必须是一个函数
- data() {
- // 这个 return 出去的 { } 中,可以定义数据
- return {
- username: 'admin'
- }
- },
- methods: {
- chagneName() {
- // 在组件中, this 就表示当前组件的实例对象
- console.log(this)
- this.username = '123'
- }
- },
- // 当前组件中的侦听器
- watch: {},
- // 当前组件中的计算属性
- computed: {},
- // 当前组件中的过滤器
- filters: {}
- }
- </script>
使用组件的三个步骤
步骤1:在<script> 节点中使用 import 语法导入需要的组件
import Left from '@/components/Left.vue'
- // 2. 注册组件
- components: {
- Left,
- Right,
- Test
- }
- <div class="box">
- <!-- 渲染 Left 组件和 Right 组件 -->
- <!-- 3. 以标签形式,使用注册好的组件 -->
- <Left></Left>
- <Right></Right>
- </div>
vscode中配置@路径提示插件 可以参看网上教程 注意:开发的那个项目,就定位到那个项目,然后用vscode打开。(不要有与这个项目无关的文件),不然@路径提示将失效
在 vue 项目的 main.js 入口文件中,通过 Vue.component() 方法,可以注册全局组件。示例代码如下:
- // 导入需要被全局注册的那个组件
- import Count from '@/components/Count.vue'
- //参数一:注册名称 参数二:需要注册全局的哪个组件
- Vue.component('MyCount', Count)
props: ['自定义属性']
<MyCount :init="6"></MyCount>
加 : 为数值 不加为字符串
- data() {
- return {
- // 把 props 中的 init 值,转存到 count 上
- count: this.init
- }
- }
- props: {
- // 自定义属性A : { /* 配置选项 */ },
- // 自定义属性B : { /* 配置选项 */ },
- // 自定义属性C : { /* 配置选项 */ },
- init: {
- // 如果外界使用 Count 组件的时候,没有传递 init 属性,则默认值生效
- default: 0,
- // init 的值类型必须是 Number 数字
- type: Number,
- // 必填项校验
- required: true
- }
- },
默认情况下,写在 .vue 组件中的样式会全局生效,因此很容易造成多个组件之间的样式冲突问题。
解决组件样式冲突的问题
<style lang="less" scoped>
- // h5[data-v-3c83f0b7]
- // [data-v-3c83f0b7] h5
-
- // 当使用第三方组件库的时候,如果有修改第三方组件默认样式的需求,需要用到 /deep/
- /deep/ h5 {
- color: pink;
- }
注意:/deep/ 是 vue2.x 中实现样式穿透的方案。在 vue3.x 中推荐使用 :deep() 替代 /deep/
- //父组件
- <Left :msg="message" :user="userinfo"></Left>
-
-
- data() {
- return {
- message: 'hello',
- userinfo: { name: 'zs', age: 18 },
-
- }
- //子组件
- <p>msg 的值是:{{ msg }}</p>
- <p>user 的值是:{{ user }}</p>
-
-
-
- props: ['msg', 'user']
-
-
- //子组件
- export default {
- data() {
- return {
- // 子组件自己的数据,将来希望把 count 值传给父组件
- count: 0
-
- }
- },
-
- methods: {
- add() {
- // 让子组件的 count 值自增 +1
- this.count += 1
- // 把自增的结果,传给父组件 定义事件numchange名字
- this.$emit('numchange', this.count)
- }
- }
- //父组件
-
- <Right @numchange="getNewCount"></Right>
-
- data() {
- return {
-
- // 定义 countFromSon 来接收子组件传递过来的数据
- countFromSon: 0
- }
- },
-
- methods: {
- // 获取子组件传递过来的数据
- getNewCount(val) {
- console.log('numchange 事件被触发了!', val)
- this.countFromSon = val
- }
- }
- import Vue from 'vue'
-
- export default new Vue()
- <button @click="send">发给 Right</button>
-
- // 1. 导入 eventBus.js 模块
- import bus from './eventBus.js'
-
- export default {
- data() {
- return {
- str: `hello`
- }
- },
- methods: {
- send() {
- // 2. 通过 eventBus 来发送数据
- bus.$emit('share', this.str)
- }
- }
- // 1. 导入 eventBus.js 模块
- import bus from './eventBus.js'
-
- export default {
- data() {
- return {
- msgFromLeft: ''
- }
- },
- created() {
- // 2. 为 bus 绑定自定义事件
- bus.$on('share', val => {
- this.msgFromLeft = val
- })
- }
- }
生命周期 & 生命周期函数
- // created 生命周期函数,非常常用。
- // 经常在它里面,调用 methods 中的方法,请求服务器的数据。
- // 并且,把请求到的数据,转存到 data 中,供 template 模板渲染的时候使用!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。