vue学习-01vue入门
  cEe6YWJIAuf2 2023年11月14日 33 0


Vue官网地址

https://cn.vuejs.org/

Vue介绍

Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。

兼容性

Vue 不支持 IE8 及以下版本,因为 Vue 使用了 IE8 无法模拟的 ECMAScript 5 特性。但它支持所有兼容 ECMAScript 5 的浏览器。

Vue Devtools

正谷歌浏览器应用商店搜索Vue Devtools,安装即可

iguge谷歌助手

科学上网,然后在谷歌的应用商店安装iguge

命令行工具 (CLI)

参考地址:https://cli.vuejs.org/zh/
Vue CLI 需要 Node.js 8.9 或更高版本 (推荐 8.11.0+)。你可以使用 nvm 或 nvm-windows 在同一台电脑中管理多个 Node 版本。
安装环境:npm install -g @vue/cli

创建一个项目

这里提供几种方案:

  1. 升级为vue 3.x版本
npm uninstall vue-cli -g
npm install -g @vue/cli

2.降级为vue2.x方法

npm uninstall @vue/cli -g
npm install -g vue-cli

3.vue2.x脚手架的安装和初始化项目

# 创建项目
vue init webpack 项目名字
# 注意 ,以上步骤会让你创建一个vue文件夹存放vue项目,一般是webpack项目,与html中引入vue.js有一点点区别,注意router 那块选择yes,其他的选择no

#初始化项目
npm install

# 运行项目
npm run dev

4.vue3.x脚手架的安装和初始化项目

# 创建项目
vue create 项目名字
# 项目初始化
npm install

# 启动项目
npm run dev

或者:在项目的根目录下运行:npm run serve

VSCode的安装插件 Vetur

Vue知识点

  1. 模板语法
    参考HelloWorld.vue文件
    注意事项:模板中可以放语法,单个表达式语法
  1. 文本:{{}}
  2. 原始HTML:v-html
  3. 动态属性绑定:v-bind:
  1. CSS作用域
    scoped:作用域 在Vue的文件中,也有css的作用域,增加scoped属性,样式只能在当前组件中生效
  2. 条件渲染
    v-if
    v-else
    v-show
    v-if和v-show的区别:
    v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
    v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
    相比之下,v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。
    一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。
  3. 列表渲染
    v-for
    v-for 与 v-if 一同使用:注意我们不推荐在同一元素上使用 v-if 和 v-for
  1. 渲染数组(itme,index)
  2. 渲染对象(value,name,index)
  1. 事件处理
    v-on:click=“函数”
  1. 事件的实现
  2. 事件传递参数
  3. 事件修饰符
  4. 缩写:v-bind:key -> :key v-on:click -> @click
  1. 表单输入绑定
  1. v-model指令
  2. 修饰符 .lazy .number .trim
    **常见面试题:说一说双向数据绑定的原理!!!
  1. 数组更新检测
    数组方法的特异性:
    1. 改变元素组(会引起视图更新)
    push() pop() shift() unshift() splice() sort() reverse()
    2. 不改变元素数组,而是生成新的数组(不会引起视图更新)
    filter()、concat() 和 slice()
    对象的更新检测
    向响应式对象中添加一个 property,并确保这个新 property 同样是响应式的,且触发视图更新。它必须用于向响应式对象上添加新 property,因为 Vue 无法探测普通的新增 property (比如 this.myObject.newProperty = ‘hi’)
    this.$set(this.obj,“age”,20)
    API参考地址:https://cn.vuejs.org/v2/api/#vm-set
  2. 计算属性与侦听器
  1. 计算属性
    计算属性缓存 vs 方法
    我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。然而,不同的是计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。
  2. 侦听器
  1. Class 与 Style 绑定
  1. 绑定 HTML Class
    对象语法
    数组语法:注意事项:必须是数组嵌套对象
  2. 绑定 HTML Style
    对象语法
    数组语法
    注意:自动添加前缀,当 v-bind:style 使用需要添加浏览器引擎前缀的 CSS property 时,如 transform,Vue.js 会自动侦测并添加相应的前缀。
  1. 组件
  1. 组件的创建:单文件组件
    Vue组件由三个部分组成:HTML结构、JS逻辑、CSS样式。必须存在的是视图结果部分
  2. 组件引入
  3. 组件的复用:组件的每一次引用都是独立的实例对象
    应用场景:列表数据的操作中,例如购买数量的选择。把每一个列表单独抽离成一个组件
  4. data必须是一个函数
  5. 组件的组织

注意,此vue学习采用vue3的创建方式进行,且一开始没有创建路由,还请注意:

