当前位置: 首页 > article >正文

Vue3安装、创建到使用

vue安装
npm install vue@next
# 全局安装 vue-cli
npm install -g @vue/cli
#更新插件 项目中运行
vue upgrade --next
vue create 命令
vue create [options] <app-name>
options 选项可以是:
-p, --preset <presetName>: 忽略提示符并使用已保存的或远程的预设选项
-d, --default: 忽略提示符并使用默认预设选项
-i, --inlinePreset <json>: 忽略提示符并使用内联的 JSON 字符串预设选项
-m, --packageManager <command>: 在安装依赖时使用指定的 npm 客户端
-r, --registry <url>: 在安装依赖时使用指定的 npm registry
-g, --git [message]: 强制 / 跳过 git 初始化,并可选的指定初始化提交信息
-n, --no-git: 跳过 git 初始化
-f, --force: 覆写目标目录可能存在的配置
-c, --clone: 使用 git clone 获取远程预设选项
-x, --proxy: 使用指定的代理创建项目
-b, --bare: 创建项目时省略默认组件中的新手指导信息
-h, --help: 输出使用帮助信息
创建vue3项目
vue create vue3-app或vue ui
目录
build                   项目构建(webpack)相关代码
config                  配置目录,包括端口号等。我们初学可以使用默认的。
node_modules            npm 加载的项目依赖模块
src                     这里是我们要开发的目录,基本上要做的事情都在这个目录里。里面包含了几个目录及文件:

                        assets: 放置一些图片,如logo等。
                        components: 目录里面放了一个组件文件,可以不用。
                        App.vue: 项目入口文件,我们也可以直接将组件写这里,而不使用 components 目录。
                        main.js: 项目的核心文件。
                        index.css: 样式文件。
static                  静态资源目录,如图片、字体等。
public                  公共资源目录。
test                    初始测试目录,可删除
.xxxx文件                这些是一些配置文件,包括语法配置,git配置等。
index.html               首页入口文件,你可以添加一些 meta 信息或统计代码啥的。
package.json             项目配置文件。
README.md                项目的说明文档,markdown 格式
dist                     使用 npm run build 命令打包后会生成该目录。
起步

<div id="hello-vue" class="demo">
  {{ message }}
</div>
<script src="https://unpkg.com/vue@next"></script>
<script>
const HelloVueApp = {
  data() {
    return {
      message: 'Hello Vue!!'
    }
  }
}

Vue.createApp(HelloVueApp).mount('#hello-vue')
</script>
//使用 mount('#hello-vue') 将 Vue 应用 HelloVueApp 挂载到 <div id="hello-vue"></div> 中
Vue3 模板语法
文本  <span>{{...}}</span>
Html  <span v-html="rawHtml"></span>
属性  <div v-bind:id="dynamicId"></div>
表达式 
<div id="app">
    {{5+5}}<br>
    {{ ok ? 'YES' : 'NO' }}<br>
    {{ message.split('').reverse().join('') }}
    <div v-bind:id="'list-' + id">ABC</div>
</div>
    
<script>
const app = {
  data() {
    return {
      ok: true,
      message: 'ABC!!',
      id: 1
    }
  }
}
 
Vue.createApp(app).mount('#app')
</script>
指令 v-if  v-for
参数  v-bind @click @[event] :href
v-model <input v-model="msg"> input、select、textarea、checkbox、radio
Vue3 条件语句
条件判断 v-if v-else v-else-if v-show
Vue3 循环语句
v-for
迭代对象 <li v-for="(value, key, index) in object">{{ value }}</li>
迭代整数 <li v-for="n in 10">{{ n }}</li>
显示过滤/排序后的结果
输出数组中的偶数 <li v-for="n in evenNumbers">{{ n }}</li>
v-for/v-if 联合使用
<template v-for="(site,index) in sites" :site="site" :index="index" :key="site.id">
     <!-- 索引为 1 的设为默认值,索引值从0 开始-->
     <option v-if = "index == 1" :value="site.name" selected>{{site.name}}</option>
     <option v-else :value="site.name">{{site.name}}</option>
 </template>
