2021-09-06

什么是 Vue.js

  • Vue.js 是目前最火的一个前端框架,React 是最流行的一个前端框架(React 除了开发网站,还可以开发手机 App, Vue 语法也是可以用于进行手机 App 开发的,需要借助于 uni-app)

  • Vue.js 是前端的主流框架之一,和 Angular.js、React.js 一起,并成为前端三大主流框架!

  • Vue.js 是一套构建用户界面的框架,只关注视图层,它不仅易于上手,还便于与第三方库或既有项目整合。(Vue 有配套的第三方类库,可以整合起来做大型项目的开发)

框架和库的区别

  • 框架:是一套完整的解决方案;对项目的侵入性较大,一改改全套
  • 库:提供某些小功能,如 swiper、jquery

Node 的 MVC 与前端框架的 MVVM 区别

  • MVC 是后端的分层开发概念;
  • MVVM 是前端视图层的概念,主要关注于 视图层分离,也就是说:MVVM把前端的视图层,分为了 三部分 Model, View , VM ViewModel

ES6

注意: 数组的新方法 forEach some filter findIndex

this.list.filter((item) => {
  // 在es6中为字符串提供新的方法
  if (item.name.includes(key)) {
    return item
  }
})

Vue 结合 axios 实现路由请求

axios 官方文档

axios实现方法:

  1. get
// 为给定 ID 的 user 创建请求
axios
  .get("/user?ID=12345")
  .then(function (response) {
    console.log(response)
  })
  .catch(function (error) {
    console.log(error)
  })
  1. post
axios
  .post("/user", {
    firstName: "Fred",
    lastName: "Flintstone",
  })
  .then(function (response) {
    console.log(response)
  })
  .catch(function (error) {
    console.log(error)
  })

Vue 的基础相关指令

基础
  • v-cloak:能够解决插值表达式闪烁的问题,只会替换自己的占位符,不会影响其他人
  • v-text:没有闪烁问题,会覆盖元素中的内容
    • 案例
      共同点:把 html 元素标签当文本输出
      <p v-colak>+++{{ msg }}++++</p> ==> +++123++++
      <h4 v-text="msg">+++</h4> ==> 123
    
  • v-html:不把 html 元素标签当文本输出,会覆盖原本元素内容
绑定

Vue 指令之 v-bind 的三种用法

  • 直接使用指令 v-bind(可以写合法的 js 表达式)
  • 使用简化指令:
  • 在绑定的时候,拼接绑定内容::title=“btnTitle + ‘, 这是追加的内容’”

v-on:事件绑定机制

  • v-on:click=“show”
  • 缩写:@click=“show”

Vue指令之 v-on的缩写和事件修饰符
事件修饰符:

  1. .stop 阻止冒泡 阻止所有冒泡行为
  2. .prevent 阻止默认事件
  3. .capture 添加事件侦听器时使用事件捕获模式(实现从外到里)
  4. (只阻止自己的冒泡行为) .self 只当事件在该元素本身(比如不是子元素)触发时触发回调
  5. .once 事件只触发一次
实例中的 data

vue 实例中调用 data 数据,必须通过 this.方法名进行访问
Vue 实例会监听自身上的 data所有数据的改变,
只要一发生变化就自动把数据同步到 html 页面中

[好处:只需要考虑数据改变,不需要考虑渲染]

样式
  1. 数组
<h1 :class="['red', 'thin']">这是一个邪恶的H1</h1>
  1. 数组中使用三元表达式
<h1 :class="['red', 'thin', isactive?'active':'']">这是一个邪恶的H1</h1>
  1. 数组中嵌套对象
<h1 :class="['red', 'thin', {'active': isactive}]">这是一个邪恶的H1</h1>
使用内联样式
  1. 直接在元素上通过 :style 的形式,书写样式对象
<h1 :style="{color: 'red', 'font-size': '40px'}">这是一个善良的H1</h1>
  1. 将样式对象,定义到 data 中,并直接引用到 :style
  • 在 data 上定义样式:
data: {
        h1StyleObj: { color: 'red', 'font-size': '40px', 'font-weight': '200' }
}
  • 在元素中,通过属性绑定的形式,将样式对象应用到元素中:
<h1 :style="h1StyleObj">这是一个善良的H1</h1>
  1. :style 中通过数组,引用多个 data 上的样式对象
  • 在 data 上定义样式:
data: {
        h1StyleObj: { color: 'red', 'font-size': '40px', 'font-weight': '200' },
        h1StyleObj2: { fontStyle: 'italic' }
}
  • 在元素中,通过属性绑定的形式,将样式对象应用到元素中:
<h1 :style="[h1StyleObj, h1StyleObj2]">这是一个善良的H1</h1>
循环与判断

v-for key 属性只能使用number string 并且只能使用 v-bind 绑定使用
在组件中或者特殊情况中,v-for 有问题 必须使用 v-for 时,指定唯一 key 值

示例:

<!-- 键值  键名  索引值 -->
<p v-for="(value,key,i) in user">
 <p> id: {{ i }}</p>
 <p> name: {{ value }}</p>
 <p> gender: {{ value.gender }}</p>
 <p>  i: {{ key }} </p>
 <p>i1: {{ i }} </p>
</p>
<p v-for="item in li2" :key="item.id">
  <input type="checkbox" name="" id="" />
  {{ item.id }} ===> {{ item.name }}
</p>

v-if:每次都会重新删除再重新创建元素
v-show:每次只是切换 display:none 性能更高
对比:

  • v-if 有较高的切换性能消耗 v-show 有较高的初始渲染消耗
  • 经常切换不要使用 v-if 如果长期不切换不要使用 v-show
过滤器

案例:

<div id="app" v-cloak>{{ msg | msgInFo('过去') | msgFooter}}</div>
<script>
  // 定义一个全局 Vue 的过滤器 msgInFo 一定要定义在Vue实例前面
  Vue.filter("msgInFo", function (ret, arg) {
    // 字符串 正则表达式 使用 全局匹配
    return ret.replace(/未来/g, arg)
  })
  Vue.filter("msgFooter", function (ret) {
    return ret + "===>" + 123465789
  })

  const vm = new Vue({
    el: "#app",
    data: {
      msg: "如果未来还能相遇,我愿给你最好的未来,让我们的未来不再遥遥无期",
    },
    methods: {},
    filters: {
      // 定义私有过滤器
    },
  })
</script>
按键修饰符

自定义按键修饰符

Vue.config.keyCodes.f2 = 113
@keyup.f2 = "方法名"
自定义指令
  • 使用 Vue.directive() 定义全局的指令 v-focus
  • 参数 1 : 指令的名称,定义指令名称不需要加 v- 前缀,
  • 调用时必须 v- 前缀 + 自定义指令名称 来进行调用
  • 参数 2: 是一个对象,这个对象身上,有一些指令相关的函数,这些函数可以在特定的阶段,执行相关的操作

案例:

Vue.directive("focus", {
  bind: function (el) {
    // 每当指令绑定到元素上的时候,会立即执行这个 bind 函数,只执行一次
    // 注意: 在每个 函数中,第一个参数,永远是 el ,表示 被绑定了指令的那个元素,这个 el 参数,是一个原生的JS对象
    // 在元素 刚绑定了指令的时候,还没有 插入到 DOM中去,这时候,调用 focus 方法没有作用
    //  因为,一个元素,只有插入DOM之后,才能获取焦点
    el.focus()
  },
  //只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
  inserted: function (el) {
    // inserted 表示元素 插入到DOM中的时候,会执行 inserted 函数【触发1次】
    el.focus()
    // 和JS行为有关的操作,最好在 inserted 中去执行,放置 JS行为不生效
  },
  //被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
  updated: function (el) {
    // 当VNode更新的时候,会执行 updated, 可能会触发多次
  },
  // VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。
})

//  自定义样式
Vue.directive("color", {
  // 样式:通过指令绑定给元素,无需管是否插入到页面,这时候浏览器自动解析 bind:写样式
  bind: function (el, binding) {
    // el.style.color = 'red'
    el.style.color = binding.value
  },
  // 行为放在 inserted 中
  inserted: function (el) {},
})
生命周期

Vue生命周期
)(./lifecycle.png)]

beforeCreate() {
//第一个生命周期 ,在执行的时候 data methods 等数据尚未初始化

},
created() {
// 第二个生命周期 在created 中已经初始化data methods ,可以从中获取数据
},
beforeMount() {
// 第三个生命周期,表示模板已经在内存中编译完成,但是尚未渲染

},
mounted() {
// 第四个生命周期 表示内存中编译完成模板,并已经完成渲染,等待使用
// 注意: mounted 是 实例创建期间的最后一个生命周期函数,当执行完 mounted 就表示,实例已经被完全创建好了,此时,如果没有其它操作的话,这个实例,就静静的 躺在我们的内存中,一动不动
},
beforeUpdate() {
// 这时候界面尚未更新,数据更新
// 得出结论: 当执行 beforeUpdate 的时候,页面中的显示的数据,还是旧的,此时 data 数据是最新的,页面尚未和 最新的数据保持同步

},
updated() {

// updated 事件执行的时候,页面和 data 数据已经保持同步了,都是最新的
},
动画效果