<template>
   <div class="hello">
       <p>{{ msg }}</p>
       <p>{{ 1+1 }}</p>
       <p>{{ num + 10 }}</p>
       <p>{{ 10 > 20 ? '真的' : '假的' }}</p>
       <p>{{ msg.split('').reverse().join('') }}</p>
       <!-- v-html:指令,Vue内置指令 -->
       <p v-html="vHTML"></p>
       <p :class="bindClass">我是文本</p>
       <a v-bind:href="Href">iwen的站点</a>
       <p v-bind:attr="attr">自定义属性</p>
       <p :class="bindClass" class="size">动态属性与固定属性不冲突</p>
       <hr />
       <h3 v-if="flag">我是孙悟空</h3>
       <h3 v-else>我是六耳猕猴</h3>
       <template v-if="flag">
           <h3>仓央嘉措</h3>
           <p>站在布达拉宫</p>
           <p>我是雪域最大的王</p>
       </template>
       <template v-else>
           <p>流浪在拉萨街头</p>
           <p>我是世间最美的情郎</p>
       </template>
       <p v-show="flag">我是show的展示</p>
       <hr />
       <ul>
           <li v-for="(item,index) in banner.data" v-bind:key="index">
               <a v-bind:href="item.url">
                   <img v-bind:src="item.image" alt />
                   <p>{{ item.title }}</p>
               </a>
           </li>
       </ul>
       <ul>
           <li v-for="(value,name,index) in userInfo" v-bind:key="index">
               <span>{{ name }}</span>:
               <span>{{ value }}</span> -
               <span>{{ index }}</span>
           </li>
       </ul>
       <p v-for="(item,index) in names" v-bind:key="index">{{ item }}</p>
       <ul>
           <li v-for="(diff,index) in diffs" v-bind:key="index">
               <span v-if="diff.flag">{{ diff.name }}</span>
           </li>
       </ul>
       <!-- 事件 -->
       <button v-on:click="clickHandle">按钮1</button>
       <button v-on:click="counter += 1">按钮2</button>
       <p>{{ counter }}</p>
       <button v-on:click="paramsHandle('hello',$event)">按钮3</button>
       <ul>
           <li
               v-on:click="getItemHandle(item)"
               v-for="(item,index) in names"
               :key="index"
           >{{ item }}</li>
       </ul>
       <form v-on:submit.stop.prevent="formHandle">
           <button>表单按钮</button>
       </form>
       <input type="text" @keyup.enter="inputHandle" />
       <hr />
       <!-- 表单输入绑定 -->
       <textarea type="text" v-model.lazy="username"></textarea>
       <p>{{ username }}</p>
       <div>
           <input type="checkbox" id="jack" value="Jack11" v-model="checkedNames" />
           <label for="jack">Jack</label>
           <input type="checkbox" id="john" value="John22" v-model="checkedNames" />
           <label for="john">John</label>
           <input type="checkbox" id="mike" value="Mike33" v-model="checkedNames" />
           <label for="mike">Mike</label>
           <span>{{ checkedNames }}</span>
       </div>
       <!-- 数组更新检测 -->
       <ul>
         <li v-for="(item,index) in container" :key="index">{{ item }}</li>
       </ul>
       <button @click="addHandle">添加数据</button>
       <ul>
         <li v-for="(value,name,index) in obj" :key="index">{{ value }}</li>
         <button @click="addObjHandle">添加数据</button>
       </ul>
       <!-- 计算属性与侦听器 -->
       <p>{{ setMSG }}</p>
       <p>{{ setMSG }}</p>
       <p>{{ getMSG() }}</p>
       <input type="text" v-model="password">
       <p>{{ password }}</p>
       <!-- class与style的绑定 -->
       <p :class="{ 'active':isActive,'text-danger':hasError }">class与style样式绑定</p>
       <ul>
         <li :class="{ 'active':index === 2 }" v-for="(item,index) in container" :key="index">{{ item }}</li>
       </ul>
       <p :class="[helloActive,helloText]">数组语法</p>
       <p :class="[isActive ? 'active' : 'text-danger',helloActive]">数组语法2</p>
       <p :class="[isActive ? 'active' : 'text-danger',{ 'text-danger1':hasError }]">必须数组嵌套对象</p>
       <p :style="{ fontSize:fontNum + 'px',display:'flex' }">style样式</p>
   </div> 
</template>