在组件上使用 v-for
<my-component v-for="item in items" :key="item.id"></my-component>
Vue3 组件
<my-component-name></my-component-name>
组件的复用
全局组件 app.vue中注册组件
局部组件 components: {
            'component-a': ComponentA,
            'component-b': ComponentB
          }
Prop
子组件用来接受父组件传递过来的数据的一个自定义属性
父组件的数据需要通过 props 把数据传给子组件,子组件需要显式地用 props 选项声明 "prop"
<div id="app">
  <site-name title="Baidu"></site-name>
  <site-name title="Taobao"></site-name>
</div>
 
<script>
const app = Vue.createApp({})
 
app.component('site-name', {
  props: ['title'],
  template: `<h4>{{ title }}</h4>`
})
 
app.mount('#app')
</script>
显示
Baidu
Taobao
动态 Prop
<div id="app">
  <site-info
    v-for="site in sites"
    :id="site.id"
    :title="site.title"
  ></site-info>
</div>
 
<script>
const Site = {
  data() {
    return {
      sites: [
        { id: 1, title: 'Baidu' },
        { id: 2, title: 'Taobao' }
      ]
    }
  }
}
 
const app = Vue.createApp(Site)
 
app.component('site-info', {
  props: ['id','title'],
  template: `<h4>{{ id }} - {{ title }}</h4>`
})
 
app.mount('#app')
</script>
显示
1 - Baidu
2 - Taobao
Prop 验证
Vue.component('my-component', {
  props: {
    // 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
    propA: Number,
    // 多个可能的类型
    propB: [String, Number],
    // 必填的字符串
    propC: {
      type: String,
      required: true
    },
    // 带有默认值的数字
    propD: {
      type: Number,
      default: 100
    },
    // 带有默认值的对象
    propE: {
      type: Object,
      // 对象或数组默认值必须从一个工厂函数获取
      default: function () {
        return { message: 'hello' }
      }
    },
    // 自定义验证函数
    propF: {
      validator: function (value) {
        // 这个值必须匹配下列字符串中的一个
        return ['success', 'warning', 'danger'].indexOf(value) !== -1
      }
    }
  }
})
type 可以是下面原生构造器
String、Number、Boolean、Array、Object、Date、Function、Symbol
type 也可以是一个自定义构造器,使用 instanceof 检测
Vue3 计算属性
//computed
<p>原始字符串: {{ message }}</p>
<p>计算后反转字符串: {{ reversedMessage }}</p>
<script>
const app = {
  data() {
    return {
      message: 'ABC!!'
    }
  },
  computed: {
    // 计算属性的 getter
    reversedMessage: function () {
      // `this` 指向 vm 实例
      return this.message.split('').reverse().join('')
    }
  }
}
</script>
computed vs methods
computed 是基于它的依赖缓存,只有相关依赖发生改变时才会重新取值。而使用 methods ,在重新渲染的时候,函数总会重新调用执行
methods: {
    reversedMessage2: function () {
        return this.message.split('').reverse().join('')
     }
 }
可以说使用 computed 性能会更好,但是如果你不希望缓存,你可以使用 methods 属性
computed setter
var vm = new Vue({
  el: '#app',
  data: {
    name: 'Baidu',
    url: 'https://www.Baidu.com'
  },
  computed: {
    site: {
      // getter
      get: function () {
        return this.name + ' ' + this.url
      },
      // setter
      set: function (newValue) {
        var names = newValue.split(' ')
        this.name = names[0]
        this.url = names[names.length - 1]
      }
    }
  }
})
vm.site = '淘宝 http://www.Taobao.com';
setter 会被调用时, vm.name 和 vm.url 也会被对应更新
Vue3 监听属性 watch
千米与米之间的换算
<div id = "app">
    千米 : <input type = "text" v-model = "kilometers">
    米 : <input type = "text" v-model = "meters">
