添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
success: (res: GetStorageSuccess) => { const list = JSON.parseArray(res.data as string) if (list != null) { this.list = list

现在获取JSON.parseArray(res.data as string)这样就行 以前的写法是:JSON.parseArray<Item>(JSON.stringify(res.data))

const emits = defineEmits<{ (event: 'reply', obj: ReplyEmit): void }>();
function reply() {
  const data: ReplyEmit = { id: '123', message: 'Hello, World!' };
  emits('reply', data);
//下面是父组件
<MyComponent @reply="handleReply" />
methods: {
  handleReply(obj) {
    console.log(obj.id);       // '123'
    console.log(obj.message);  // 'Hello, World!'
类型声明 { (event: 'reply', obj: ReplyEmit): void }
这里使用了 TypeScript 的函数类型定义,描述了这个组件可以触发的事件及其参数类型。
event: 'reply':指定该组件可以发射一个名为 'reply' 的事件。这个事件名称是字符串类型 'reply',表示在使用组件时,父组件可以监听 reply 事件。
obj: ReplyEmit:reply 事件的第二个参数是 obj,类型为 ReplyEmit。这意味着触发 reply 事件时,会传递一个类型为 ReplyEmit 的对象。这个对象类型 ReplyEmit 需要在你的代码中定义好,可以包含你需要传递的具体数据。
void:表示这个函数没有返回值,即触发事件后不会有返回值给调用者。

onLoad 必须有参数 没有的话会报错,还要放在script最下面,不然容易找不到某些方法

箭头函数必须有大括号

// 从响应式 proxy 创建的只读 proxy     const stateCopy = readonly(state)     console.log(isReactive(stateCopy)) // -> true
function useState<State extends string>(initial: State) {
  const state = ref(initial) as Ref<State> // state.value -> State extends string
  return state
    <span>{{ count }}</span>
    <button @click="count ++">Increment count</button>
    <button @click="nested.count.value ++">Nested Increment count</button>
</template>
<script>
  import { ref } from 'vue'
  export default {
    setup() {
      const count = ref(0)
      return {
        count,
        nested: {
          count
</script>
let { author, title } = toRefs(book) title.value = 'Vue 3 Detailed Guide' // 我们需要使用 .value 作为标题,现在是 ref console.log(book.title) // 'Vue 3 Detailed Guide'
function useFoo(x: number | Ref<number>) {
  const unwrapped = unref(x) // unwrapped 现在一定是数字类型
export default {
  setup(props) {
    useSomeFeature(toRef(props, 'foo'))    // 把props继承的对象中的foo属性传入useSomeFeature这个函数。
function useDebouncedRef(value, delay = 200) {
  let timeout
  return customRef((track, trigger) => {
    return {
      get() {
        track()
        return value
      set(newValue) {
        clearTimeout(timeout)
        timeout = setTimeout(() => {
          value = newValue
          trigger()
        }, delay)
export default {
  setup() {
    return {
      text: useDebouncedRef('hello')
watch(counter, (newValue, oldValue) => {
  console.log('The new counter value is: ' + counter.value)
// 到最后要讲里面写的方法和变量return回来
return {a}
// src/components/UserRepositories.vue `setup` function
import { fetchUserRepositories } from '@/api/repositories'
import { ref, onMounted, watch, toRefs, computed } from 'vue'
// in our component
setup (props) {
  // 使用 `toRefs` 创建对 props 中的 `user` property 的响应式引用
  const { user } = toRefs(props)
  const repositories = ref([])
  const getUserRepositories = async () => {
    // 更新 `props.user ` 到 `user.value` 访问引用值
    repositories.value = await fetchUserRepositories(user.value)
  onMounted(getUserRepositories)
  // 在用户 prop 的响应式引用上设置一个侦听器
  watch(user, getUserRepositories)
  const searchQuery = ref('')
  const repositoriesMatchingSearchQuery = computed(() => {
    return repositories.value.filter(
      repository => repository.name.includes(searchQuery.value)
  return {
    repositories,
    getUserRepositories,
    searchQuery,
    repositoriesMatchingSearchQuery
attrs slots 是有状态的对象,它们总是会随组件本身的更新而更新。这意味着你应该避免对它们进行解构,并始终以 attrs.x 或 slots.x 的方式引用 property。
请注意,与 props 不同,attrs 和 slots 是非响应式的。
如果你打算根据 attrs 或 slots 更改应用副作用,那么应该在 onUpdated 生命周期钩子中执行此操作

执行 setup 时,组件实例尚未被创建。因此,你只能访问以下 property:

props
attrs
slots
换句话说,你将无法访问以下组件选项:

computed
methods

注意,从 setup 返回的 refs 在模板中访问时是被自动解开的,因此不应在模板中使用 .value

setup 还可以返回一个渲染函数,该函数可以直接使用在同一作用域中声明的响应式状态:

// MyBook.vue
import { h, ref, reactive } from 'vue'
export default {
  setup() {
    const readersNumber = ref(0)
    const book = reactive({ title: 'Vue 3 Guide' })
    // Please note that we need to explicitly expose ref value here
    return () => h('div', [readersNumber.value, book.title])
  setup() {
    const ButtonCounter = resolveComponent('button-counter')
    return () => h(ButtonCounter)
  @update:title="pageTitle = $event"
  :content="pageContent"
  @update:content="pageContent = $event"
<script lang="ts">
import { defineComponent, ref } from 'vue'
import { MyButton } from '@/components'
export default defineComponent({
  components: {
    MyButton
  props: {
      name: String
  setup() {
    const count = ref(0)
    const inc = () => count.value++
    return {
      count,
<script>
<script setup lang="ts">
import { defineComponent, ref, defineProps } from 'vue'
import { MyButton } from '@/components'
defineProps<{
    name:string
const count = ref(0)
const inc = () => count.value++
<script>
    watch([() => state.listParam.customerName, () => state.listParam.mainFollower],
      ([newCustomerName, newMainFoller],[oldCustomerName,oldMainFoller]) => {
        state.listParam.customerName = newCustomerName.trim()
        state.listParam.mainFollower = newMainFoller.trim()
       immediate: true
    return {
        …toRefs(state)  // 三点运算符实现多个返回

await语法支持
在script setup内可以直接使用await语法:

<script setup>
  const post = await fetch(`/api/post/1`).then((r) => r.json())
</script>
interface DebuggerOptions {   onTrack?: (event: DebuggerEvent) => void   onTrigger?: (event: DebuggerEvent) => void interface DebuggerEvent {   effect: ReactiveEffect   target: any   type: OperationTypes   key: string | symbol | undefined
vue文件
<el-form :model="listParam" label-position="left" inline>
    <el-form-item prop="searchKey">
       <el-input v-model="listParam.searchKey" placeholder="请输入关键字" clearable size="small"></el-input>
    </el-form-item>
    <el-form-item prop="mainFollower">
      <el-input v-model="listParam.mainFollower" placeholder="请输入跟进人姓名" clearable size="small"></el-input>
    </el-form-item>
</el-form>
    watchEffect(() => {       state.listParam.searchKey = state.listParam.searchKey ? state.listParam.searchKey.trim() : ""       state.listParam.mainFollower= state.listParam.mainFollower? state.listParam.mainFollower.trim() : ""     return {         ...toRefs(state)
function watchEffect(
  effect: (onInvalidate: InvalidateCbRegistrator) => void,
  options?: WatchEffectOptions
): StopHandle
interface WatchEffectOptions {
  flush?: 'pre' | 'post' | 'sync' // 默认:'pre'
  onTrack?: (event: DebuggerEvent) => void
  onTrigger?: (event: DebuggerEvent) => void
interface DebuggerEvent {
  effect: ReactiveEffect
  target: any
  type: OperationTypes
  key: string | symbol | undefined
type InvalidateCbRegistrator = (invalidate: () => void) => void
type StopHandle = () => void
    watch(() => state.listParam.searchKey, (newVal,oldVal) => {         console.log(newVal, oldVal)         state.listParam.searchKey = newVal.trim()     return {         ...toRefs(state)     watch([() => state.listParam.customerName, () => state.listParam.mainFollower],       ([newCustomerName, newMainFoller],[oldCustomerName,oldMainFoller]) => {         state.listParam.customerName = newCustomerName.trim()         state.listParam.mainFollower = newMainFoller.trim()        immediate: true     return {         ...toRefs(state) // 参见 `watchEffect` 共享选项的类型声明 interface WatchOptions extends WatchEffectOptions {   immediate?: boolean // 默认:false   deep?: boolean var that = this this.$echarts.registerMap('hunan', hunan); // 取数据 var myChart = this.$echarts.init(this.$refs.hunan_map) var data = json.data; var series = []; // 画线,点的函数 var convertLineData = function (data) { var res = []; for (var i = 0; i < data.length; i++) { var dataItem = data[i]; var coordS = dataItem.lineS; // 线起点 var coordM = dataItem.lineM; // 线中间点 var coordE = dataItem.lineE; // 线尾点 if (coordS && coordM && coordE) { res.push({ coords: [coordS, coordM, coordE] return res; var convertValData = function (data) { var res = []; for (var i = 0; i < data.length; i++) { var dataItem = data[i]; res.push({ name: dataItem.areaName, value: dataItem.lineE.concat(dataItem.value) return res; // 这里是你要在地图上画的点,线配置,往data里面加就行 var json = { data: [{ areaName: '长沙市', value: 94, lineS: [113.482279,28.19409], lineM: [113.441, 28.4242], lineE: [113.8648, 29.2891] series.push( { // 这是画的线配置 name: '', type: 'lines', zlevel: 2, symbol: 'none', // silent: true, //不响应鼠标点击或事件 effect: { show: false // 关闭特效 tooltip: { show: false labelLayout: { draggable: true polyline: true, // 支持多点连线 itemStyle:{ normal:{ lineStyle:{ width: that.nowSize(2), type:'dotted' //'dotted'虚线 'solid'实线 lineStyle: { normal: { color: 'green', opacity: 0.9, curveness: 0 data: convertLineData(data) { // 这里是点还有点旁边的内容 name: '', type: 'scatter', coordinateSystem: 'geo', zlevel: 2, hoverAnimation: false, // hover时不高亮点 cursor: 'default', // 鼠标设置为箭头 itemStyle: { normal: { color: 'red' tooltip: { show: false, label: { rich: { //自定义样式a fontFamily: 'lcd', //字体名称 color: '#fff', //字体颜色 fontSize: that.nowSize(12), //字体大小 borderColor: 'rgba(30, 157, 222, 1)', borderWidth: that.nowSize(1.2), padding: [8, 8, 8, 8] //**自定义样式b** color: '#fff', fontSize: 16 // normal: { show: true, position: 'right', fontSize: that.nowSize(14), fontWeight: 'bold', color: '#f5a623', formatter: function (param) { return '{a|' + param.value[2] + '/工单' + '}' // 此处用到自定义样式 data: convertValData(data) var option = { // 这里是地图内容配置 // backgroundColor: '#404a59', // 背景色 title: { text: '全省人工服务概况', left: 'center', textStyle: { color: '#2b9de0', fontSize: that.nowSize(18) tooltip: { trigger: 'item' legend: { show: false, selectorLabel: { backgroundColor: 'black' geo: { map: 'hunan', label: { color: 'black', fontSize: that.nowSize(14), emphasis: { show: true, color: 'green', areaColor: 'yellow' roam: false, selectedMode: 'single', itemStyle: { areaColor: 'red', normal: { // areaColor: 'black', // 地图整体的颜色 borderColor: '#404a59' // 边缘线颜色 emphasis: { itemStyle: { areaColor: 'red' // hover 的背景色 select: [{ itemStyle: { areaColor: 'black' // hover 的背景色 regions: [{ // 默认选择 name: val.name, selected: true, itemStyle: { normal: { areaColor: '#AADDFF' // areaColor: 'red', // 地图背景色 // backgroundColor: 'black', // opacity: 0 series: series myChart.setOption(option); // 应用配置 // 加个点击事件 myChart.on('click', function (e) { // e.color = '#d50000' if (e.hasOwnProperty('region')) { option.geo.regions[0].name = e.region.name myChart.setOption(option); } else { return false; console.log(e.region,option)

建议线画地图出来,再一步步移植代码。

线,点或者其它什么样式基本都是label里面能改,字体样式什么的就是itemStyle里面改。

反正2个互相用就能解决大部分问题

最后formatter是个很有用的东西,在这是编辑点右边的数据。你们可以自己定义。

最后放个echart文档地址

https://echarts.apache.org/zh/option.html#title

const app = getApp();
const userInfo = app.globalData.userInfo;
console.log(userInfo); // 输出: { id: 123, name: ‘Alice’ }

3. 本地存储传值 ( 适用于需要跨页面、甚至跨应用会话的数据传递。 )

uni.setStorageSync('userInfo', { id: 123, name: 'Alice' });
uni.navigateTo({
  url: '/pages/detail/detail'
//接受页面
onLoad() {
  const userInfo = uni.getStorageSync('userInfo');
  console.log(userInfo); // 输出: { id: 123, name: 'Alice' }
    ```javascript
    import eventBus from '@/eventBus';
    eventBus.$emit('sendUserInfo', { id: 123, name: 'Alice' });
    uni.navigateTo({
      url: '/pages/detail/detail'
    **接收值页面:**
    ```javascript
    import eventBus from '@/eventBus';
    onLoad() {
      eventBus.$on('sendUserInfo', (userInfo) => {
        console.log(userInfo); // 输出: { id: 123, name: 'Alice' }
    let a=document.createElement('a')
    a.style.display = 'none'
    a.setAttribute('download', 'bg.jpg')
    a.href = require('@/assets/bg.jpg')
    document.body.appendChild(a)
    console.log('href', a.href)
    a.click()
    document.body.removeChild(a)

后端传的话需要调用get接口。

其它文件类型下载基本都是一样的 调用后端get接口,使用blob类型

responseType: ‘blob’。进行下载

注意:如果要是本地下载一些静态资源(除图片外) 资源要放在public目录文件下,不然打包后路径你会发现很多报错,下载找不到路径。@这个不会被解析。

附下载代码:

async download(){
    console.log(this.urlName)
    let res = await axios.get(`jt/${this.urlName}`, { responseType: 'blob' })
    const url = window.URL.createObjectURL(res.data)
    const link = document.createElement('a')
    link.href = url;
    link.setAttribute('download', `${this.urlName}`)
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)

jt/${this.urlName}

jt是public下的一个文件夹, this.urlName是你要下载的文件的名字。

<meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>lesson 31</title> <script src="https://unpkg.com/vue@next"></script> </head> <div id="root"></div> </body> <script> // render function // template -> render -> h -> 虚拟DOM(JS对象)-> 真实 DOM -> 展示到页面上 const app = Vue.createApp({ template: ` <my-title :level="2"> hello dell </my-title> app.component('my-title', { props: ['level'], render() { const { h } = Vue; return h('h' + this.level, {}, [ this.$slots.default(), h('h4', {}, 'dell') const vm = app.mount('#root'); </script> </html>

state 存放状态
mutations state成员操作(处理数据,更改保存到state中。用法this.$store.commit )
getters 加工state成员给外界
actions 异步操作(一般用于处理请求逻辑之后将数据给mutations,用法this.$store.dispatch )
modules 模块化状态管理
modules 的每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割。

简单基础使用就不说了,说重点。

在项目中一般是以模块化管理为主。为了方便每个模块的管理和维护大多使用modules模块化状态管理。

import getters from './getters' import actions from './modules/actions' import mutations from './modules/mutation' import user from './modules/user.js' import user2 from './modules/user2' import state from './store' Vue.use(vuex) export default new vuex.Store({ getters, state, //模块vuex modules: { //公共vuex2个模块 actions, mutations, //各个单独模块使用的vuex user, user2

使用modules后外面不要再加actions和mutations(会报错)

上其中一个单独模块的代码

//这里是user.js的代码
//某个模块专门使用的vuex。调用时加上该模块名字。如this.$store.commit('user/方法名')
const state = {
  userName:''
const getters = {
  userName:(state) => state.userName
const actions = {
  add_name({commit},name){
    commit('ADD_NAME',name);
    console.log('这里是user1的actions',name)
const  mutations = {
  ADD_NAME(state,name){
    state.userName=name;
    console.log('这里是user1',name)
    return true;
export default {
  namespaced: true,            //记住一定要加这个
  state,
  getters,
  actions,
  mutations

namespaced是告诉vuex给它搞个看见出来。默认false. 开启后就是提示打开了命名空间。这样2个模块有同样的方法也不会报错。

当你要调用某个模块的方法时记得写法是

this.$store.commit(‘模块名/方法名’)

this.$store.dispatch(‘模块名/方法名’)

一切弄完之后记得挂载到main.js上

import Vue from 'vue'
import App from './App'
import router from './router'
import Vuex from 'vuex'
import store from './store/index'
Vue.config.productionTip = false
Vue.use(Vuex)
/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  store,    //这就是挂载了
  components: { App },
  template: '<App/>'

有时候报错说未找到该模块有这个方法

报错信息为:

[vuex] unknown action type: user/add_name

你可以删除命名空间试试。

下面放其他js的代码

//actions.js代码
//公共actions异步方法
export default {//在action中可以进行异步操作。
  namespaced: true,
  actions:{
    add_book({commit},book){
      commit('ADD_BOOK',book);
    delete_book({commit},book){
      commit('DELETE_BOOK',id);
//mutations.js代码
//公共mutation方法
export default {//这里要注意不要在mutations里面进行异步操作
  namespaced: true,
  mutations:{
    ADD_BOOK(state,book){
      state.bookList.push(book);
      return true;
    DELETE_BOOK(state,id){
    bar = 'hello';
baz: boolean;
// error,Property 'baz' has no initializer and is not definitely assigned in the constructor
constructor() {
this.foo = 42;

有两种情况下我们不可避免该error的产生:

  • 该属性本来就可以是 undefined 。这种情况下添加类型undefined
  • 属性被间接初始化了(例如构造函数中调用一个方法,更改了属性的值)。这种情况下我们可以使用 显式赋值断言 (修饰符号 !) 来帮助类型系统识别类型。后面具体介绍它,先看下代码中怎么使用:
class StrictClass {
// …
baz!: boolean;
// ^
// 注意到这个!标志
// 代表着显式赋值断言修饰符
}


显式赋值断言(Definite Assignment Assertions)

尽管我们尝试将类型系统做的更富表现力,但我们知道有时用户比TypeScript更加了解类型

跟上面提到的类属性例子差不多,我们无法在给一个值赋值前使用它,但如果我们已经确定它已经被赋值了,这个时候类型系统就需要我们人的介入

let x: number;
initialize();
console.log(x + x);
//          ~   ~
// Error! Variable 'x' is used before being assigned.
function initialize() {
    x = 10;

添加 ! 修饰:let x!: number,则可以修复这个问题

我们也可以在表达式中使用!,类似 variable as string和 <string>variable :

let x: number;
initialize();
console.log(x! + x!); //ok
function initialize() {
    x = 10;

下面是一些小代码记录


关于类的继承


在父级类和子级类中一定要写一个constructor函数,如:

// 父级
class Parent{undefined
    name:string;
    age:number;
    constructor(name:string,age:number){undefined
        this.name = name;
        this.age = age;
// 子级
class Web extends Tparent{undefined
     constructor(name:string){undefined
    this.name = name;

这个里面要放父级有的所有变量,这样子级才能拿得到。不然会报错。

 static是静态内容


访问修饰符

 public是共有内容,默认 例子:public name:string;
 private是私有内容,私有属性无法继承和访问  例子: private name:string;

// 通过关键字interface来声明接口
interface laberValue{undefined
    laber:string;
// 指定类型为接口类型
function printLaber(laberValue:laberValue) {undefined
    console.log(laberValue.laber)
var myobjs = {laber:'hellos rouse'}
printLaber(myobjs)
// 接口的数组类型
interface StringArray{undefined
    //[index:number]这是下标
    [index:number]:string;
var myArray:StringArray;
myArray=["fuck","any","www",""];
console.log(myArray[1]);
// 接口的class的类型,对类的约束
interface ClockInterface{undefined
    currentTime:string;
    // void:不需要返回值
    setTime(d:string):void;
class Clock implements ClockInterface{undefined
    currentTime:string;
    setTime(){undefined
        console.log('tag '+this.currentTime);
    constructor(currentTime:string){undefined
        this.currentTime=currentTime;
var dsq=new Clock('jacks');
dsq.setTime();
// 接口的继承和混合类型
interface Shape{undefined
    color:string;
interface PenStroke{undefined
    penWidth:number;
interface Square extends Shape,PenStroke{undefined
    sideLength:number;
// 泛型<T>,这个T你可以任意指定其他内容,如:<K>
// function Hellopes(num:number):number {undefined
//     return num;
function Hellopes<T>(num:T):T {undefined
        return num;
// 当你使用时需要什么类型就设置什么类型<类型>
var output = Hellopes<string>("hello,jack");
console.log(output)
var listers:Array<string>=Hellopll<string>(["1","2","3"]);
for(var i=0;i<listers.length;i++){undefined
    console.log(listers[i]);

Module

解释:主要是把类,接口都定义在一个module中,方便维护和编写,避免出错

// module,每个类和接口要加export
module Validition{undefined
    export interface StringValidator{undefined
    isAccept(s:string):boolean;
    var letterRegxp = /^[A-Za-z]+$/;
    var numberRegxp = /^[0-9]+$/;
    export class letters implements StringValidator{undefined
        // 复写函数
        isAccept(s:string):boolean{undefined
            return letterRegxp.test(s);
    export class ZipCodeVailed implements StringValidator{undefined
    isAccept(s:string):boolean{undefined
        return s.length === 5 && numberRegxp.test(s);
// 泛型的类型
function Heoo<T>(arg:T):T{undefined
    return arg;
// 箭头函数意义(arg:K)的函数返回值类型为K
var myhello:<K>(arg:K)=>K=Heoo;
// 因为它本身自带类型检查,所以上诉代码可以简写为:var myhello=Heoo;
console.log(myhello("heoooooo"));
// 调用时定义类型
interface Hellp{undefined
    <T>(arg:T):T;
function myHellp<T>(arg:T):T{undefined
    return arg;
var MH:Hellp = myHellp;
// MH后面可以接类型,也可以不接,直接写MH("这是函数")
console.log(MH<string>("这是在调用时定义的泛型"));
// 定义接口时定义类型
interface Hellw<T>{undefined
    (arg:T):T;
function eee<T>(arg:T):T{undefined
    return arg;
var qeew:Hellw<string>=eee;
console.log(qeew("这是在接口定义了泛型"));
var myHelloNumber = new HelloNumber<number>();
myHelloNumber.zeros = 10;
myHelloNumber.add =(x,y)=>x+y
console.log(myHelloNumber.zeros)
console.log(myHelloNumber.add(1,5))