<script>
export default {
   // 函数
   data() {
       return {
           fontNum:30,
           helloActive:'active',
           helloText:"text-danger",
           isActive:false,
           hasError:true,
           password:"",
           container:[1,2,3,4,5],
           obj:{
             name:'iwen'
           },
           username: "",
           checkedNames:[],
           msg: "Hello Vue",
           num: 10,
           vHTML: "我是属性绑定",
           bindClass: "text-2", // 动态赋值,js操作,后续可以通过事件改变
           Href: "http://iwenwiki.com",
           attr: "1001",
           flag: false,
           names: ["iwen", "ime", "frank"],
           banner: {
               status: 200,
               data: [
                   {
                       image: "http://iwenwiki.com:3002/images/savefood1.jpg",
                       title: "养生从我开始,从不懈怠",
                       url: "http://iwenwiki.com"
                   },
                   {
                       image: "http://iwenwiki.com:3002/images/savefood2.jpg",
                       title: "以梦为马,不负韶华",
                       url: "http://iwenwiki.com"
                   },
                   {
                       image: "http://iwenwiki.com:3002/images/savefood3.jpg",
                       title: "都是第一次为人,凭什么我要让着你",
                       url: "http://iwenwiki.com"
                   },
                   {
                       image: "http://iwenwiki.com:3002/images/savefood4.jpg",
                       title: "这只猫太可恶了,我的耳机又坏了",
                       url: "http://iwenwiki.com"
                   },
                   {
                       image: "http://iwenwiki.com:3002/images/savefood5.jpg",
                       title: "死猫,你再咬,看我打不打你就完了",
                       url: "http://iwenwiki.com"
                   }
               ]
           },
           userInfo: {
               name: "iwen",
               age: 20
           },
           diffs: [
               {
                   name: "蔬菜",
                   flag: true
               },
               {
                   name: "水果",
                   flag: true
               },
               {
                   name: "肉类",
                   flag: false
               }
           ],
           counter: 1
       };
   },
   methods: {
       clickHandle(e) {
           // 修改data的数据
           this.flag = !this.flag;
       },
       paramsHandle(data, event) {
           console.log(data);
           console.log(event);
       },
       getItemHandle(data) {
           console.log(data);
       },
       formHandle(e) {
           // e.preventDefault();
           console.log(111);
       },
       inputHandle(e) {
           // if(e.keyCode === 13){
           //   console.log("enter");
           // }
           console.log("enter");
       },
       addHandle(){
         // this.container.push(6);
         this.container = this.container.concat([6,7,8,9])
       },
       addObjHandle(){
         // 对象的更新检测,在ES6中,我们不推荐大家直接修改对象
         // this.obj.age = 20;
         this.$set(this.obj,"age",20)
       },
       getMSG(){
         return this.msg.split("").reverse().join("")
       }
   },
   computed:{
     // 计算属性的优点,如果数据源没有发生变化,则不会重新计算
     setMSG(){
       return this.msg.split("").reverse().join("")
     }
   },
   watch:{
     /**
      * new:当前最新的数据
      * old:上一次操作的数据
      * 所有data中声明的属性都可以监听
      * 后续学习props的属性值,也可以通过watch监听数据变化
      */
     password(newPassword,oldPassword){
       /**
        * React中我们讲过搜索:搜索历史!
        */
       console.log("newPassword:"+newPassword);
       console.log("oldPassword:"+oldPassword);
       if(newPassword === "123"){
         console.log("临界值");
       }
     }
   }
};
</script>
<!-- scoped:作用域  在Vue的文件中,也有css的作用域,增加scoped属性,样式只能在当前组件中生效 -->
<style scoped>
.text-1 {
   color: red;
}
.text-2 {
   color: green;
}

.size {
   font-size: 30px;
}

.active{
 color: red;
 font-size: 30px;
}
</style>

main.js文件

import Vue from 'vue'
import App from './App.vue'
import './registerServiceWorker'

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')

App.vue

<template>
  <div id="app">
    <img alt="Vue logo" src="./assets/logo.png">
    <!-- <HelloWorld msg="Welcome to Your Vue.js App"/> -->
    <MyComponent />
    <MyComponent />
    <MyComponent />
    <!-- <my-component></my-component> -->
  </div>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'
import MyComponent from "./components/MyComponent"

export default {
  name: 'App',
  components: {
    HelloWorld,
    MyComponent // 注入
  }
}
</script>

<style lang="less">
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

MyComponent.vue

<template>
    <!-- Vue2.x版本下,有且只能有一个根组件 -->
    <div>
        创建组件:{{ num }}
        <button @click=" num += 1 ">按钮</button>
    </div>
</template>
<script>
export default {
    name:"MyComponent",
    data(){
        return{
            num:0
        }
    },
    methods:{

    },
    computed:{

    },
    watch:{

    }
}
</script>
<style scoped lang="less">

</style>

registerServiceWorker.js

/* eslint-disable no-console */

import { register } from 'register-service-worker'

if (process.env.NODE_ENV === 'production') {
  register(`${process.env.BASE_URL}service-worker.js`, {
    ready () {
      console.log(
        'App is being served from cache by a service worker.\n' +
        'For more details, visit https://goo.gl/AFskqB'
      )
    },
    registered () {
      console.log('Service worker has been registered.')
    },
    cached () {
      console.log('Content has been cached for offline use.')
    },
    updatefound () {
      console.log('New content is downloading.')
    },
    updated () {
      console.log('New content is available; please refresh.')
    },
    offline () {
      console.log('No internet connection found. App is running in offline mode.')
    },
    error (error) {
      console.error('Error during service worker registration:', error)
    }
  })
}


【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月14日 0

暂无评论

推荐阅读
  xaeiTka4h8LY   2024年04月26日   45   0   0 split数组字符串
cEe6YWJIAuf2