</div>
<p id="info"></p>   
<script>
const app = {
  data() {
    return {
      kilometers : 0,
      meters:0
    }
  },
  watch : {
      kilometers:function(val) {
          this.kilometers = val;
          this.meters = this.kilometers * 1000
      },
      meters : function (val) {
          this.kilometers = val/ 1000;
          this.meters = val;
      }
  }
}
vm = Vue.createApp(app).mount('#app')
</script>
watch 对象创建了 data 对象的两个监控方法: kilometers 和 meters。
当我们再输入框输入数据时,watch 会实时监听数据变化并改变自身的值
异步加载中使用 watch
data() {
      return {
        question: '',
        answer: '每个问题结尾需要输入 ? 号。'
      }
    },
    watch: {
      // 每当问题改变时,此功能将运行,以 ? 号结尾,兼容中英文 ?
      question(newQuestion, oldQuestion) {
        if (newQuestion.indexOf('?') > -1 || newQuestion.indexOf('?') > -1) {
          this.getAnswer()
        }
      }
    },
    methods: {
      getAnswer() {
        this.answer = '加载中...'
        axios
          .get('url')
          .then(response => {
            this.answer = response.data.answer
          })
          .catch(error => {
            this.answer = '错误! 无法访问 API。 ' + error
          })
      }
    }
Vue3 样式绑定
:class
<div class="static" :class="{ 'active' : isActive, 'text-danger' : hasError }"></div>
当 isActive 或者 hasError 变化时,class 属性值也将相应地更新。例如,如果 active 的值为 true,class 列表将变为 "static active text-danger"
直接绑定数据里的一个对象
<style>
.static {
    width: 100px;
    height: 100px;
}
.active {
    background: green;
}
.text-danger {
    background: red;
}
</style>
<div id="app">
    <div class="static" :class="classObject"></div>
</div>
<script>
const app = {
    data() {
      return {
         classObject: {
            'active': false,
            'text-danger': true
         }
      }
   }
}
Vue.createApp(app).mount('#app')
</script>
//红色
绑定一个返回对象的计算属性
data() {
  return {
    isActive: true,
    error: null
  }
},
computed: {
  classObject() {
    return {
      active: this.isActive && !this.error,
      'text-danger': this.error && this.error.type === 'fatal'
    }
  }
}
//绿色
数组语法
<div class="static" :class="[activeClass, errorClass]"></div>

data() {
    return {
       activeClass: 'active',
       errorClass: 'text-danger'
    }
}
三元表达式
<div class="static" :class="[isActive ? activeClass : '', errorClass]"></div>

组件上使用 class 属性
<my-component :class="{ active: isActive }"></my-component>