在这里插入图片描述

在进入/离开的过渡中,会有 6 个 class 切换。

  1. 注意:Vue 的动画都是把显示标签放在<transition>

  2. v-enter:定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除。

  3. v-enter-active:定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数。

  4. v-enter-to:2.1.8 版及以上定义进入过渡的结束状态。在元素被插入之后下一帧生效 (与此同时 v-enter 被移除),在过渡/动画完成之后移除。

  5. v-leave:定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除。

  6. v-leave-active:定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。

  7. v-leave-to:2.1.8 版及以上定义离开过渡的结束状态。在离开过渡被触发之后下一帧生效 (与此同时 v-leave 被删除),在过渡/动画完成之后移除。

原生动画

案例:

/* 进入与离开起始状态 */
.v-enter,
.v-leave-to {
  opacity: 0;
  transform: translateX(200px);
}

/* 
v-enter-active 进场动画时间段
v-leave-active 离场动画时间段
*/
.v-enter-active,
.v-leave-active {
  transition: all 0.9s ease;
}
/* 下面的 .v-move 和 .v-leave-active 配合使用,能够实现列表后续的元素,渐渐地漂上来的效果 */
.v-move {
  transition: all 0.6s ease;
}
.v-leave-active {
  position: absolute;
}

/* 自定义动画命令前缀 在transition 添加name='my' */
.my-enter,
.my-leave-to {
  opacity: 0;
  transform: translateX(200px);
}

.my-enter-active,
.my-leave-active {
  transition: all 0.9s ease;
}
借助第三方动画 animate.css
<!-- 使用第三方动画效果 -->
<transition enter-active-class="bounceIn" leave-active-class="bounceOut">
  <h3 v-if="flag" class="animated">This is h3</h3>
</transition>
<!-- 自定义进出时长 -->
<transition
  enter-active-class="bounceIn"
  leave-active-class="bounceOut"
  :duration="{ enter:200, leave:400 }"
>
  <h3 v-if="flag" class="animated">This is h3</h3>
</transition>
<!-- transition展示 -->

<!-- 在实现列表动画的时候,需要用transition-group进行包裹 li标签 进行v-for循环渲染,不能使用transition -->
<!-- 给 transition-group 添加 appear 属性,实现页面刚展示出来时候,入场时候的效果  -->
<!-- 必须为每一个 元素 设置 :key 属性 -->
<!-- 通过 为 transition-group 元素,设置 tag 属性,指定 transition-group 渲染为指定的元素,如果不指定 tag 属性,默认,渲染为 span 标签 -->
<!-- transition-group appear属性 ,进场效果 -->
<transition-group appear tag="ul">
  <li class="box" v-for="(item,i) in list" :key="item.id" @click="del(item.id)">
    {{ item.id }} ===> {{ item.name }}
  </li>
</transition-group>
Vue 组件
创建组件的注意项:
  1. 代码模块化 精简代码 ,组件化 重复利用 UI 界面
  2. 无论哪种创建方式 template 中只能有一个标签 ,解决方案 div 包裹多个标签元素
创建方式:
  1. 第一种
// 创建全局组件  Vue.extend
var com = Vue.extend({
  template: "<h3>This is template Vue extends to first</h3>",
  // 通过template指定组件HTML结构
})
// 注册全局组件  Vue.component
/**
 * Vue.component("组件名称" , 组件对象)
 * Vue.component("myCom" , com) 使用驼峰命名法 使用标签时候 ==> <my-com></my-com>
 * Vue.component("mycom" , com) 使用小写命名法  直接使用
 */
Vue.component("mycom", com)

// 第一种创建方式简写式
//              组件名称    组件实例  template 组件内容
Vue.component(
  "mycom1",
  Vue.extend({
    template: "<h4>This is template Vue extends to second</h4>",
  })
)
  1. 第二种
Vue.component("mycom2", {
  template: "<h4>This is template Vue extends to three</h4>",
})
  1. 第三种
;<template id="tmpl">
  <div>
    <h3>This is the fourth way of external definition</h3>
  </div>
</template>
Vue.component("mycom3", {
  template: "#tmpl",
})
  1. 第四种:
var vm = new Vue({
  el: "#app2",
  components: {
    // 定义实例内部私有组件
    login: {
      template: "#tmpl",
    },
  },
})
组件中的私有方法

