vite
1、npm init vite@latest // 简单版,不只适用于vue(react也可以)
npm init vue@latest // 复杂版,更多选项(针对vue做了封装)
2、配置文件
// ********************************************** // package.json 文件 // ********************************************** *** "dev": "vite --host 0.0.0.0", *** // ********************************************** // vite-env.d.ts 文件 // ********************************************** /// <reference types="vite/client" /> declare module '*.vue' { import type { DefineComponent } from 'vue' const component: DefineComponent<{}, {}, any> export default component }
3、安装插件
// 1.安装less cnpm install less
// 2.添加cesium
cnpm install cesium vite-plugin-cesium --save
// 2.1配置vite.config.js
import cesium from 'vite-plugin-cesium';
export default defineConfig({ plugins: [vue(),cesium()] })
4、安装volar 2个插件【Vue Language Features (Volar)、TypeScript Vue Plugin (Volar)】,禁用vetur【有冲突,适用于vue2】
5、页面模版代码
<template> <div>{{ xxx }}</div> </template> <script setup lang="ts"> import { ref, shallowRef } from 'vue' const name = ref<string>('xxx') </script> <style lang="less" scoped> </style>
语法
1、
// v-text <div v-text="a"> // v-html <div v-html="a"> // v-if <div v-if="a=='a'"> a </div> <div v-else-if="a=='b'"> b </div> <div v-else> c </div>
//动态修改事件
const click:string='dblclick'
const xxx = () => {
console.info("xxx")
}
<button @[click].stop="xxx">双击我</button> <!-- .stop 阻止冒泡 .once 只点击一次 .prevent阻止(submit阻止刷新页面) 其他的可以看自动提示 -->
// 绑定属性 v-bind
const id:string = '1001'
const style = {
color:'red',
border:'1px solid red'
}
const classOption = true
<div v-bind:id="id"></div> <!-- 简写【:】,可以绑定任何属性 -->
<div :style="style">sdfsd</div>
<div class="d" :class="classOption? ['a','s']:'b'">sdfsd</div> <!-- 静态、动态class可以各一个 -->
.a{
border:1px solid red
}
.b{
border:1px solid blue
}
.d{
font-weight: bold;
}
.s{
font-size: 40px;
}
// 绑定数据 v-model // ref 或 reactive 才是响应式的
import {ref} from 'vue'
const a=ref('asdf')
<input v-model="a" type="text">
<div>{{ a }}</div>
// 循环 v-for
const arr:string[] = ['北京','重庆']
const arrObj = [{id:'1001',name:"北京"},{id:'1002',name:"重庆"}]
<div :key="index" v-for="(item,index) in arr">
<p>{{ index }} - {{ item }}</p>
</div>
<div :key="item.id" v-for="(item,index) in arrObj">
<p>{{ index }} - {{ item.id }} - {{ item.name }}</p>
</div>
// ref、reactive 添加ref、reactive才能双向绑定
// 区别1:reactive不支持基本类型,只支持引用类型
// 区别2:reactive调用属性时,可以不用.value
// 区别3:reactive不能直接附值(会破坏proxy,页面不会渲染),如果是数组可以push+解构(...arr),其他类型数据可以放到对象里面的一个属性上,保障proxy不会被破坏
// 总结:异步时尽量不用reactive,比较麻烦
type T = { // 定义一个相对复杂对象 相当于list<map> // ref 略,上面讲到了
id:string
name:string
}[]
const arrObj = reactive<T>([{id:'1001',name:"北京"},{id:'1002',name:"重庆"}])
const click = () => {
const temp:T = [{id:'9001',name:"改变了1"},{id:'9001',name:"改变了2"}]
// arrObj = temp // 直接附值会破坏proxy,数据不会渲染到页面
arrObj.length=0
arrObj.push(...temp)
}
<div :key="item.id" v-for="(item,index) in arrObj">
<p>{{ index }} - {{ item.id }} - {{ item.name }}</p>
</div>
<button @click="click">点击我接收后台数据</button>
//计算 computed // 解决场景:复杂计算场景,不用封装计算的方法每次调用,只需要修改关联值就行了,采用computed包裹,修改了关联值会触发回调自动重新计算
const n1 = ref<number>(0)
const n2 = ref<number>(0)
let number1 = computed(()=>{
return n1.value+n2.value
})
<input type="number" v-model="n1">
<input type="number" v-model="n2">
计算结果:{{ number1 }}
// 计算2 watchEffect
const a1 = ref<string>('')
const a2 = ref<string>('')
const watchEffect1 = watchEffect((oninvalidate)=>{
let btn:HTMLButtonElement = document.querySelector('#btn') as HTMLButtonElement // as ... 断言
console.info('btn EL:',btn)
console.log('a1:'+a1.value)
oninvalidate(()=>{ // 监听之前执行
console.info("************* before *************")
})
},{
flush:'post', // 组件更新后执行,其他参数看自动提示
onTrigger(e){
debugger // 断点调试
}
})
const stopWatch = () => watchEffect1() // watchEffect1返回的就是stop函数,一旦被执行,就停止监听
<input type="text" v-model="a1">
<input type="text" v-model="a2">
<button id="btn" @click="stopWatch">停止监听</button>
// 父子组件传值 // 父组件 -> 子组件 // 父组件 import Menu from "./Menu/index.vue" const name ="名称" <Menu :title="name" :arr="[1,2,3]"></Menu> // 子组件 // 方式一:普通js型 // const props = defineProps({ // title:{ // type:String, // default:"未设置默认值" // } // }) // 方式二:ts方式 defineProps(简约版,推荐) const props = defineProps<{ title:string, arr:number[], }>() // 方式三:ts方式 withDefaults(复杂版,支持默认值设置,不传参数也会有警告) // const props = withDefaults( // defineProps<{ // title:string, // arr:number[], // }>(), // { // arr:()=>[666] // 当没有传递arr参数时,为arr设置的默认值 // } // ) console.log("【父组件给子组件传值】在子组件中打印,父组件传递给子组件的title值为:"+props.title) console.log("【父组件给子组件传值】在子组件中打印,父组件传递给子组件的arr值为:"+props.arr) <div class="menu"> 标题:{{ title }} 其他:{{ arr }} </div> // 子组件 -> 父组件 // 父组件 onMounted(()=>{ console.info("【子组件给父组件传值】在父组件中打印,子组件暴露给父组件的属性name的值为:"+menuComponents.value?.name) const funRlt = menuComponents.value?.open('asdf') console.info(funRlt) }) const menuComponents = ref<InstanceType<typeof Menu>>(); const getInfo = (name:string) => { console.info("【子组件给父组件传值】在父组件中打印,【点击按钮时】子组件传递给父组件的name值为:"+name) } const getInfo2 = (name:string) => { console.info("【子组件给父组件传值】在父组件中打印,【点击按钮时】子组件传递给父组件的name值为:"+name) console.info("【子组件给父组件传值】在父组件中打印,子组件暴露给父组件的属性name的值为:"+menuComponents.value?.name) } <Menu @on-click="getInfo" @on-click2="getInfo2"></Menu> // 子组件 // 方式一:js方式 // const emit = defineEmits(['on-click','on-click2']) // const send = () => { // emit('on-click','我是子组件的name') // } // const send2 = () => { // emit('on-click2','我是子组件的name2') // } // 方式二:ts方式 const emit = defineEmits<{ (emit:"on-click",name:string):void (emit:"on-click2",name:string):void }>() const send = () => { emit('on-click','我是子组件的name') } const send2 = () => { emit('on-click2','我是子组件的name') } // 方式三:暴露方法或属性 defineExpose({ name:"123456", open:(param:string)=>{ console.info("我是子组件中的方法,我打印了一句话,父组件还给我传了一个参数param:"+param) return param+"kkkk" } }) <button @click="send">第一个按钮</button> <button @click="send2">第二个按钮</button>