组件有多个根元素,可以使用 $attrs 组件属性执行此操作
template: `
    <p :class="$attrs.class">I like ok!</p>
    <span>这是一个子组件</span>
`
template 中 ` 是反引号
:style(内联样式)
<div :style="{ color: activeColor, fontSize: fontSize + 'px' }">ABC</div>
样式对象
<div :style="styleObject">ABC</div>

data() {
    return {
        styleObject: {
            color: "red",
            fontSize: "30px"
        }
    }
}
style="color: red; font-size: 30px;"
数组
<div :style="[baseStyles, overridingStyles]">ABC</div>

data() {
        return {
            baseStyles: {
                color: 'green',
                fontSize: '30px'
            },
            overridingStyles: {
                'font-weight': 'bold'
            }
        }
    }
多重值 <div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>
如果浏览器支持不带浏览器前缀的 flexbox,那么就只会渲染 display: flex
Vue3 事件处理
v-on缩写@
可以执行多个方法,由逗号运算符分隔
<button @click="one($event), two($event)">点我</button>
事件修饰符
.stop - 阻止冒泡
.prevent - 阻止默认事件
.capture - 阻止捕获
.self - 只监听触发该元素的事件
 .once - 只触发一次
.left - 左键事件
 .right - 右键事件
.middle - 中间滚轮事件

<!-- 阻止单击事件冒泡 -->
<a v-on:click.stop="doThis"></a>
<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>
<!-- 修饰符可以串联  -->
<a v-on:click.stop.prevent="doThat"></a>
<!-- 只有修饰符 -->
<form v-on:submit.prevent></form>
<!-- 添加事件侦听器时使用事件捕获模式 -->
<div v-on:click.capture="doThis">...</div>
<!-- 只当事件在该元素本身(而不是子元素)触发时触发回调 -->
<div v-on:click.self="doThat">...</div>

<!-- click 事件只能点击一次 -->
<a v-on:click.once="doThis"></a>
按键修饰符
<input v-on:keyup.13="submit">
只有在 keyCode 是 13 时调用 vm.submit()
最常用的按键别名 <input @keyup.enter="submit">

全部的按键别名:
.enter
.tab
.delete (捕获 "删除" 和 "退格" 键)
.esc
.space
.up
.down
.left
.right

系统修饰键:
.ctrl
.alt
.shift
.meta

鼠标按钮修饰符:
.left
.right
.middle
.exact 修饰符
<!-- 即使 Alt 或 Shift 被一同按下时也会触发 -->
<button @click.ctrl="onClick">A</button>

<!-- 有且只有 Ctrl 被按下的时候才触发 -->
<button @click.ctrl.exact="onCtrlClick">A</button>

<!-- 没有任何系统修饰符被按下的时候才触发 -->
<button @click.exact="onClick">A</button>
Vue3 表单
v-model
表单 <input>、<textarea> 及 <select> 等元素上创建双向数据绑定
v-model 在内部为不同的输入元素使用不同的属性并抛出不同的事件:
1. text 和 textarea 元素使用 value 属性和 input 事件;
2. checkbox 和 radio 使用 checked 属性和 change 事件;
3. select 字段将 value 作为属性并将 change 作为事件。
select multiple 多选时会绑定到一个数组
复选框 (Checkbox) <input type="checkbox" v-model="toggle" true-value="yes" false-value="no" />

单选框 (Radio) <input type="radio" v-model="pick" :value="a" />

选择框选项 (Select) obj
<select v-model="selected">
  <!-- 内联对象字面量 -->
  <option :value="{ number: 123 }">123</option>
</select>
// 当被选中时
typeof vm.selected // => 'object'
vm.selected.number // => 123
修饰符
.lazy
转变为在 change 事件中同步
<!-- 在 "change" 而不是 "input" 事件中更新 -->
<input v-model.lazy="msg" >

.number
将用户的输入值转为 Number 类型
<input v-model.number="age" type="number">

.trim
自动过滤用户输入的首尾空格
<input v-model.trim="msg">
Vue3 自定义指令
钩子函数
指令定义函数提供了几个钩子函数(可选):

created : 在绑定元素的属性或事件监听器被应用之前调用。
beforeMount : 指令第一次绑定到元素并且在挂载父组件之前调用。。
mounted : 在绑定元素的父组件被挂载后调用。。
beforeUpdate: 在更新包含组件的 VNode 之前调用。。
updated: 在包含组件的 VNode 及其子组件的 VNode 更新后调用。
beforeUnmount: 当指令与在绑定元素父组件卸载之前时,只调用一次。
unmounted: 当指令与元素解除绑定且父组件已卸载时,只调用一次。

例
// 注册
app.directive('my-directive', {
  // 指令是具有一组生命周期的钩子:
  // 在绑定元素的 attribute 或事件监听器被应用之前调用
  created() {},
  // 在绑定元素的父组件挂载之前调用
  beforeMount() {},
  // 绑定元素的父组件被挂载时调用
  mounted() {},
  // 在包含组件的 VNode 更新之前调用
  beforeUpdate() {},
  // 在包含组件的 VNode 及其子组件的 VNode 更新之后调用
  updated() {},
  // 在绑定元素的父组件卸载之前调用
  beforeUnmount() {},
  // 卸载绑定元素的父组件时调用
  unmounted() {}
})
 
// 注册 (功能指令)
app.directive('my-directive', () => {
  // 这将被作为 `mounted` 和 `updated` 调用
})
 
// getter, 如果已注册,则返回指令定义
const myDirective = app.directive('my-directive')
钩子函数参数
el 指令绑定到的元素。这可用于直接操作 DOM

binding 是一个对象,包含以下属性
    instance:使用指令的组件实例。
    value:传递给指令的值。例如,在 v-my-directive="1 + 1" 中,该值为 2。
    oldValue:先前的值,仅在 beforeUpdate 和 updated 中可用。值是否已更改都可用。
    arg:参数传递给指令 (如果有)。例如在 v-my-directive:foo 中,arg 为 "foo"。
    modifiers:包含修饰符 (如果有) 的对象。例如在 v-my-directive.foo.bar 中,修饰符对象为 {foo: true,bar: true}。
    dir:一个对象,在注册指令时作为参数传递。例如,在以下指令中:
<div id="app">
   <div v-dire="{ name: 'baidu', url: 'www.baidu.com' }"></div>
</div>

<script>
const app = Vue.createApp({})
app.directive('dire', (el, binding, vnode) => {
    console.log(binding.value.name) // => "baidu"
    console.log(binding.value.url) // => "www.baidu.com"
    el.innerHTML = JSON.stringify(binding.value)
})
app.mount('#app')
</script>

简写函数
<script>
app.directive('dire', function (el, binding) {
  // 设置指令的背景颜色
  el.style.backgroundColor = binding.value.color
})
</script>

接受所有合法的 JavaScript 表达式
<div id="app">
    <div v-dire="{ color: 'green', text: 'hello App!' }"></div>
</div>
 
<script>
Vue.directive('dire', function (el, binding) {
    // 简写方式设置文本及背景颜色
    el.innerHTML = binding.value.text
    el.style.backgroundColor = binding.value.color
})
new Vue({
  el: '#app'
})
</script>
Vue3 混入mixins
// mixins提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能
// mixins: 可以定义共用的变量,在每个组件中使用,引入组件中之后,各个变量是相互独立的,值的修改在组件中不会相互影响。
// vuex:用来做状态管理的,里面定义的变量在每个组件中均可以使用和修改,在任一组件中修改此变量的值之后,其他组件中此变量的值也会随之修改。
// 定义混入对象
const myMixin = {
  methods: {
    foo() {
      console.log('foo')
    },
    conflicting() {
      console.log('from mixin')
    }
  }
}
 
const app = Vue.createApp({
  mixins: [myMixin],
  methods: {
    bar() {
      console.log('bar')
    },
    conflicting() {
      console.log('from self')
    }
  }
})
 
const vm = app.mount('#app')
 
vm.foo() // => "foo"
vm.bar() // => "bar"
vm.conflicting() // => "from self"
Vue3 组合式 API(Composition API)
1.setup 组件
setup() 函数在组件创建 created() 之前执行
setup() 函数接收两个参数 props 和 context
props是响应式的,当传入新的 prop 时,它将被更新。
context是一个普通的 JavaScript 对象,它是一个上下文对象,暴露了其它可能在 setup 中有用的值。
<template>
    <div>
        <p>计数器实例: {{ count }}</p>
        <input @click="myFn" type="button" value="点我加 1">
    </div>
</template>

<script>
import {ref, onMounted} from 'vue';

export default {
    setup(props, context){
        // 透传 Attributes(非响应式的对象,等价于 $attrs)
        console.log(context.attrs)

        // 插槽(非响应式的对象,等价于 $slots)
        console.log(context.slots)

        // 触发事件(函数,等价于 $emit)
        console.log(context.emit)

        // 暴露公共属性(函数)
        console.log(context.expose)

        //定义初始值为0的变量,要使用ref方法赋值,直接赋值的话变量改变不会更新 UI
        // ref() 函数可以根据给定的值来创建一个响应式的数据对象,返回值是一个对象,且只包含一个 .value 属性。
        // 在 setup() 函数内,由 ref() 创建的响应式数据返回的是对象,所以需要用 .value 来访问
        let count = ref(0);

        // 定义点击事件 myFn
        function myFn(){
            console.log(count);
            count.value += 1;
        }
       
       // 组件被挂载时,我们用 onMounted 钩子记录一些消息
        onMounted(() => console.log('component mounted!'));

        // 外部使用组合API中定义的变量或方法,在模板中可用。
        return {count,myFn} // 返回的函数与方法的行为相同
    }
}
</script>
2.Vue 组合式 API 生命周期钩子
import { onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted, onErrorCaptured  } from 'vue';
export default {
  setup() {
    // 载入之前调用
    onBeforeMount(() => {})
    // 载入之后调用
    onMounted(() => {})
    // 更新之前调用
    onBeforeUpdate(() => {})
    // 更新之后调用
    onUpdated(() => {})
    // 卸载之前调用
    onBeforeUnmount(() => {})
    // 卸载之后调用
    onUnmounted(() => {})
    // 生命周期钩子抛出错误时调用
    onErrorCaptured(() => {}) 
  }
};
3.响应式 API:核心
import { ref, reactive, computed, readonly, watchEffect, watch } from 'vue';
export default {
  setup() {
    const count = ref(1)
    console.log(count.value) // 1
    
    const plusOne = computed(() => count.value + 1)
    console.log(plusOne.value) // 2
    plusOne.value++ // 错误
  
    const obj = reactive({ count: 0 })
    obj.count++ // 1
    //传入[数组]会转成proxy对象
    const arr= reactive([1, 2, 3])
    console.log(arr[0]) // 1
    
    const count = ref(1)
    watchEffect(() => console.log(count.value))
    count.value++

    const stop = watchEffect(() => {})
    // 当不再需要此侦听器时:
    stop()

    const state = reactive({ count: 0 })
    watch(() => state.count,
      (count, prevCount) => {
          /* ... */
      })
  }
}
最后编辑于:2024-10-27 15:58:34


喜欢的朋友记得点赞、收藏、关注哦!!!


http://www.kler.cn/a/382526.html

相关文章:

  • 开源模型应用落地-glm模型小试-glm-4-9b-chat-vLLM集成(四)
  • 在Java中,实现数据库连接通常使用JDBC
  • Vue(JavaScript)读取csv表格并求某一列之和(大浮点数处理: decimal.js)
  • 【C++篇】在秩序与混沌的交响乐中: STL之map容器的哲学探寻
  • Qt中的动态链接库编程(Q_DECL_IMPORT、Q_DECL_EXPORT)
  • 砥砺十年风雨路,向新而行创新程丨怿星科技十周年庆典回顾
  • vue:Transition
  • 剑指offer第六天
  • vue3+ant design vue与vue3+vant实现阿里云oss文件上传
  • 机器学习—矩阵乘法的规则
  • 高校实验室安全巡检系统设计与实现(源码+定制+开发)高校实验室巡检系统、实验室安全管理平台、实验室安全监控系统、智能实验室巡查系统、高校实验室风险管理
  • pandas习题 051:将字符串数据读取到 DataFrame
  • 信奥赛_NOIP/CSP——差分算法
  • 深度学习—Pandas标签库基础
  • kill-start系统进程的研究
  • 虚拟现实和增强现实技术,如何打造沉浸式体验?
  • cuda 环境搭建
  • 躺平成长-代码开发,利用kimi开发小程序(09)
  • 源码解析篇 | YOLO11:计算机视觉领域的新突破 !对比YOLOv8如何 ?
  • DDoS防护应急手段详解
  • string模拟实现构造+析构
  • Java学习Day60:微服务总结!(有经处无火,无火处无经)
  • 栈的算法题 —— 有效的括号(LeetCode)
  • Java | Leetcode Java题解之第539题最小时间差
  • Python 自动化运维:安全与合规最佳实践
  • go 包管理