在组件的 data 属性,必须使用 return 进行返回

Vue.component("counter", {
  template: "#counter",
  data: function () {
    return { count: 0 }
  },
  methods: {
    increment() {
      this.count++
    },
  },
})
组件的切换

Vue 提供了 component ,来展示对应名称的组件
component 是一个占位符, :is 属性,可以用来指定要展示的组件的名称
通过 mode 属性,设置组件切换时候的 模式

<transition mode="out-in">
  <component :is="component_className"></component>
</transition>
<script>
  // 组件名称是 字符串
  Vue.component("login", {
    template: "<h2>登陆页面</h2>",
  })

  Vue.component("register", {
    template: "<h2>注册页面</h2>",
  })

  var vm = new Vue({
    el: "#app",
    data: {
      component_className: "login",
    },
    methods: {},
  })
</script>
组件相互传值
  1. 父组件 ==> 子组件

父组件引用子组件时,:传递子组件注册名称=“父组件数据”
以属性绑定方式传递到子组件内部使用

案例:

<com :parentmsg="父类数据名称"></com>
<script>
  var com = {
    template: "<h1>This is son data --- {{ parentmsg }}</h1>",
    /**
     * 把父组件传递过来的 parentmsg 属性,先在 props 数组中,定义一下,这样,才能使用这个数据
     * props 都是只读 ,内部data可以读写操作
     * */
    props: ["parentmsg"], // 进行注册,然后就可以使用这个属性
  }
</script>
  1. 子组件 ==> 父组件

v-on 事件绑定机制 绑定式 @子组件方法名称:父组件方法名称 ===> 将父组件方法赋值于子组件

案例:

<!-- app中的标签 show是父组件 -->
<com @func="show"></com>
<!-- template中的  myclick是子组件-->
<template id="tmpl">
  <div>
    <input
      type="button"
      @click="myclick"
      value="这是子组件中的按钮 - 点击它,触发 父组件传递过来的 func 方法"
    />
  </div>
</template>
<script>
  myclick() {
        /** * emit 英文原意: 是触发,调用、发射的意思 *
    this.$emit(函数名,传递的值) * 2. 通过$emit函数触发 */
    this.$emit("func", 123) //
    this.$emit("func", this.some)
  }
</script>
Vue 获取元素组件
<h6 ref="myh6">123456</h6>
console.log(this.$refs.myh6.innerText) ==> 123456
前端路由模块
vue-router

vue-router来实现(hash)
vue-router 前端路由模块 以 #/login 为请求路由 区别于后端 /login

  1. 通过<router-view></router-view>展示
  2. 通过<router-link to="/login">登陆</router-link>链接路由

案例:

// 1. 创建template 模板对象
var login = {
  template: "<h1> login page </h1>",
}
var register = {
  template: "<h1> register page </h1>",
}
// new VueRouter 实例
var routerObjects = new VueRouter({
  //  routes 路由匹配规则  属性1 path 监听的路由链接地址  component 展示对应的组件名称
  //  component 的属性值,必须是一个 组件的模板对象, 不能是 组件的引用名称;
  routes: [
    {
      path: "/",
      redirect: "/login",
      children: [
        /**
         * children 属性 实现子路由,同时,子路由的 path 前面,不要带 / ,
         * 否则永远以根路径开始请求,这样不方便我们用户去理解URL地址
         * */
        { path: "/login", component: login },
        { path: "/login", component: login },
      ],
    },
    { path: "/login", component: login },
    { path: "/register", component: register },
  ],
  // 自定义样式
  linkActiveClass: "myactive", //通过.myactive 进行写样式
})
// router: routerObjects // 注册router 前端路由到实例中
vue-router – $route 传参
  1. 第一种方式-query:
<router-link to="/login?id=123&name=cat">第一种传参方法==>login</router-link>

在方法中 :this.$route.query 获取参数
  1. 第二种传参 - params:
使用第二种方式,必须在routes中进行定义:

{ path: '/register/:id/:name', component: register }

<router-link to="/register/360/cat30">第二种传参方法===>register</router-link>

在方法中 :this.$route.params 获取参数

组件三分页面

默认 default 属性值, name 参数指定同一个路由下的不同组件

<router-view name="left"></router-view>
<router-view name="main"></router-view>
在routes定义:
routes: [
            // components 定义多个组件并加以使用
            {
                path: '/', components:
                {
                    default: header,
                    left: left,
                    main: main
                }
            }
        ]
watch 与 computed 属性

watch 属性监听
一旦监听的属性值发生变化 watch 回调函数立马响应执行

var vm = new Vue({
  el: "#app",
  router,
  // render 会覆盖app中所有组件 相当于v-text 简写方式
  //   render(h) {
  //     return h(login)
  //   },
  render: (c) => c(login),
  // watch 属性监听 路由变化
  watch: {
    "$route.path": function (newVal, oldVal) {
      console.log(newVal + "===>" + oldVal)
      if (newVal === "/login") {
        console.log("欢迎登陆")
      } else if (newVal === "/register") {
        console.log("欢迎注册")
      }
    },
  },
  computed: {
    /**
     * 在 computed 中,可以定义一些 属性,这些属性,叫做 【计算属性】
     * 注意1: 计算属性,在引用的时候,一定不要加 () 去调用,直接把它 当作 普通 属性去使用就好了;
     * 注意2: 只要 计算属性,这个 function 内部,所用到的 任何 data 中的数据发送了变化,就会 立即重新计算 这个 计算属性的值
     * 注意3: 计算属性的求值结果,会被缓存起来,方便下次直接使用; 如果 计算属性方法中,所以来的任何数据,都没有发生过变化,则,不会重新对 计算属性求值;
     */

    result: function () {
      return this.firstnum + "-" + this.lastnum
    },
  },
})
watchcomputedmethods之间的对比
  1. computed属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算。主要当作属性来使用;
  2. methods方法表示一个具体的操作,主要书写业务逻辑;
  3. watch一个对象,键是需要观察的表达式,值是对应回调函数。主要用来监听某些特定数据的变化,从而进行某些具体的业务逻辑操作;可以看作是computedmethods的结合体;

nrm的安装使用

作用:提供了一些最常用的 NPM 包镜像地址,能够让我们快速的切换安装包时候的服务器地址;
什么是镜像:原来包刚一开始是只存在于国外的 NPM 服务器,但是由于网络原因,经常访问不到,这时候,我们可以在国内,创建一个和官网完全一样的 NPM 服务器,只不过,数据都是从人家那里拿过来的,除此之外,使用方式完全一样;

  1. 运行npm i nrm -g全局安装nrm包;
  2. 使用nrm ls查看当前所有可用的镜像源地址以及当前所使用的镜像源地址;
  3. 使用nrm use npmnrm use taobao切换不同的镜像源地址;

注意: nrm 只是单纯的提供了几个常用的 下载包的 URL 地址,并能够让我们在 这几个 地址之间,很方便的进行切换,但是,我们每次装包的时候,使用的 装包工具,都是 npm

相关文章

  1. vue.js 1.x 文档
  2. vue.js 2.x 文档
  3. String.prototype.padStart(maxLength, fillString)
  4. js 里面的键盘事件对应的键码
  5. URL 中的 hash(井号)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用python中的pymsql完成如下:表结构与数据创建 1. 建立 `users` 表和 `orders` 表。 `users` 表有用户ID、用户名、年龄字段,(id,name,age) `orders` 表有订单ID、订单日期、订单金额,用户id字段。(id,order_date,amount,user_id) 2 两表的id作为主键,`orders` 表用户id为users的外键 3 插入数据 `users` (1, '张三', 18), (2, '李四', 20), (3, '王五', 22), (4, '赵六', 25), (5, '钱七', 28); `orders` (1, '2021-09-01', 500, 1), (2, '2021-09-02', 1000, 2), (3, '2021-09-03', 600, 3), (4, '2021-09-04', 800, 4), (5, '2021-09-05', 1500, 5), (6, '2021-09-06', 1200, 3), (7, '2021-09-07', 2000, 1), (8, '2021-09-08', 300, 2), (9, '2021-09-09', 700, 5), (10, '2021-09-10', 900, 4); 查询语句 1. 查询订单总金额 2. 查询所有用户的平均年龄,并将结果四舍五入保留两位小数。 3. 查询订单总数最多的用户的姓名和订单总数。 4. 查询所有不重复的年龄。 5. 查询订单日期在2021年9月1日至9月4日之间的订单总金额。 6. 查询年龄不大于25岁的用户的订单数量,并按照降序排序。 7. 查询订单总金额排名前3的用户的姓名和订单总金额。 8. 查询订单总金额最大的用户的姓名和订单总金额。 9. 查询订单总金额最小的用户的姓名和订单总金额。 10. 查询所有名字中含有“李”的用户,按照名字升序排序。 11. 查询所有年龄大于20岁的用户,按照年龄降序排序,并只显示前5条记录。 12. 查询每个用户的订单数量和订单总金额,并按照总金额降序排序。
最新发布
06-03
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值